src/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
227 / 380
59.7%
Branches:
185 / 718
25.8%
Functions:
17 / 24
70.8%

ps/brpc/brpc_ps_client.cpp
Line Branch Exec Source
1 #include "brpc_ps_client.h"
2
3 #include <brpc/channel.h>
4 #include <fmt/format.h>
5 #include <gflags/gflags.h>
6
7 #include <algorithm>
8 #include <cstdint>
9 #include <cstring>
10 #include <future>
11 #include <string>
12 #include <vector>
13
14 #include <google/protobuf/arena.h>
15
16 #include "base/array.h"
17 #include "base/factory.h"
18 #include "base/flatc.h"
19 #include "base/log.h"
20 #include "base/timer.h"
21 #include "ps/base/parameters.h"
22 #include "ps_brpc.pb.h"
23
24 #ifdef ENABLE_PERF_REPORT
25 # include <chrono>
26 # include "base/report/report_client.h"
27 #endif
28
29 using recstoreps_brpc::CommandRequest;
30 using recstoreps_brpc::CommandResponse;
31 using recstoreps_brpc::GetParameterRequest;
32 using recstoreps_brpc::GetParameterResponse;
33 using recstoreps_brpc::InitEmbeddingTableRequest;
34 using recstoreps_brpc::InitEmbeddingTableResponse;
35 using recstoreps_brpc::PSCommand;
36 using recstoreps_brpc::PutParameterRequest;
37 using recstoreps_brpc::PutParameterResponse;
38 using recstoreps_brpc::UpdateParameterRequest;
39 using recstoreps_brpc::UpdateParameterResponse;
40
41 namespace {
42
43 50 const ParameterCompressReader* ExtractGetResponseReader(
44 const brpc::Controller& cntl,
45 const GetParameterResponse& response,
46 std::string* payload_storage,
47 int* payload_size) {
48
1/2
✓ Branch 2 taken 50 times.
✗ Branch 3 not taken.
50 if (!cntl.response_attachment().empty()) {
49 50 payload_storage->clear();
50 50 cntl.response_attachment().copy_to(payload_storage);
51 50 *payload_size = payload_storage->size();
52 return reinterpret_cast<const ParameterCompressReader*>(
53 50 payload_storage->data());
54 }
55
56 ✗ *payload_size = response.parameter_value().size();
57 return reinterpret_cast<const ParameterCompressReader*>(
58 ✗ response.parameter_value().data());
59 }
60
61 } // namespace
62
63 DEFINE_int32(brpc_timeout_ms, 5000, "brpc request timeout in milliseconds");
64 DEFINE_int32(brpc_max_retry, 3, "brpc max retry times");
65 DEFINE_bool(parameter_client_random_init_brpc, false, "");
66 DEFINE_bool(brpc_ps_use_rdma,
67 false,
68 "Use RDMA transport for the brpc PS channel (requires brpc built "
69 "with WITH_RDMA=ON).");
70
71 namespace {
72
73 // The brpc PS client is loaded as a shared library from Python and never calls
74 // gflags::ParseCommandLineFlags, so RDMA options are configured from env vars
75 // (consistent with the RECSTORE_RDMA_* convention used by the raw-verbs path).
76 // RECSTORE_BRPC_USE_RDMA=1 -> enable RDMA transport
77 // RECSTORE_BRPC_RDMA_DEVICE=mlx5_0 -> select the HCA (maps to brpc
78 // -rdma_device) RECSTORE_BRPC_TIMEOUT_MS=60000 -> request timeout (maps to
79 // -brpc_timeout_ms)
80 30 bool ResolveBrpcUseRdmaFromEnv(bool fallback) {
81 30 const char* value = std::getenv("RECSTORE_BRPC_USE_RDMA");
82
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
30 if (value == nullptr || *value == '\0') {
83 30 return fallback;
84 }
85
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ return std::string(value) != "0";
86 }
87
88 ✗ void ApplyBrpcRdmaDeviceFromEnv() {
89 ✗ const char* dev = std::getenv("RECSTORE_BRPC_RDMA_DEVICE");
90
0/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ if (dev != nullptr && *dev != '\0') {
91 ✗ google::SetCommandLineOption("rdma_device", dev);
92 }
93 ✗ }
94
95 30 int BrpcTimeoutMsFromEnv(int fallback) {
96 30 const char* ms = std::getenv("RECSTORE_BRPC_TIMEOUT_MS");
97
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
30 if (ms == nullptr || *ms == '\0') {
98 30 return fallback;
99 }
100 try {
101
0/4
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ return std::stoi(ms);
102 ✗ } catch (...) {
103 ✗ return fallback;
104 ✗ }
105 }
106
107 } // namespace
108
109 // New constructor that takes JSON config
110 24 BRPCParameterClient::BRPCParameterClient(json config) {
111
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 host_ = config.value("host", "localhost");
112
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 port_ = config.value("port", 15000);
113
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 shard_ = config.value("shard", 0);
114 24 timeout_ms_ =
115
2/4
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
24 BrpcTimeoutMsFromEnv(config.value("timeout_ms", FLAGS_brpc_timeout_ms));
116
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 max_retry_ = config.value("max_retry", FLAGS_brpc_max_retry);
117
118
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 Initialize();
119
120 // Initialize bRPC channel
121
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 channel_ = std::make_shared<brpc::Channel>();
122
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 brpc::ChannelOptions options;
123 24 options.timeout_ms = timeout_ms_;
124 24 options.max_retry = max_retry_;
125 48 bool use_rdma_enabled = ResolveBrpcUseRdmaFromEnv(
126
2/4
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
24 config.value("use_rdma", FLAGS_brpc_ps_use_rdma));
127
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 if (use_rdma_enabled) {
128
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ ApplyBrpcRdmaDeviceFromEnv();
129 }
130 #if BRPC_WITH_RDMA
131 options.use_rdma = use_rdma_enabled;
132 #endif
133
134
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 std::string server_addr = fmt::format("{}:{}", host_, port_);
135
2/4
✓ Branch 3 taken 24 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 24 times.
24 if (channel_->Init(server_addr.c_str(), &options) != 0) {
136
0/8
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ LOG(ERROR) << "Failed to initialize bRPC channel to " << server_addr;
137 } else {
138
3/6
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 24 times.
✗ Branch 8 not taken.
48 LOG(INFO) << "Initialized bRPC PS Client Shard " << shard_ << " at "
139
6/12
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 24 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 24 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 24 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 24 times.
✗ Branch 17 not taken.
24 << server_addr << " (use_rdma=" << use_rdma_enabled << ")";
140 }
141 24 }
142
143 // Legacy constructor for backward compatibility
144 6 BRPCParameterClient::BRPCParameterClient(
145 6 const std::string& host, int port, int shard)
146 6 : host_(host),
147 6 port_(port),
148 6 shard_(shard),
149
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 timeout_ms_(BrpcTimeoutMsFromEnv(FLAGS_brpc_timeout_ms)),
150
1/2
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
12 max_retry_(FLAGS_brpc_max_retry) {
151
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 Initialize();
152
153
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 channel_ = std::make_shared<brpc::Channel>();
154
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 brpc::ChannelOptions options;
155 6 options.timeout_ms = timeout_ms_;
156 6 options.max_retry = max_retry_;
157
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 bool use_rdma_enabled = ResolveBrpcUseRdmaFromEnv(FLAGS_brpc_ps_use_rdma);
158
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (use_rdma_enabled) {
159
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ ApplyBrpcRdmaDeviceFromEnv();
160 }
161 #if BRPC_WITH_RDMA
162 options.use_rdma = use_rdma_enabled;
163 #endif
164
165 ✗ std::string server_addr = fmt::format("{}:{}", host, port);
166
2/4
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 6 times.
6 if (channel_->Init(server_addr.c_str(), &options) != 0) {
167
0/8
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ LOG(ERROR) << "Failed to initialize bRPC channel to " << server_addr;
168 } else {
169
3/6
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
12 LOG(INFO) << "Initialized bRPC PS Client Shard " << shard_ << " at "
170
6/12
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 6 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 6 times.
✗ Branch 17 not taken.
6 << server_addr << " (use_rdma=" << use_rdma_enabled << ")";
171 }
172 6 }
173
174 30 bool BRPCParameterClient::Initialize() { return true; }
175
176 40 int BRPCParameterClient::GetParameter(const base::ConstArray<uint64_t>& keys,
177 base::RecTensor& values) {
178 #ifdef ENABLE_PERF_REPORT
179 auto start_time = std::chrono::high_resolution_clock::now();
180 #endif
181
182
2/4
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 40 times.
40 if (!recstore::IsFloatEmbeddingValues(
183 40 values, static_cast<int64_t>(keys.Size()))) {
184 ✗ return -1;
185 }
186
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 40 times.
40 if (keys.Size() == 0) {
187 ✗ return 0;
188 }
189
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 const int64_t D = values.shape(1);
190
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 float* dst = values.data_as<float>();
191 40 std::memset(dst, 0, keys.Size() * static_cast<size_t>(D) * sizeof(float));
192
193
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
40 if (FLAGS_parameter_client_random_init_brpc) {
194
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ std::fill(dst, dst + keys.Size() * static_cast<size_t>(D), 0.1f);
195 ✗ return 0;
196 }
197
198 int request_num =
199 40 (keys.Size() + MAX_PARAMETER_BATCH_BRPC - 1) / MAX_PARAMETER_BATCH_BRPC;
200
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 google::protobuf::Arena arena;
201
1/2
✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
40 std::vector<GetParameterRequest*> requests(request_num);
202
1/2
✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
40 std::vector<GetParameterResponse*> responses(request_num);
203
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 40 times.
80 for (int i = 0; i < request_num; ++i) {
204
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 requests[i] = google::protobuf::Arena::Create<GetParameterRequest>(&arena);
205 40 responses[i] =
206
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 google::protobuf::Arena::Create<GetParameterResponse>(&arena);
207 }
208
1/2
✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
40 std::vector<brpc::Controller> controllers(request_num);
209 40 std::vector<int> key_sizes;
210
211
1/2
✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
40 recstoreps_brpc::ParameterService_Stub stub(channel_.get());
212
213 #ifdef ENABLE_PERF_REPORT
214 auto wait_start_time = std::chrono::high_resolution_clock::now();
215 #endif
216
217 // Send async RPC requests
218
2/2
✓ Branch 1 taken 40 times.
✓ Branch 2 taken 40 times.
80 for (int start = 0, index = 0; start < keys.Size();
219 40 start += MAX_PARAMETER_BATCH_BRPC, ++index) {
220 int key_size =
221 40 std::min((int)(keys.Size() - start), MAX_PARAMETER_BATCH_BRPC);
222
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 key_sizes.push_back(key_size);
223
224
1/2
✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
80 controllers[index].request_attachment().append(
225 40 reinterpret_cast<const char*>(&keys[start]),
226 40 sizeof(uint64_t) * key_size);
227
228
1/2
✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
40 google::protobuf::Closure* done = brpc::NewCallback([]() { /* no-op */ });
229
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 stub.GetParameter(
230 40 &controllers[index], requests[index], responses[index], done);
231 }
232
233 // Wait for all RPCs to complete
234
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 40 times.
80 for (int i = 0; i < request_num; ++i) {
235
2/4
✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 40 times.
✗ Branch 6 not taken.
40 brpc::Join(controllers[i].call_id());
236
2/4
✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 40 times.
40 if (controllers[i].Failed()) {
237
0/10
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ LOG(ERROR) << "bRPC GetParameter failed: " << controllers[i].ErrorText();
238 ✗ return -1;
239 }
240 }
241
242 #ifdef ENABLE_PERF_REPORT
243 auto wait_end_time = std::chrono::high_resolution_clock::now();
244 auto wait_duration =
245 std::chrono::duration_cast<std::chrono::microseconds>(
246 wait_end_time - wait_start_time)
247 .count();
248 double wait_start_us =
249 std::chrono::duration_cast<std::chrono::microseconds>(
250 wait_start_time.time_since_epoch())
251 .count();
252 std::string wait_label =
253 "brpc_client::RPC_Call_And_Wait_Shard" + std::to_string(shard_);
254 FlameGraphData wait_fg = {
255 wait_label,
256 wait_start_us,
257 2, // level
258 static_cast<double>(wait_duration),
259 static_cast<double>(wait_duration)};
260 std::string unique_id =
261 "embread_debug|" + std::to_string(static_cast<uint64_t>(wait_start_us));
262 report_flame_graph("emb_read_flame_map", unique_id.c_str(), wait_fg);
263
264 double start_us_for_rpc =
265 std::chrono::duration_cast<std::chrono::microseconds>(
266 start_time.time_since_epoch())
267 .count();
268 std::string report_id_for_rpc =
269 "brpc_client::GetParameter_Vec|" +
270 std::to_string(static_cast<uint64_t>(start_us_for_rpc));
271
272 report("embread_stages",
273 report_id_for_rpc.c_str(),
274 "rpc_duration_us",
275 static_cast<double>(wait_duration));
276
277 auto deserialize_start_time = std::chrono::high_resolution_clock::now();
278 #endif
279
280 // Parse responses
281 40 std::string payload_storage;
282 40 size_t row_offset = 0;
283
2/2
✓ Branch 1 taken 40 times.
✓ Branch 2 taken 40 times.
80 for (int i = 0; i < responses.size(); ++i) {
284 40 auto* response = responses[i];
285 40 int key_size = key_sizes[i];
286 40 int payload_size = 0;
287
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 auto parameters = ExtractGetResponseReader(
288 40 controllers[i], *response, &payload_storage, &payload_size);
289
290
2/4
✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 40 times.
40 if (payload_size == 0 || parameters == nullptr) {
291 ✗ row_offset += static_cast<size_t>(key_size);
292 ✗ continue;
293 }
294
2/4
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 40 times.
40 if (!parameters->Valid(payload_size)) {
295
0/8
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ LOG(ERROR) << "GetParameter invalid payload: " << payload_size;
296 ✗ return -1;
297 }
298
299
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
40 if (parameters->size == 0) {
300 ✗ row_offset += static_cast<size_t>(key_size);
301 ✗ continue;
302 }
303
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
40 if (unlikely(parameters->size != key_size)) {
304
0/10
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ LOG(ERROR) << "GetParameter error: " << parameters->size << " vs "
305
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ << key_size;
306 ✗ return -1;
307 }
308
309
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 CopyCompressItemsToFlat(parameters, dst, D, row_offset);
310 40 row_offset += static_cast<size_t>(key_size);
311 }
312
313 #ifdef ENABLE_PERF_REPORT
314 auto deserialize_end_time = std::chrono::high_resolution_clock::now();
315 auto deserialize_duration =
316 std::chrono::duration_cast<std::chrono::microseconds>(
317 deserialize_end_time - deserialize_start_time)
318 .count();
319 double deserialize_start_us =
320 std::chrono::duration_cast<std::chrono::microseconds>(
321 deserialize_start_time.time_since_epoch())
322 .count();
323 std::string des_label =
324 "brpc_client::Deserialize_Shard" + std::to_string(shard_);
325 FlameGraphData des_fg = {
326 des_label,
327 deserialize_start_us,
328 2, // level
329 static_cast<double>(deserialize_duration),
330 static_cast<double>(deserialize_duration)};
331 std::string des_unique_id =
332 "embread_debug|" +
333 std::to_string(static_cast<uint64_t>(deserialize_start_us));
334 report_flame_graph("emb_read_flame_map", des_unique_id.c_str(), des_fg);
335
336 double start_us_for_des =
337 std::chrono::duration_cast<std::chrono::microseconds>(
338 start_time.time_since_epoch())
339 .count();
340 std::string report_id_for_des =
341 "brpc_client::GetParameter_Vec|" +
342 std::to_string(static_cast<uint64_t>(start_us_for_des));
343 report("embread_stages",
344 report_id_for_des.c_str(),
345 "deserialize_duration_us",
346 static_cast<double>(deserialize_duration));
347 #endif
348
349 #ifdef ENABLE_PERF_REPORT
350 auto end_time = std::chrono::high_resolution_clock::now();
351 auto duration =
352 std::chrono::duration_cast<std::chrono::microseconds>(
353 end_time - start_time)
354 .count();
355 report("ps_client_latency",
356 "GetParameter",
357 "latency_us",
358 static_cast<double>(duration));
359
360 double start_us =
361 std::chrono::duration_cast<std::chrono::microseconds>(
362 start_time.time_since_epoch())
363 .count();
364 FlameGraphData fg_data = {
365 "brpc_client::GetParameter_Vec",
366 start_us,
367 1, // level
368 static_cast<double>(duration),
369 static_cast<double>(duration)};
370
371 std::string report_id = "brpc_client::GetParameter_Vec|" +
372 std::to_string(static_cast<uint64_t>(start_us));
373
374 report("embread_stages",
375 report_id.c_str(),
376 "duration_us",
377 static_cast<double>(duration));
378
379 report("embread_stages",
380 report_id.c_str(),
381 "request_size",
382 static_cast<double>(keys.Size()));
383
384 std::string final_unique_id =
385 "embread_debug|" + std::to_string(static_cast<uint64_t>(start_us));
386 report_flame_graph("emb_read_flame_map", final_unique_id.c_str(), fg_data);
387 #endif
388
389 40 return 0;
390 40 }
391
392 10 static void OnPrefetchDone(BrpcPrefetchBatch* batch) {
393 10 batch->completed_count_++;
394 10 }
395
396 uint64_t
397 10 BRPCParameterClient::PrefetchParameter(const base::ConstArray<uint64_t>& keys) {
398 10 uint64_t prefetch_id = next_prefetch_id_++;
399 int request_num =
400 10 (keys.Size() + MAX_PARAMETER_BATCH_BRPC - 1) / MAX_PARAMETER_BATCH_BRPC;
401
402 // Construct in map so batch pointers stay valid
403
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 auto it = prefetch_batches_.emplace(prefetch_id, request_num).first;
404 10 struct BrpcPrefetchBatch* pb = &it->second;
405
406
1/2
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
10 recstoreps_brpc::ParameterService_Stub stub(channel_.get());
407
408
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 10 times.
20 for (int start = 0, index = 0; start < keys.Size();
409 10 start += MAX_PARAMETER_BATCH_BRPC, ++index) {
410 int key_size =
411 10 std::min((int)(keys.Size() - start), MAX_PARAMETER_BATCH_BRPC);
412 10 pb->key_sizes_[index] = key_size;
413
414
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 GetParameterRequest request;
415
416
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 pb->controllers_[index] = std::make_unique<brpc::Controller>();
417
1/2
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
20 pb->controllers_[index]->request_attachment().append(
418 10 reinterpret_cast<const char*>(&keys[start]),
419 10 sizeof(uint64_t) * key_size);
420
421
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 google::protobuf::Closure* done = brpc::NewCallback(OnPrefetchDone, pb);
422
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 stub.GetParameter(
423 10 pb->controllers_[index].get(), &request, &pb->responses_[index], done);
424 10 }
425
426 10 return prefetch_id;
427 10 }
428
429 ✗ bool BRPCParameterClient::IsPrefetchDone(uint64_t prefetch_id) {
430
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ auto it = prefetch_batches_.find(prefetch_id);
431
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ if (it == prefetch_batches_.end()) {
432
0/8
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ LOG(ERROR) << "Invalid prefetch_id: " << prefetch_id;
433 ✗ return false;
434 }
435
436 ✗ auto& pb = it->second;
437
438 ✗ return pb.completed_count_ == pb.batch_size_;
439 }
440
441 10 void BRPCParameterClient::WaitForPrefetch(uint64_t prefetch_id) {
442
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 auto it = prefetch_batches_.find(prefetch_id);
443
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
10 if (it == prefetch_batches_.end()) {
444
0/8
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ LOG(ERROR) << "Invalid prefetch_id: " << prefetch_id;
445 ✗ return;
446 }
447 10 auto& pb = it->second;
448
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
20 for (int i = 0; i < pb.batch_size_; ++i) {
449
1/2
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
10 if (pb.controllers_[i]) {
450
2/4
✓ Branch 3 taken 10 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 10 times.
✗ Branch 7 not taken.
10 brpc::Join(pb.controllers_[i]->call_id());
451 }
452 }
453 10 pb.completed_count_ = pb.batch_size_;
454 }
455
456 10 bool BRPCParameterClient::GetPrefetchResult(uint64_t prefetch_id,
457 base::RecTensor& values) {
458
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 auto it = prefetch_batches_.find(prefetch_id);
459
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
10 if (it == prefetch_batches_.end()) {
460
0/8
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ LOG(ERROR) << "Invalid prefetch_id: " << prefetch_id;
461 ✗ return false;
462 }
463
464 10 auto& pb = it->second;
465 10 int request_num = pb.batch_size_;
466
467 10 int keys_size = 0;
468
2/2
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 10 times.
20 for (const auto& size : pb.key_sizes_) {
469 10 keys_size += size;
470 }
471
2/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 10 times.
10 const bool discard = values.data() == nullptr && values.dim() == 0;
472
4/8
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 10 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 10 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 10 times.
10 if (!discard && !recstore::EnsureEmbeddingOutput(
473 values, static_cast<int64_t>(keys_size))) {
474 ✗ return false;
475 }
476
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✓ Branch 3 taken 10 times.
✗ Branch 4 not taken.
10 const int64_t D = discard ? 0 : values.shape(1);
477
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✓ Branch 3 taken 10 times.
✗ Branch 4 not taken.
10 float* dst = discard ? nullptr : values.data_as<float>();
478
3/6
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
10 if (!discard && dst != nullptr && keys_size > 0) {
479 10 std::memset(dst,
480 0,
481 10 static_cast<size_t>(keys_size) * static_cast<size_t>(D) *
482 sizeof(float));
483 }
484 10 size_t row_offset = 0;
485
486
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
20 for (int i = 0; i < request_num; ++i) {
487
2/4
✓ Branch 3 taken 10 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 10 times.
10 if (pb.controllers_[i]->Failed()) {
488
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ LOG(ERROR) << "Prefetch request failed: "
489
0/6
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ << pb.controllers_[i]->ErrorText();
490 ✗ return false;
491 }
492
493 10 auto& response = pb.responses_[i];
494 10 int key_size = pb.key_sizes_[i];
495 10 std::string payload_storage;
496 10 int payload_size = 0;
497
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 auto parameters = ExtractGetResponseReader(
498 10 *pb.controllers_[i], response, &payload_storage, &payload_size);
499
500
2/4
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
10 if (payload_size == 0 || parameters == nullptr) {
501 ✗ row_offset += static_cast<size_t>(key_size);
502 ✗ continue;
503 }
504
2/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
10 if (!parameters->Valid(payload_size)) {
505
0/8
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ LOG(ERROR) << "Prefetch invalid payload: " << payload_size;
506 ✗ return false;
507 }
508
509
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (parameters->size == 0) {
510 ✗ row_offset += static_cast<size_t>(key_size);
511 ✗ continue;
512 }
513
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (unlikely(parameters->size != key_size)) {
514
0/10
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ LOG(ERROR) << "GetParameter error: " << parameters->size << " vs "
515
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ << key_size;
516 ✗ return false;
517 }
518
519
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if (!discard) {
520
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 CopyCompressItemsToFlat(parameters, dst, D, row_offset);
521 10 row_offset += static_cast<size_t>(key_size);
522 }
523
1/3
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
10 }
524
525
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 prefetch_batches_.erase(it);
526
527 10 return true;
528 }
529
530 34 bool BRPCParameterClient::ClearPS() {
531
1/2
✓ Branch 1 taken 34 times.
✗ Branch 2 not taken.
34 CommandRequest request;
532
1/2
✓ Branch 1 taken 34 times.
✗ Branch 2 not taken.
34 CommandResponse response;
533
1/2
✓ Branch 1 taken 34 times.
✗ Branch 2 not taken.
34 request.set_command(PSCommand::CLEAR_PS);
534
535
1/2
✓ Branch 1 taken 34 times.
✗ Branch 2 not taken.
34 brpc::Controller cntl;
536
1/2
✓ Branch 2 taken 34 times.
✗ Branch 3 not taken.
34 recstoreps_brpc::ParameterService_Stub stub(channel_.get());
537
1/2
✓ Branch 1 taken 34 times.
✗ Branch 2 not taken.
34 stub.Command(&cntl, &request, &response, nullptr);
538
539
2/4
✓ Branch 1 taken 34 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 34 times.
34 if (cntl.Failed()) {
540
0/10
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ LOG(ERROR) << "bRPC Command failed: " << cntl.ErrorText();
541 ✗ return false;
542 }
543 34 return true;
544 34 }
545
546 6 bool BRPCParameterClient::LoadFakeData(int64_t data) {
547
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 CommandRequest request;
548
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 CommandResponse response;
549
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 request.set_command(PSCommand::LOAD_FAKE_DATA);
550
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 request.add_arg1(&data, sizeof(int64_t));
551
552
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 brpc::Controller cntl;
553
1/2
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 recstoreps_brpc::ParameterService_Stub stub(channel_.get());
554
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 stub.Command(&cntl, &request, &response, nullptr);
555
556
2/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
6 if (cntl.Failed()) {
557
0/10
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ LOG(ERROR) << "bRPC LoadFakeData failed: " << cntl.ErrorText();
558 ✗ return false;
559 }
560
2/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
6 if (response.reply().size() != static_cast<size_t>(data)) {
561
0/6
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ LOG(ERROR) << "bRPC LoadFakeData reply size mismatch: expected " << data
562
0/8
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ << ", got " << response.reply().size();
563 ✗ return false;
564 }
565 6 return true;
566 6 }
567
568 6 bool BRPCParameterClient::DumpFakeData(int64_t n) {
569
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 CommandRequest request;
570
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 CommandResponse response;
571
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 request.set_command(PSCommand::DUMP_FAKE_DATA);
572
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 request.add_arg1(&n, sizeof(int64_t));
573
574
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 brpc::Controller cntl;
575
1/2
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 recstoreps_brpc::ParameterService_Stub stub(channel_.get());
576
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 stub.Command(&cntl, &request, &response, nullptr);
577
578
2/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
6 if (cntl.Failed()) {
579
0/10
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ LOG(ERROR) << "bRPC DumpFakeData failed: " << cntl.ErrorText();
580 ✗ return false;
581 }
582
2/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
6 if (response.reply() != "ok") {
583
0/10
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ LOG(ERROR) << "bRPC DumpFakeData unexpected reply: " << response.reply();
584 ✗ return false;
585 }
586 6 return true;
587 6 }
588
589 ✗ bool BRPCParameterClient::LoadCkpt(
590 const std::vector<std::string>& model_config_path,
591 const std::vector<std::string>& emb_file_path) {
592
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ CommandRequest request;
593
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ CommandResponse response;
594
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ request.set_command(PSCommand::RELOAD_PS);
595
596
0/2
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ for (auto& each : model_config_path) {
597
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ request.add_arg1(each);
598 }
599
0/2
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ for (auto& each : emb_file_path) {
600
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ request.add_arg2(each);
601 }
602
603
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ brpc::Controller cntl;
604
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ recstoreps_brpc::ParameterService_Stub stub(channel_.get());
605
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ stub.Command(&cntl, &request, &response, nullptr);
606
607
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ if (cntl.Failed()) {
608
0/10
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ LOG(ERROR) << "bRPC LoadCkpt failed: " << cntl.ErrorText();
609 ✗ return false;
610 }
611 ✗ return true;
612 ✗ }
613
614 28 bool BRPCParameterClient::PutParameter(const std::vector<uint64_t>& keys,
615 const base::RecTensor& values) {
616 #ifdef ENABLE_PERF_REPORT
617 auto start_time = std::chrono::high_resolution_clock::now();
618 #endif
619
2/4
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 28 times.
28 if (!recstore::IsFloatEmbeddingValues(
620 28 values, static_cast<int64_t>(keys.size()))) {
621 ✗ return false;
622 }
623
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
✓ Branch 4 taken 28 times.
✗ Branch 5 not taken.
28 const int64_t D = keys.empty() ? 0 : values.shape(1);
624
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
✓ Branch 4 taken 28 times.
✗ Branch 5 not taken.
28 const float* src = keys.empty() ? nullptr : values.data_as<float>();
625
626
1/2
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
28 recstoreps_brpc::ParameterService_Stub stub(channel_.get());
627
628
2/2
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 28 times.
56 for (int start = 0, index = 0; start < keys.size();
629 28 start += MAX_PARAMETER_BATCH_BRPC, ++index) {
630 int key_size =
631 28 std::min((int)(keys.size() - start), MAX_PARAMETER_BATCH_BRPC);
632
633
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 PutParameterRequest request;
634
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 PutParameterResponse response;
635
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 ParameterCompressor compressor;
636 56 CompressEmbeddingRows(
637
1/2
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
28 &compressor, keys.data() + start, src + start * D, key_size, D);
638
639
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 brpc::Controller cntl;
640
1/2
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
28 compressor.AppendToIOBuf(&cntl.request_attachment());
641
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 stub.PutParameter(&cntl, &request, &response, nullptr);
642
643
2/4
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 28 times.
28 if (cntl.Failed()) {
644
0/10
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ LOG(ERROR) << "bRPC PutParameter failed: " << cntl.ErrorText();
645 ✗ return false;
646 }
647
4/8
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 28 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 28 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 28 times.
✗ Branch 11 not taken.
28 }
648
649 #ifdef ENABLE_PERF_REPORT
650 auto end_time = std::chrono::high_resolution_clock::now();
651 auto duration =
652 std::chrono::duration_cast<std::chrono::microseconds>(
653 end_time - start_time)
654 .count();
655 report("ps_client_latency",
656 "PutParameter",
657 "latency_us",
658 static_cast<double>(duration));
659 #endif
660
661 28 return true;
662 28 }
663
664 14 int BRPCParameterClient::PutParameter(const base::ConstArray<uint64_t>& keys,
665 const base::RecTensor& values) {
666
1/2
✓ Branch 5 taken 14 times.
✗ Branch 6 not taken.
14 std::vector<uint64_t> key_vec(keys.Data(), keys.Data() + keys.Size());
667
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 bool success = PutParameter(key_vec, values);
668
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
28 return success ? 0 : -1;
669 14 }
670
671 ✗ void BRPCParameterClient::Command(recstore::PSCommand command) {
672
0/5
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ switch (command) {
673 ✗ case recstore::PSCommand::CLEAR_PS:
674 ✗ ClearPS();
675 ✗ break;
676 ✗ case recstore::PSCommand::RELOAD_PS:
677
0/4
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ LOG(WARNING) << "RELOAD_PS command requires additional parameters";
678 ✗ break;
679 ✗ case recstore::PSCommand::LOAD_FAKE_DATA: {
680 ✗ int64_t fake_data = 1000;
681 ✗ LoadFakeData(fake_data);
682 ✗ } break;
683 ✗ case recstore::PSCommand::DUMP_FAKE_DATA: {
684 ✗ DumpFakeData(4096);
685 ✗ } break;
686 ✗ default:
687
0/6
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ LOG(ERROR) << "Unknown PS command: " << static_cast<int>(command);
688 ✗ break;
689 }
690 ✗ }
691
692 ✗ int BRPCParameterClient::UpdateParameter(const std::string& table_name,
693 const base::ConstArray<uint64_t>& keys,
694 const base::RecTensor& grads) {
695 #ifdef ENABLE_PERF_REPORT
696 auto start_time = std::chrono::high_resolution_clock::now();
697 const uint64_t trace_id = recstore::g_trace_id;
698 #endif
699
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ if (!recstore::IsFloatEmbeddingValues(
700 ✗ grads, static_cast<int64_t>(keys.Size()))) {
701
0/8
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ LOG(ERROR) << "UpdateParameter keys/grads size mismatch: " << keys.Size();
702 ✗ return -1;
703 }
704
705
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ ParameterCompressor compressor;
706
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ if (keys.Size() > 0) {
707
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ CompressEmbeddingRows(
708 &compressor,
709 keys.Data(),
710
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ grads.data_as<float>(),
711 ✗ keys.Size(),
712 grads.shape(1));
713 }
714 #ifdef ENABLE_PERF_REPORT
715 auto serialize_done_time = std::chrono::high_resolution_clock::now();
716 #endif
717
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ if (keys.Size() == 0) {
718
0/6
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ LOG(WARNING) << "UpdateParameter no gradients to send";
719 ✗ return 0;
720 }
721
722
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ UpdateParameterRequest request;
723
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ UpdateParameterResponse response;
724 request.set_table_name(table_name);
725
726
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ brpc::Controller cntl;
727 #ifdef ENABLE_PERF_REPORT
728 if (trace_id != 0) {
729 cntl.http_request().SetHeader(
730 "x-recstore-trace-id", std::to_string(trace_id));
731 }
732 auto rpc_start_time = std::chrono::high_resolution_clock::now();
733 #endif
734
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ compressor.AppendToIOBuf(&cntl.request_attachment());
735
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ recstoreps_brpc::ParameterService_Stub stub(channel_.get());
736
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ stub.UpdateParameter(&cntl, &request, &response, nullptr);
737
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ if (cntl.Failed()) {
738
0/10
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ LOG(ERROR) << "UpdateParameter RPC failed: " << cntl.ErrorText();
739 ✗ return -1;
740 }
741
742 #ifdef ENABLE_PERF_REPORT
743 auto end_time = std::chrono::high_resolution_clock::now();
744 auto duration =
745 std::chrono::duration_cast<std::chrono::microseconds>(
746 end_time - start_time)
747 .count();
748 auto serialize_duration =
749 std::chrono::duration_cast<std::chrono::microseconds>(
750 serialize_done_time - start_time)
751 .count();
752 auto rpc_duration =
753 std::chrono::duration_cast<std::chrono::microseconds>(
754 end_time - rpc_start_time)
755 .count();
756 report("ps_client_latency",
757 "UpdateParameter",
758 "latency_us",
759 static_cast<double>(duration));
760
761 const uint64_t effective_trace_id =
762 trace_id == 0
763 ? static_cast<uint64_t>(
764 std::chrono::duration_cast<std::chrono::microseconds>(
765 start_time.time_since_epoch())
766 .count())
767 : trace_id;
768 std::string stage_id =
769 "brpc_client::EmbUpdate|" + std::to_string(effective_trace_id);
770 report("embupdate_stages",
771 stage_id.c_str(),
772 "client_serialize_us",
773 static_cast<double>(serialize_duration));
774 report("embupdate_stages",
775 stage_id.c_str(),
776 "client_rpc_us",
777 static_cast<double>(rpc_duration));
778 report("embupdate_stages",
779 stage_id.c_str(),
780 "client_total_us",
781 static_cast<double>(duration));
782 report("embupdate_stages",
783 stage_id.c_str(),
784 "client_request_size",
785 static_cast<double>(keys.Size()));
786 #endif
787
788
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ return response.success() ? 0 : -1;
789 ✗ }
790
791 ✗ int BRPCParameterClient::InitEmbeddingTable(
792 const std::string& table_name,
793 const recstore::EmbeddingTableConfig& config) {
794 #ifdef ENABLE_PERF_REPORT
795 auto start_time = std::chrono::high_resolution_clock::now();
796 #endif
797
798
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ InitEmbeddingTableRequest request;
799
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ InitEmbeddingTableResponse response;
800 request.set_table_name(table_name);
801
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ request.set_config_payload(config.Serialize());
802
803
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ brpc::Controller cntl;
804
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ recstoreps_brpc::ParameterService_Stub stub(channel_.get());
805
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ stub.InitEmbeddingTable(&cntl, &request, &response, nullptr);
806
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ if (cntl.Failed()) {
807
0/10
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ LOG(ERROR) << "InitEmbeddingTable RPC failed: " << cntl.ErrorText();
808 ✗ return -1;
809 }
810
811 #ifdef ENABLE_PERF_REPORT
812 auto end_time = std::chrono::high_resolution_clock::now();
813 auto duration =
814 std::chrono::duration_cast<std::chrono::microseconds>(
815 end_time - start_time)
816 .count();
817 report("ps_client_latency",
818 "InitEmbeddingTable",
819 "latency_us",
820 static_cast<double>(duration));
821 #endif
822
823
0/6
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ return response.success() ? response.tag() : -1;
824 ✗ }
825
826 ✗ int64_t BRPCParameterClient::ExchangeSparseGradientCommit(
827 const std::string& table, const std::string& payload) {
828
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ recstoreps_brpc::SparseGradientCommitRequest request;
829
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ recstoreps_brpc::SparseGradientCommitResponse response;
830 request.set_table_name(table);
831 request.set_payload(payload);
832
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ brpc::Controller controller;
833
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ recstoreps_brpc::ParameterService_Stub stub(channel_.get());
834
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ stub.SparseGradientCommit(&controller, &request, &response, nullptr);
835
0/10
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ if (controller.Failed() || !response.error().empty()) {
836
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ throw std::runtime_error(
837
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ "SparseGradientCommit: " +
838
0/10
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ (controller.Failed() ? controller.ErrorText() : response.error()));
839 }
840
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ return response.committed_step();
841 ✗ }
842