src/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
272 / 432
63.0%
Branches:
195 / 750
26.0%
Functions:
15 / 20
75.0%

ps/grpc/grpc_ps_client.cpp
Line Branch Exec Source
1 #include "grpc_ps_client.h"
2
3 #include <fmt/format.h>
4 #include <grpcpp/grpcpp.h>
5
6 #include <algorithm>
7 #include <cstdint>
8 #include <cstring>
9 #include <future>
10 #include <string>
11 #include <vector>
12
13 #include "base/array.h"
14 #include "base/factory.h"
15 #include "base/flatc.h"
16 #include "base/log.h"
17 #include "base/timer.h"
18 #include "ps/base/parameters.h"
19 #include "ps.grpc.pb.h"
20 #include "ps.pb.h"
21
22 #ifdef ENABLE_PERF_REPORT
23 # include "base/report/report_client.h"
24 # include <chrono>
25 #endif
26
27 using grpc::Channel;
28 using grpc::ClientAsyncResponseReader;
29 using grpc::ClientContext;
30 using grpc::Status;
31 using recstoreps::CommandRequest;
32 using recstoreps::CommandResponse;
33 using recstoreps::GetParameterRequest;
34 using recstoreps::GetParameterResponse;
35 using recstoreps::InitEmbeddingTableRequest;
36 using recstoreps::InitEmbeddingTableResponse;
37 using recstoreps::PSCommand;
38 using recstoreps::PutParameterRequest;
39 using recstoreps::PutParameterResponse;
40 using recstoreps::UpdateParameterRequest;
41 using recstoreps::UpdateParameterResponse;
42
43 namespace {
44
45 184 void SetRpcDeadline(grpc::ClientContext* context, int timeout_ms = 15000) {
46
1/2
✓ Branch 1 taken 184 times.
✗ Branch 2 not taken.
184 context->set_deadline(
47
1/2
✓ Branch 3 taken 184 times.
✗ Branch 4 not taken.
184 std::chrono::system_clock::now() + std::chrono::milliseconds(timeout_ms));
48 184 }
49
50 } // namespace
51
52 DEFINE_int32(get_parameter_threads, 4, "get clients per shard");
53 DEFINE_bool(parameter_client_random_init, false, "");
54
55 // New constructor that takes JSON config.
56 /*
57 Example: load config from file
58 std::ifstream config_file(FLAGS_config_path);
59 nlohmann::json ex;
60 config_file >> ex;
61 json client_config = ex["client"];
62
63 */
64 34 GRPCParameterClient::GRPCParameterClient(json config) {
65 // Extract fields from JSON config
66
1/2
✓ Branch 1 taken 34 times.
✗ Branch 2 not taken.
34 host_ = config.value("host", "localhost");
67
1/2
✓ Branch 1 taken 34 times.
✗ Branch 2 not taken.
34 port_ = config.value("port", 15000);
68
1/2
✓ Branch 1 taken 34 times.
✗ Branch 2 not taken.
34 shard_ = config.value("shard", 0);
69 34 nr_clients_ = FLAGS_get_parameter_threads;
70 34 Initialize();
71
72
1/2
✓ Branch 1 taken 34 times.
✗ Branch 2 not taken.
34 grpc::ChannelArguments args;
73
1/2
✓ Branch 1 taken 34 times.
✗ Branch 2 not taken.
34 args.SetMaxReceiveMessageSize(-1);
74
1/2
✓ Branch 1 taken 34 times.
✗ Branch 2 not taken.
34 args.SetMaxSendMessageSize(-1);
75
76 34 channel_ = grpc::CreateCustomChannel(
77
2/4
✓ Branch 1 taken 34 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 34 times.
✗ Branch 5 not taken.
102 fmt::format("{}:{}", host_, port_),
78
1/2
✓ Branch 1 taken 34 times.
✗ Branch 2 not taken.
68 grpc::InsecureChannelCredentials(),
79 34 args);
80
2/4
✓ Branch 1 taken 34 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 34 times.
✗ Branch 5 not taken.
34 auto* raw_cq = new grpc::CompletionQueue();
81 34 cq_.reset(raw_cq);
82
83
2/2
✓ Branch 0 taken 136 times.
✓ Branch 1 taken 34 times.
170 for (int i = 0; i < nr_clients_; i++) {
84
1/2
✓ Branch 2 taken 136 times.
✗ Branch 3 not taken.
136 stubs_.push_back(nullptr);
85
1/2
✓ Branch 3 taken 136 times.
✗ Branch 4 not taken.
136 stubs_[i] = recstoreps::ParameterService::NewStub(channel_);
86
4/8
✓ Branch 1 taken 136 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 136 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 136 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 136 times.
✗ Branch 11 not taken.
136 LOG(INFO) << "Init PS Client Shard " << i;
87 }
88 34 }
89
90 // Legacy constructor for backward compatibility
91 2 GRPCParameterClient::GRPCParameterClient(
92 2 const std::string& host, int port, int shard)
93 2 : host_(host),
94 2 port_(port),
95 2 shard_(shard),
96
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 nr_clients_(FLAGS_get_parameter_threads) {
97 2 Initialize();
98
99
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 grpc::ChannelArguments args;
100
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 args.SetMaxReceiveMessageSize(-1);
101
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 args.SetMaxSendMessageSize(-1);
102
103 2 channel_ = grpc::CreateCustomChannel(
104
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 fmt::format("{}:{}", host, port),
105
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 grpc::InsecureChannelCredentials(),
106 2 args);
107
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 auto* raw_cq = new grpc::CompletionQueue();
108 2 cq_.reset(raw_cq);
109
110
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2 times.
10 for (int i = 0; i < nr_clients_; i++) {
111
1/2
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
8 stubs_.push_back(nullptr);
112
1/2
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
8 stubs_[i] = recstoreps::ParameterService::NewStub(channel_);
113
4/8
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 8 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 8 times.
✗ Branch 11 not taken.
8 LOG(INFO) << "Init PS Client Shard " << i;
114 }
115 2 }
116
117 72 int GRPCParameterClient::GetParameter(const base::ConstArray<uint64_t>& keys,
118 base::RecTensor& values) {
119 #ifdef ENABLE_PERF_REPORT
120 auto start_time = std::chrono::high_resolution_clock::now();
121 #endif
122
123
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 72 times.
72 if (!recstore::IsFloatEmbeddingValues(
124 72 values, static_cast<int64_t>(keys.Size()))) {
125 ✗ return -1;
126 }
127
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 72 times.
72 if (keys.Size() == 0) {
128 ✗ return 0;
129 }
130 72 const int64_t D = values.shape(1);
131 72 float* dst = values.data_as<float>();
132 72 std::memset(dst, 0, keys.Size() * static_cast<size_t>(D) * sizeof(float));
133
134
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
72 if (FLAGS_parameter_client_random_init) {
135
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ std::fill(dst, dst + keys.Size() * static_cast<size_t>(D), 0.1f);
136 ✗ return 0;
137 }
138 72 get_param_key_sizes_.clear();
139 72 get_param_status_.clear();
140 72 get_param_requests_.clear();
141 72 get_param_responses_.clear();
142 72 get_param_resonse_readers_.clear();
143 72 get_param_contexts_.clear();
144
145 int request_num =
146 72 (keys.Size() + MAX_PARAMETER_BATCH - 1) / MAX_PARAMETER_BATCH;
147
148 72 get_param_status_.resize(request_num);
149 72 get_param_requests_.resize(request_num);
150 72 get_param_responses_.resize(request_num);
151 72 get_param_contexts_.resize(request_num);
152
153
2/2
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 72 times.
144 for (int start = 0, index = 0; start < keys.Size();
154 72 start += MAX_PARAMETER_BATCH, ++index) {
155 72 int key_size = std::min((int)(keys.Size() - start), MAX_PARAMETER_BATCH);
156
1/2
✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
72 get_param_key_sizes_.emplace_back(key_size);
157 72 auto& status = get_param_status_[index];
158 72 auto& request = get_param_requests_[index];
159 72 auto& response = get_param_responses_[index];
160 72 request.set_keys(reinterpret_cast<const char*>(&keys[start]),
161 72 sizeof(uint64_t) * key_size);
162 // rpc
163 // grpc::ClientContext context;
164
1/2
✓ Branch 2 taken 72 times.
✗ Branch 3 not taken.
72 if (!get_param_contexts_[index]) {
165
1/2
✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
72 get_param_contexts_[index] = std::make_unique<grpc::ClientContext>();
166 }
167
2/4
✓ Branch 5 taken 72 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 72 times.
✗ Branch 9 not taken.
144 get_param_resonse_readers_.emplace_back(stubs_[0]->AsyncGetParameter(
168 72 get_param_contexts_[index].get(), request, cq_.get()));
169 72 auto& rpc = get_param_resonse_readers_.back();
170 // GetParameter(&context, request, &response);
171
1/2
✓ Branch 2 taken 72 times.
✗ Branch 3 not taken.
72 rpc->Finish(&response, &status, reinterpret_cast<void*>(index));
172 }
173
174 72 int get = 0;
175
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 72 times.
144 while (get != request_num) {
176 void* got_tag;
177 72 bool ok = false;
178
1/2
✓ Branch 2 taken 72 times.
✗ Branch 3 not taken.
72 cq_->Next(&got_tag, &ok);
179
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
72 if (unlikely(!ok)) {
180
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) << "error";
181 }
182 72 get++;
183 }
184
185 #ifdef ENABLE_PERF_REPORT
186 auto after_rpc_time = std::chrono::high_resolution_clock::now();
187 auto rpc_duration =
188 std::chrono::duration_cast<std::chrono::microseconds>(
189 after_rpc_time - start_time)
190 .count();
191 double start_us_for_rpc =
192 std::chrono::duration_cast<std::chrono::microseconds>(
193 start_time.time_since_epoch())
194 .count();
195 std::string report_id_for_rpc =
196 "grpc_client::GetParameter|" +
197 std::to_string(static_cast<uint64_t>(start_us_for_rpc));
198 report("embread_stages",
199 report_id_for_rpc.c_str(),
200 "rpc_duration_us",
201 static_cast<double>(rpc_duration));
202 #endif
203
204 72 size_t row_offset = 0;
205
2/2
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 72 times.
144 for (int i = 0; i < get_param_responses_.size(); ++i) {
206 72 auto& response = get_param_responses_[i];
207 72 int key_size = get_param_key_sizes_[i];
208
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 72 times.
72 if (response.parameter_value().empty()) {
209 ✗ row_offset += static_cast<size_t>(key_size);
210 ✗ continue;
211 }
212 auto parameters = reinterpret_cast<const ParameterCompressReader*>(
213 72 response.parameter_value().data());
214
2/4
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 72 times.
72 if (parameters == nullptr || parameters->size == 0) {
215 ✗ row_offset += static_cast<size_t>(key_size);
216 ✗ continue;
217 }
218
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
72 if (unlikely(parameters->size != key_size)) {
219
0/8
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ LOG(ERROR) << "GetParameter error: " << parameters->size << " vs "
220
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ << key_size;
221 ✗ return -1;
222 }
223
224 72 CopyCompressItemsToFlat(parameters, dst, D, row_offset);
225 72 row_offset += static_cast<size_t>(key_size);
226 }
227
228 #ifdef ENABLE_PERF_REPORT
229 auto end_time = std::chrono::high_resolution_clock::now();
230 auto duration =
231 std::chrono::duration_cast<std::chrono::microseconds>(
232 end_time - start_time)
233 .count();
234 double start_us =
235 std::chrono::duration_cast<std::chrono::microseconds>(
236 start_time.time_since_epoch())
237 .count();
238
239 auto deserialize_duration =
240 std::chrono::duration_cast<std::chrono::microseconds>(
241 end_time - after_rpc_time)
242 .count();
243
244 report("embread_stages",
245 "grpc_client::GetParameter",
246 "deserialize_duration_us",
247 static_cast<double>(deserialize_duration));
248
249 report("embread_stages",
250 "grpc_client::GetParameter",
251 "duration_us",
252 static_cast<double>(duration));
253
254 report("embread_stages",
255 "grpc_client::GetParameter",
256 "request_size",
257 static_cast<double>(keys.Size()));
258
259 FlameGraphData grpc_client_data = {
260 "grpc_ps_client::GetParameter",
261 start_us,
262 1, // level
263 static_cast<double>(duration),
264 static_cast<double>(duration)};
265
266 std::string unique_id = "embread_debug";
267 report_flame_graph("emb_read_flame_map", unique_id.c_str(), grpc_client_data);
268 #endif
269
270 72 return 0;
271 }
272
273 // return prefetch id
274 uint64_t
275 112 GRPCParameterClient::PrefetchParameter(const base::ConstArray<uint64_t>& keys) {
276 int request_num =
277 112 (keys.Size() + MAX_PARAMETER_BATCH - 1) / MAX_PARAMETER_BATCH;
278
279
1/2
✓ Branch 1 taken 112 times.
✗ Branch 2 not taken.
112 struct PrefetchBatch pb(request_num);
280
281
2/2
✓ Branch 1 taken 112 times.
✓ Branch 2 taken 112 times.
224 for (int start = 0, index = 0; start < keys.Size();
282 112 start += MAX_PARAMETER_BATCH, ++index) {
283 112 int key_size = std::min((int)(keys.Size() - start), MAX_PARAMETER_BATCH);
284 112 pb.key_sizes_[index] = key_size;
285 112 auto& status = pb.status_[index];
286
1/2
✓ Branch 2 taken 112 times.
✗ Branch 3 not taken.
112 if (!pb.contexts_[index]) {
287
1/2
✓ Branch 1 taken 112 times.
✗ Branch 2 not taken.
112 pb.contexts_[index] = std::make_unique<grpc::ClientContext>();
288 }
289 112 auto& request = pb.requests_[index];
290 112 auto& response = pb.responses_[index];
291 112 request.set_keys(reinterpret_cast<const char*>(&keys[start]),
292 112 sizeof(uint64_t) * key_size);
293 // rpc
294 // grpc::ClientContext context;
295
2/4
✓ Branch 5 taken 112 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 112 times.
✗ Branch 9 not taken.
224 pb.response_readers_.emplace_back(stubs_[0]->AsyncGetParameter(
296 112 pb.contexts_[index].get(), request, pb.cqs_.get()));
297 112 auto& rpc = pb.response_readers_.back();
298 // GetParameter(&context, request, &response);
299
1/2
✓ Branch 2 taken 112 times.
✗ Branch 3 not taken.
112 rpc->Finish(&response, &status, reinterpret_cast<void*>(index));
300 }
301 112 uint64_t prefetch_id = 0;
302 {
303
1/2
✓ Branch 1 taken 112 times.
✗ Branch 2 not taken.
112 std::lock_guard<std::mutex> lk(prefetch_mu_);
304 112 prefetch_id = next_prefetch_id_++;
305
1/2
✓ Branch 2 taken 112 times.
✗ Branch 3 not taken.
112 prefetch_batches_.emplace(prefetch_id, std::move(pb));
306 112 }
307
308 112 return prefetch_id;
309 112 }
310
311 4 bool GRPCParameterClient::IsPrefetchDone(uint64_t prefetch_id) {
312
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 std::lock_guard<std::mutex> lk(prefetch_mu_);
313
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 auto it = prefetch_batches_.find(prefetch_id);
314
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
4 if (it == prefetch_batches_.end()) {
315
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;
316 ✗ return false;
317 }
318 4 auto& pb = it->second;
319 4 int request_num = pb.batch_size_;
320 4 int get = 0;
321
322
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (pb.completed_count_ == pb.batch_size_) {
323 4 return true;
324 }
325
326 ✗ void* got_tag = nullptr;
327 ✗ bool ok = false;
328 auto deadline =
329
0/2
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ std::chrono::system_clock::now() + std::chrono::milliseconds(0);
330 for (;;) {
331
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ auto status = pb.cqs_->AsyncNext(&got_tag, &ok, deadline);
332
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ if (status == grpc::CompletionQueue::NextStatus::GOT_EVENT) {
333
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ if (unlikely(!ok)) {
334
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) << "CompletionQueue returned not ok for prefetch";
335 }
336 ✗ pb.completed_count_++;
337
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ if (pb.completed_count_ == pb.batch_size_)
338 ✗ break;
339 deadline =
340
0/2
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ std::chrono::system_clock::now() + std::chrono::milliseconds(0);
341 ✗ continue;
342
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ } else if (status == grpc::CompletionQueue::NextStatus::TIMEOUT) {
343 ✗ break;
344 } else {
345
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) << "CompletionQueue shutdown during prefetch";
346 ✗ break;
347 }
348 ✗ }
349 ✗ return (pb.completed_count_ == pb.batch_size_);
350 4 }
351
352 212 void GRPCParameterClient::WaitForPrefetch(uint64_t prefetch_id) {
353
1/2
✓ Branch 1 taken 212 times.
✗ Branch 2 not taken.
212 std::lock_guard<std::mutex> lk(prefetch_mu_);
354
1/2
✓ Branch 1 taken 212 times.
✗ Branch 2 not taken.
212 auto it = prefetch_batches_.find(prefetch_id);
355
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 212 times.
212 if (it == prefetch_batches_.end()) {
356
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;
357 ✗ return;
358 }
359 212 auto& pb = it->second;
360 212 void* got_tag = nullptr;
361 212 bool ok = false;
362 212 int idle_rounds = 0;
363 212 constexpr auto kPollInterval = std::chrono::milliseconds(200);
364 212 constexpr int kMaxIdleRounds = 150; // 30s
365
2/2
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 212 times.
324 while (pb.completed_count_ < pb.batch_size_) {
366
1/2
✓ Branch 2 taken 112 times.
✗ Branch 3 not taken.
112 auto deadline = std::chrono::system_clock::now() + kPollInterval;
367
1/2
✓ Branch 2 taken 112 times.
✗ Branch 3 not taken.
112 auto status = pb.cqs_->AsyncNext(&got_tag, &ok, deadline);
368
1/2
✓ Branch 0 taken 112 times.
✗ Branch 1 not taken.
112 if (status == grpc::CompletionQueue::NextStatus::GOT_EVENT) {
369 112 idle_rounds = 0;
370
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 112 times.
112 if (unlikely(!ok)) {
371
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) << "CompletionQueue returned not ok for prefetch";
372 }
373 112 pb.completed_count_++;
374 112 continue;
375 }
376
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ if (status == grpc::CompletionQueue::NextStatus::TIMEOUT) {
377 ✗ idle_rounds++;
378
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ if (idle_rounds >= kMaxIdleRounds) {
379
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) << "WaitForPrefetch timed out for prefetch_id "
380
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ << prefetch_id << ", completed " << pb.completed_count_
381
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.
✗ << "/" << pb.batch_size_;
382 ✗ break;
383 }
384 ✗ continue;
385 }
386
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ if (status == grpc::CompletionQueue::NextStatus::SHUTDOWN) {
387
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) << "CompletionQueue shutdown while waiting prefetch";
388 ✗ break;
389 }
390 }
391
1/2
✓ Branch 1 taken 212 times.
✗ Branch 2 not taken.
212 }
392
393 112 bool GRPCParameterClient::GetPrefetchResult(uint64_t prefetch_id,
394 base::RecTensor& values) {
395
1/2
✓ Branch 1 taken 112 times.
✗ Branch 2 not taken.
112 std::lock_guard<std::mutex> lk(prefetch_mu_);
396
1/2
✓ Branch 1 taken 112 times.
✗ Branch 2 not taken.
112 auto it = prefetch_batches_.find(prefetch_id);
397
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 112 times.
112 if (it == prefetch_batches_.end()) {
398
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;
399 ✗ return false;
400 }
401 112 auto& pb = it->second;
402 112 int request_num = pb.batch_size_;
403
404 112 int keys_size = 0;
405
2/2
✓ Branch 4 taken 112 times.
✓ Branch 5 taken 112 times.
224 for (const auto& size : pb.key_sizes_) {
406 112 keys_size += size;
407 }
408
3/4
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 104 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 8 times.
112 const bool discard = values.data() == nullptr && values.dim() == 0;
409
4/8
✓ Branch 0 taken 112 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 112 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 112 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 112 times.
112 if (!discard && !recstore::EnsureEmbeddingOutput(
410 values, static_cast<int64_t>(keys_size))) {
411 ✗ return false;
412 }
413
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 112 times.
✓ Branch 3 taken 112 times.
✗ Branch 4 not taken.
112 const int64_t D = discard ? 0 : values.shape(1);
414
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 112 times.
✓ Branch 3 taken 112 times.
✗ Branch 4 not taken.
112 float* dst = discard ? nullptr : values.data_as<float>();
415
3/6
✓ Branch 0 taken 112 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 112 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 112 times.
✗ Branch 5 not taken.
112 if (!discard && dst != nullptr && keys_size > 0) {
416 112 std::memset(dst,
417 0,
418 112 static_cast<size_t>(keys_size) * static_cast<size_t>(D) *
419 sizeof(float));
420 }
421 112 size_t row_offset = 0;
422
423
2/2
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 112 times.
224 for (int i = 0; i < request_num; ++i) {
424 112 auto& response = pb.responses_[i];
425 112 int key_size = pb.key_sizes_[i];
426
2/4
✓ Branch 1 taken 112 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 112 times.
112 if (response.parameter_value().empty()) {
427 ✗ row_offset += static_cast<size_t>(key_size);
428 ✗ continue;
429 }
430 auto parameters = reinterpret_cast<const ParameterCompressReader*>(
431
1/2
✓ Branch 1 taken 112 times.
✗ Branch 2 not taken.
112 response.parameter_value().data());
432
433
2/4
✓ Branch 0 taken 112 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 112 times.
112 if (parameters == nullptr || parameters->size == 0) {
434 ✗ row_offset += static_cast<size_t>(key_size);
435 ✗ continue;
436 }
437
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 112 times.
112 if (unlikely(parameters->size != key_size)) {
438
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 "
439
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ << key_size;
440 ✗ return false;
441 }
442
443
1/2
✓ Branch 0 taken 112 times.
✗ Branch 1 not taken.
112 if (!discard) {
444
1/2
✓ Branch 1 taken 112 times.
✗ Branch 2 not taken.
112 CopyCompressItemsToFlat(parameters, dst, D, row_offset);
445 112 row_offset += static_cast<size_t>(key_size);
446 }
447 }
448
449 112 return true;
450 112 }
451
452 26 bool GRPCParameterClient::ClearPS() {
453
1/2
✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
26 CommandRequest request;
454
1/2
✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
26 CommandResponse response;
455
1/2
✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
26 request.set_command(PSCommand::CLEAR_PS);
456
1/2
✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
26 grpc::ClientContext context;
457
1/2
✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
26 SetRpcDeadline(&context);
458
1/2
✓ Branch 3 taken 26 times.
✗ Branch 4 not taken.
26 grpc::Status status = stubs_[0]->Command(&context, request, &response);
459
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 26 times.
26 if (!status.ok()) {
460
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) << "gRPC ClearPS failed: " << status.error_code() << " "
461
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.
✗ << status.error_message();
462 }
463 52 return status.ok();
464 26 }
465
466 // Read n bytes from the server. The server does not access storage;
467 // it generates data randomly instead.
468 2 bool GRPCParameterClient::LoadFakeData(int64_t n) {
469
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 CommandRequest request;
470
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 CommandResponse response;
471
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 request.set_command(PSCommand::LOAD_FAKE_DATA);
472
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 request.add_arg1(&n, sizeof(int64_t));
473
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 grpc::ClientContext context;
474
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 SetRpcDeadline(&context);
475
1/2
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
2 grpc::Status status = stubs_[0]->Command(&context, request, &response);
476
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (!status.ok()) {
477
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) << "gRPC LoadFakeData failed: " << status.error_code() << " "
478
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.
✗ << status.error_message();
479 ✗ return false;
480 }
481
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
2 if (response.reply().size() != static_cast<size_t>(n)) {
482
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) << "gRPC LoadFakeData reply size mismatch: expected " << n
483
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();
484 ✗ return false;
485 }
486 2 return true;
487 2 }
488
489 // Write n bytes(random generated) into the server
490 2 bool GRPCParameterClient::DumpFakeData(int64_t n) {
491
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 CommandRequest request;
492
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 CommandResponse response;
493
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 request.set_command(PSCommand::DUMP_FAKE_DATA);
494
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 request.add_arg1(&n, sizeof(int64_t));
495
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 grpc::ClientContext context;
496
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 SetRpcDeadline(&context);
497
1/2
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
2 grpc::Status status = stubs_[0]->Command(&context, request, &response);
498
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (!status.ok()) {
499
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) << "gRPC DumpFakeData failed: " << status.error_code() << " "
500
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.
✗ << status.error_message();
501 ✗ return false;
502 }
503
3/6
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
2 if (response.reply() != "ok") {
504
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) << "gRPC DumpFakeData unexpected reply: " << response.reply();
505 ✗ return false;
506 }
507 2 return true;
508 2 }
509
510 ✗ bool GRPCParameterClient::LoadCkpt(
511 const std::vector<std::string>& model_config_path,
512 const std::vector<std::string>& emb_file_path) {
513
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ CommandRequest request;
514
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ CommandResponse response;
515
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ request.set_command(PSCommand::RELOAD_PS);
516
517
0/2
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ for (auto& each : model_config_path) {
518
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ request.add_arg1(each);
519 }
520
0/2
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ for (auto& each : emb_file_path) {
521
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ request.add_arg2(each);
522 }
523
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ grpc::ClientContext context;
524
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ SetRpcDeadline(&context, 30000);
525
0/2
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ grpc::Status status = stubs_[0]->Command(&context, request, &response);
526 ✗ return status.ok();
527 ✗ }
528
529 ✗ bool GRPCParameterClient::SaveCheckpoint(const std::string& path,
530 const std::string& metadata) {
531
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ CommandRequest request;
532
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ CommandResponse response;
533
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ request.set_command(PSCommand::SAVE_CHECKPOINT);
534
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ request.add_arg1(path);
535
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ request.add_arg2(metadata);
536
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ grpc::ClientContext context;
537
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ SetRpcDeadline(&context, 600000);
538
0/2
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ const grpc::Status status = stubs_[0]->Command(&context, request, &response);
539
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ if (!status.ok()) {
540
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) << "gRPC checkpoint save failed: " << status.error_code() << " "
541
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.
✗ << status.error_message();
542 }
543 ✗ return status.ok();
544 ✗ }
545
546 ✗ bool GRPCParameterClient::LoadCheckpoint(const std::string& path,
547 const std::string& metadata) {
548
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ CommandRequest request;
549
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ CommandResponse response;
550
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ request.set_command(PSCommand::LOAD_CHECKPOINT);
551
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ request.add_arg1(path);
552
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ request.add_arg2(metadata);
553
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ grpc::ClientContext context;
554
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ SetRpcDeadline(&context, 600000);
555
0/2
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ const grpc::Status status = stubs_[0]->Command(&context, request, &response);
556
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ if (!status.ok()) {
557
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) << "gRPC checkpoint load failed: " << status.error_code() << " "
558
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.
✗ << status.error_message();
559 }
560 ✗ return status.ok();
561 ✗ }
562
563 152 bool GRPCParameterClient::PutParameter(const std::vector<uint64_t>& keys,
564 const base::RecTensor& values) {
565
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 152 times.
152 if (!recstore::IsFloatEmbeddingValues(
566 152 values, static_cast<int64_t>(keys.size()))) {
567
0/6
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ LOG(ERROR) << "PutParameter keys/values size mismatch: " << keys.size();
568 ✗ return false;
569 }
570
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 152 times.
152 const int64_t D = keys.empty() ? 0 : values.shape(1);
571
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 152 times.
152 const float* src = keys.empty() ? nullptr : values.data_as<float>();
572
2/2
✓ Branch 1 taken 152 times.
✓ Branch 2 taken 152 times.
304 for (int start = 0, index = 0; start < keys.size();
573 152 start += MAX_PARAMETER_BATCH, ++index) {
574 152 int key_size = std::min((int)(keys.size() - start), MAX_PARAMETER_BATCH);
575
1/2
✓ Branch 1 taken 152 times.
✗ Branch 2 not taken.
152 PutParameterRequest request;
576
1/2
✓ Branch 1 taken 152 times.
✗ Branch 2 not taken.
152 PutParameterResponse response;
577
1/2
✓ Branch 1 taken 152 times.
✗ Branch 2 not taken.
152 ParameterCompressor compressor;
578 152 std::vector<std::string> blocks;
579 304 CompressEmbeddingRows(
580 &compressor,
581
1/2
✓ Branch 1 taken 152 times.
✗ Branch 2 not taken.
152 keys.data() + start,
582 152 src + start * D,
583 key_size,
584 D,
585 &blocks);
586
1/2
✓ Branch 1 taken 152 times.
✗ Branch 2 not taken.
152 compressor.ToBlock(&blocks);
587
2/8
✓ Branch 4 taken 152 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 152 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
152 CHECK_EQ(blocks.size(), 1);
588
1/2
✓ Branch 1 taken 152 times.
✗ Branch 2 not taken.
152 request.mutable_parameter_value()->swap(blocks[0]);
589
1/2
✓ Branch 1 taken 152 times.
✗ Branch 2 not taken.
152 grpc::ClientContext context;
590
1/2
✓ Branch 1 taken 152 times.
✗ Branch 2 not taken.
152 SetRpcDeadline(&context);
591
1/2
✓ Branch 3 taken 152 times.
✗ Branch 4 not taken.
152 grpc::Status status = stubs_[0]->PutParameter(&context, request, &response);
592
1/2
✓ Branch 1 taken 152 times.
✗ Branch 2 not taken.
152 if (status.ok()) {
593 152 continue;
594 } else {
595
0/8
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ std::cout << status.error_code() << ": " << status.error_message()
596
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ << std::endl;
597 ✗ return false;
598 }
599
6/12
✓ Branch 1 taken 152 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 152 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 152 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 152 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 152 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 152 times.
✗ Branch 17 not taken.
912 }
600 152 return true;
601 }
602
603 2 int GRPCParameterClient::UpdateParameter(const std::string& table_name,
604 const base::ConstArray<uint64_t>& keys,
605 const base::RecTensor& grads) {
606 #ifdef ENABLE_PERF_REPORT
607 auto start_time = std::chrono::high_resolution_clock::now();
608 const uint64_t trace_id = recstore::g_trace_id;
609 #endif
610
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
2 if (!recstore::IsFloatEmbeddingValues(
611 2 grads, static_cast<int64_t>(keys.Size()))) {
612
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();
613 ✗ return -1;
614 }
615
616
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 ParameterCompressor compressor;
617
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if (keys.Size() > 0) {
618
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
4 CompressEmbeddingRows(
619 &compressor,
620 keys.Data(),
621
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 grads.data_as<float>(),
622 2 keys.Size(),
623 grads.shape(1));
624 }
625 #ifdef ENABLE_PERF_REPORT
626 auto serialize_done_time = std::chrono::high_resolution_clock::now();
627 #endif
628
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (keys.Size() == 0) {
629
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";
630 ✗ return 0;
631 }
632
633
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 UpdateParameterRequest request;
634
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 UpdateParameterResponse response;
635 request.set_table_name(table_name);
636
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 compressor.ToBlock(request.mutable_gradients());
637
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
2 if (request.gradients().empty()) {
638
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 serialized gradients payload";
639 ✗ return 0;
640 }
641
642
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 grpc::ClientContext context;
643
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 SetRpcDeadline(&context);
644 #ifdef ENABLE_PERF_REPORT
645 if (trace_id != 0) {
646 context.AddMetadata("x-recstore-trace-id", std::to_string(trace_id));
647 }
648 auto rpc_start_time = std::chrono::high_resolution_clock::now();
649 #endif
650 grpc::Status status =
651
1/2
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
2 stubs_[0]->UpdateParameter(&context, request, &response);
652 #ifdef ENABLE_PERF_REPORT
653 auto end_time = std::chrono::high_resolution_clock::now();
654 auto serialize_duration =
655 std::chrono::duration_cast<std::chrono::microseconds>(
656 serialize_done_time - start_time)
657 .count();
658 auto rpc_duration =
659 std::chrono::duration_cast<std::chrono::microseconds>(
660 end_time - rpc_start_time)
661 .count();
662 auto total_duration =
663 std::chrono::duration_cast<std::chrono::microseconds>(
664 end_time - start_time)
665 .count();
666 std::string stage_id =
667 "grpc_client::EmbUpdate|" +
668 std::to_string(
669 trace_id == 0
670 ? static_cast<uint64_t>(
671 std::chrono::duration_cast< std::chrono::microseconds>(
672 start_time.time_since_epoch())
673 .count())
674 : trace_id);
675 report("embupdate_stages",
676 stage_id.c_str(),
677 "client_serialize_us",
678 static_cast<double>(serialize_duration));
679 report("embupdate_stages",
680 stage_id.c_str(),
681 "client_rpc_us",
682 static_cast<double>(rpc_duration));
683 report("embupdate_stages",
684 stage_id.c_str(),
685 "client_total_us",
686 static_cast<double>(total_duration));
687 report("embupdate_stages",
688 stage_id.c_str(),
689 "client_request_size",
690 static_cast<double>(keys.Size()));
691 #endif
692
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (!status.ok()) {
693
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: " << status.error_message();
694 ✗ return -1;
695 }
696
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
2 return response.success() ? 0 : -1;
697 2 }
698
699 20 int GRPCParameterClient::InitEmbeddingTable(
700 const std::string& table_name,
701 const recstore::EmbeddingTableConfig& config) {
702
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 InitEmbeddingTableRequest request;
703
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 InitEmbeddingTableResponse response;
704 request.set_table_name(table_name);
705
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
40 request.set_config_payload(config.Serialize());
706
707
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 grpc::ClientContext context;
708 grpc::Status status =
709
1/2
✓ Branch 3 taken 20 times.
✗ Branch 4 not taken.
20 stubs_[0]->InitEmbeddingTable(&context, request, &response);
710
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
20 if (!status.ok()) {
711
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: " << status.error_message();
712 ✗ return -1;
713 }
714
3/6
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 20 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 20 times.
✗ Branch 7 not taken.
20 return response.success() ? response.tag() : -1;
715 20 }
716
717 // BasePSClient pure virtual implementations
718 // int GRPCParameterClient::GetParameter(const base::ConstArray<uint64_t>& keys,
719 // float* values) {
720 // return GetParameter(ConstArray<uint64_t>(keys.Data(), keys.Size()), values)
721 // ? 0 : -1;
722 // }
723
724 142 int GRPCParameterClient::PutParameter(const base::ConstArray<uint64_t>& keys,
725 const base::RecTensor& values) {
726
1/2
✓ Branch 5 taken 142 times.
✗ Branch 6 not taken.
142 std::vector<uint64_t> key_vec(keys.Data(), keys.Data() + keys.Size());
727
1/2
✓ Branch 1 taken 142 times.
✗ Branch 2 not taken.
142 bool success = PutParameter(key_vec, values);
728
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 142 times.
142 if (!success) {
729
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) << "PutParameter batch failed";
730 }
731
1/2
✓ Branch 0 taken 142 times.
✗ Branch 1 not taken.
284 return success ? 0 : -1;
732 142 }
733
734 ✗ void GRPCParameterClient::Command(recstore::PSCommand command) {
735
0/6
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ switch (command) {
736 ✗ case recstore::PSCommand::CLEAR_PS:
737 ✗ ClearPS();
738 ✗ break;
739 ✗ case recstore::PSCommand::RELOAD_PS:
740
741
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";
742 ✗ break;
743 ✗ case recstore::PSCommand::LOAD_FAKE_DATA: {
744 ✗ int64_t fake_data = 1000;
745 ✗ LoadFakeData(fake_data);
746 ✗ } break;
747 ✗ case recstore::PSCommand::DUMP_FAKE_DATA: {
748 ✗ DumpFakeData(4096);
749 ✗ } break;
750 ✗ case recstore::PSCommand::SAVE_CHECKPOINT:
751 case recstore::PSCommand::LOAD_CHECKPOINT:
752
0/4
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ LOG(WARNING) << "Checkpoint command requires path and metadata";
753 ✗ break;
754 ✗ default:
755
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);
756 ✗ break;
757 }
758 ✗ }
759
760 ✗ int64_t GRPCParameterClient::ExchangeSparseGradientCommit(
761 const std::string& table, const std::string& payload) {
762
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ recstoreps::SparseGradientCommitRequest request;
763
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ recstoreps::SparseGradientCommitResponse response;
764 request.set_table_name(table);
765 request.set_payload(payload);
766
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ grpc::ClientContext context;
767
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ SetRpcDeadline(&context);
768 const auto status =
769
0/2
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ stubs_[0]->SparseGradientCommit(&context, request, &response);
770
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 9 not taken.
✗ Branch 10 not taken.
✗ if (!status.ok() || !response.error().empty()) {
771
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ throw std::runtime_error(
772
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ "SparseGradientCommit: " +
773
0/8
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ (status.ok() ? response.error() : status.error_message()));
774 }
775
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ return response.committed_step();
776 ✗ }
777