src/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
5 / 78
6.4%
Branches:
3 / 160
1.9%
Functions:
1 / 4
25.0%

framework/pytorch/op_flat.cc
Line Branch Exec Source
1 #include "framework/pytorch/op_flat.h"
2
3 #include <torch/extension.h>
4
5 #include "framework/pytorch/op_internal.h"
6
7 namespace recstore {
8 namespace framework {
9 namespace {
10
11 torch::Tensor
12 ✗ local_lookup_flat_torch(const torch::Tensor& keys, int64_t embedding_dim) {
13 ✗ return std::get<0>(CachedReadTorch(keys, embedding_dim, true));
14 }
15
16 ✗ void local_update_flat_torch(const std::string& table_name,
17 const torch::Tensor& keys,
18 const torch::Tensor& grads) {
19
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ ResetLocalUpdateFlatProfile();
20 #ifdef RECSTORE_ENABLE_GPU_CACHE
21 gpu::ResetLastGpuCacheProfile();
22 #endif
23 ✗ const auto total_start = SteadyNow();
24
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ TORCH_CHECK(!table_name.empty(), "table_name must be non-empty");
25
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ TORCH_CHECK(keys.dim() == 1, "Keys tensor must be 1-dimensional");
26
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ TORCH_CHECK(keys.scalar_type() == torch::kInt64,
27 "Keys tensor must have dtype int64");
28
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ TORCH_CHECK(keys.is_contiguous(), "Keys tensor must be contiguous");
29
30
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ TORCH_CHECK(grads.dim() == 2, "Grads tensor must be 2-dimensional");
31
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ TORCH_CHECK(grads.scalar_type() == torch::kFloat32,
32 "Grads tensor must have dtype float32");
33
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ TORCH_CHECK(grads.is_contiguous(), "Grads tensor must be contiguous");
34
0/6
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ TORCH_CHECK(keys.size(0) == grads.size(0),
35 "Keys and grads tensors must have the same number of entries");
36
37
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ auto kv_op = GetConcreteKVClientOp();
38
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ kv_op->RequireLocalBackend();
39
40
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ if (keys.size(0) == 0) {
41
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ g_last_local_update_flat_profile[kUpdateTotalMs] = ElapsedMs(total_start);
42 ✗ return;
43 }
44
45
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ torch::Tensor cpu_keys = keys;
46 const bool can_async_stage_cuda =
47
0/8
✗ 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 8 not taken.
✗ Branch 9 not taken.
✗ (keys.is_cuda() || grads.is_cuda()) &&
48
0/14
✗ 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 8 not taken.
✗ Branch 9 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ (!keys.is_cuda() || !grads.is_cuda() || keys.device() == grads.device());
49 ✗ bool staged_cuda_async = false;
50
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ if (keys.is_cuda()) {
51 ✗ const auto keys_stage_start = SteadyNow();
52
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ if (can_async_stage_cuda) {
53
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ cpu_keys = StageCudaTensorToPinnedCpuAsyncNoCast(keys);
54 ✗ staged_cuda_async = true;
55 } else {
56
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ cpu_keys = StageCudaTensorToPinnedCpu(keys, torch::kInt64);
57 }
58 ✗ g_last_local_update_flat_profile[kUpdateKeysStageMs] =
59
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ ElapsedMs(keys_stage_start);
60 }
61
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ torch::Tensor cpu_grads = grads;
62
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ if (grads.is_cuda()) {
63 ✗ const auto grads_stage_start = SteadyNow();
64
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ if (can_async_stage_cuda) {
65
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ cpu_grads = StageCudaTensorToPinnedCpuAsyncNoCast(grads);
66 ✗ staged_cuda_async = true;
67 } else {
68
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ cpu_grads = StageCudaTensorToPinnedCpu(grads, torch::kFloat32);
69 }
70 ✗ g_last_local_update_flat_profile[kUpdateGradsStageMs] =
71
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ ElapsedMs(grads_stage_start);
72 }
73
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ if (staged_cuda_async) {
74 ✗ const auto stage_wait_start = SteadyNow();
75
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.
✗ SynchronizeCurrentCudaStreamForTensor(keys.is_cuda() ? keys : grads);
76 ✗ g_last_local_update_flat_profile[kUpdateStageWaitMs] =
77
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ ElapsedMs(stage_wait_start);
78 }
79
80
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ base::RecTensor rec_keys = ToRecTensor(cpu_keys, base::DataType::UINT64);
81
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ base::RecTensor rec_grads = ToRecTensor(cpu_grads, base::DataType::FLOAT32);
82
83 ✗ const auto shm_call_start = SteadyNow();
84
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ kv_op->EmbUpdateCached(
85
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ table_name, rec_keys, rec_grads, CacheActions(keys, grads.size(1)), true);
86 ✗ g_last_local_update_flat_profile[kUpdateShmCallMs] =
87
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ ElapsedMs(shm_call_start);
88
89 // Client-side split of the same round trip. The server half
90 // (kUpdateServerBackendMs) comes back in the slot header, so the remainder
91 // is slot acquire + copy + wake latency.
92
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ const auto last_request = GetLastLocalShmRequestProfile();
93
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ if (last_request.opcode == static_cast<uint32_t>(LocalOpcode::kUpdateFlat)) {
94 ✗ g_last_local_update_flat_profile[kUpdateSlotAcquireMs] =
95
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ last_request.acquire_slot_us / 1000.0;
96 ✗ g_last_local_update_flat_profile[kUpdateCopyEnqueueMs] =
97
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ last_request.enqueue_us / 1000.0;
98 ✗ g_last_local_update_flat_profile[kUpdateWaitMs] =
99
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ last_request.wait_us / 1000.0;
100 ✗ g_last_local_update_flat_profile[kUpdateServerQueueWaitMs] =
101
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ last_request.server_queue_wait_us / 1000.0;
102 ✗ g_last_local_update_flat_profile[kUpdateServerBackendMs] =
103
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ last_request.server_backend_us / 1000.0;
104 }
105
106
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ g_last_local_update_flat_profile[kUpdateTotalMs] = ElapsedMs(total_start);
107
0/2
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ }
108
109 ✗ bool warmup_local_lookup_flat_cuda_region_torch() {
110
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ auto kv_op = GetConcreteKVClientOp();
111 ✗ const void* payload_base = nullptr;
112 ✗ std::size_t payload_bytes = 0;
113
0/4
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ if (!kv_op->GetLocalLookupFlatPayloadRegion(&payload_base, &payload_bytes)) {
114 ✗ return false;
115 }
116
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ return EnsurePinnedLocalShmPayload(payload_base, payload_bytes);
117 ✗ }
118
119 } // namespace
120
121 16 void RegisterFlatOps(torch::Library& m) {
122
1/2
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
16 m.def("local_lookup_flat", local_lookup_flat_torch);
123
1/2
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
16 m.def("local_update_flat", local_update_flat_torch);
124
1/2
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
16 m.def("warmup_local_lookup_flat_cuda_region",
125 warmup_local_lookup_flat_cuda_region_torch);
126 16 }
127
128 } // namespace framework
129 } // namespace recstore
130