Skip to content

Commit e151b41

Browse files
Raahul Kalyaan Jakkafacebook-github-bot
Raahul Kalyaan Jakka
authored andcommitted
Adding helper function for enabling RocksDB Checkpoint (#4213)
Summary: X-link: facebookresearch/FBGEMM#1288 Design doc: https://docs.google.com/document/d/149LdAEHOLP7ei4hwVVkAFXGa4N9uLs1J7efxfBZp3dY/edit?tab=t.0#heading=h.49t3yfaqmt54 Context: We are enabling the usage of rocksDB checkpoint feature in KVTensorWrapper. This allows us to create checkpoints of the embedding tables in SSD. Later, these checkpoints are used by the checkpointing component to create a checkpoint and upload it it to the manifold In this diff: We are adding all the helper functions to create folder structures in SSDs for storing the rocksDB checkpoints Reviewed By: duduyi2013 Differential Revision: D75489819
1 parent 033f872 commit e151b41

File tree

3 files changed

+114
-19
lines changed

3 files changed

+114
-19
lines changed

fbgemm_gpu/include/fbgemm_gpu/split_embeddings_cache/kv_db_cpp_utils.h

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,20 @@
1010

1111
#include <ATen/ATen.h>
1212
#include <folly/hash/Hash.h>
13+
#include <glog/logging.h>
1314
#include <stddef.h>
1415
#include <stdint.h>
16+
#include <filesystem>
1517
#include <optional>
16-
1718
/// @defgroup embedding-ssd Embedding SSD Operators
1819
///
1920

2021
namespace kv_db_utils {
2122

23+
#ifdef FBGEMM_FBCODE
24+
constexpr size_t num_ssd_drives = 8;
25+
#endif
26+
2227
/// @ingroup embedding-ssd
2328
///
2429
/// @brief hash function used for SSD L2 cache and rocksdb sharding algorithm
@@ -65,4 +70,94 @@ std::tuple<at::Tensor, at::Tensor> get_bucket_sorted_indices_and_bucket_tensor(
6570
std::optional<int64_t> bucket_size,
6671
std::optional<int64_t> total_num_buckets);
6772

73+
/// @ingroup embedding-ssd
74+
///
75+
/// @brief default way to generate rocksdb path based on a user provided
76+
/// base_path the file hierarchy will be
77+
/// <base_path><ssd_idx>/<tbe_uuid> for default SSD mount
78+
/// <base_path>/<tbe_uuid> for user provided base path
79+
///
80+
/// @param base_path the base path for all the rocksdb shards tied to one
81+
/// TBE/EmbeddingRocksDB
82+
/// @param db_shard_id the rocksdb shard index, this is used to determine which
83+
/// SSD to use
84+
/// @param tbe_uuid unique identifier per TBE at the lifetime of a training job
85+
/// @param default_path whether the base_path is default SSD mount or
86+
/// user-provided
87+
///
88+
/// @return the base path to that rocksdb shard
89+
inline std::string get_rocksdb_path(
90+
const std::string& base_path,
91+
int db_shard_id,
92+
const std::string& tbe_uuid,
93+
bool default_path) {
94+
if (default_path) {
95+
int ssd_drive_idx = db_shard_id % num_ssd_drives;
96+
std::string ssd_idx_tbe_id_str =
97+
std::to_string(ssd_drive_idx) + std::string("/") + tbe_uuid;
98+
return base_path + ssd_idx_tbe_id_str;
99+
} else {
100+
return base_path + std::string("/") + tbe_uuid;
101+
}
102+
}
103+
104+
/// @ingroup embedding-ssd
105+
///
106+
/// @brief generate rocksdb shard path, based on rocksdb_path
107+
/// the file hierarchy will be
108+
/// <rocksdb_shard_path>/shard_<db_shard>
109+
///
110+
/// @param db_shard_id the rocksdb shard index
111+
/// @param rocksdb_path the base path for rocksdb shard
112+
///
113+
/// @return the rocksdb shard path
114+
inline std::string get_rocksdb_shard_path(
115+
int db_shard_id,
116+
const std::string& rocksdb_path) {
117+
return rocksdb_path + std::string("/shard_") + std::to_string(db_shard_id);
118+
}
119+
120+
/// @ingroup embedding-ssd
121+
///
122+
/// @brief generate a directory to hold rocksdb checkpoint for a particular
123+
/// rocksdb shard path the file hierarchy will be
124+
/// <rocksdb_shard_path>/checkpoint_shard_<db_shard>
125+
///
126+
/// @param db_shard_id the rocksdb shard index
127+
/// @param rocksdb_path the base path for rocksdb shard
128+
///
129+
/// @return the directory that holds rocksdb checkpoints for one rocksdb shard
130+
inline std::string get_rocksdb_checkpoint_dir(
131+
int db_shard_id,
132+
const std::string& rocksdb_path) {
133+
return rocksdb_path + std::string("/checkpoint_shard_") +
134+
std::to_string(db_shard_id);
135+
}
136+
137+
inline void create_dir(const std::string& dir_path) {
138+
try {
139+
std::filesystem::path fs_path(dir_path);
140+
bool res = std::filesystem::create_directories(fs_path);
141+
if (!res) {
142+
LOG(ERROR) << "dir: " << dir_path << " already exists";
143+
}
144+
} catch (const std::exception& e) {
145+
LOG(ERROR) << "Error creating directory: " << e.what();
146+
}
147+
}
148+
149+
inline void remove_dir(const std::string& path) {
150+
if (std::filesystem::exists(path)) {
151+
try {
152+
if (std::filesystem::is_directory(path)) {
153+
std::filesystem::remove_all(path);
154+
} else {
155+
std::filesystem::remove(path);
156+
}
157+
} catch (const std::filesystem::filesystem_error& e) {
158+
LOG(ERROR) << "Error removing path: " << path
159+
<< ", exception:" << e.what();
160+
}
161+
}
162+
}
68163
}; // namespace kv_db_utils

fbgemm_gpu/src/ssd_split_embeddings_cache/ssd_table_batched_embeddings.h

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,7 @@ namespace ssd {
3333

3434
using namespace at;
3535

36-
#ifdef FBGEMM_FBCODE
37-
constexpr size_t num_ssd_drives = 8;
3836
const std::string ssd_mount_point = "/data00_nvidia";
39-
const size_t base_port = 136000;
40-
#endif
4137

4238
// mem usage propertiese
4339
// -- block cache usage
@@ -320,23 +316,22 @@ class EmbeddingRocksDB : public kv_db::EmbeddingKVDB {
320316
auto db_monitor_options = facebook::fb_rocksdb::DBMonitorOptions();
321317
db_monitor_options.fb303Prefix = "tbe_metrics";
322318

323-
std::string tbe_uuid = "";
319+
tbe_uuid_ = facebook::strings::generateUUID();
320+
use_default_ssd_path_ = !use_passed_in_path;
324321
if (!use_passed_in_path) {
325-
path = ssd_mount_point;
326-
tbe_uuid = facebook::strings::generateUUID();
322+
path_ = std::move(ssd_mount_point);
323+
} else {
324+
path_ = std::move(path);
327325
}
326+
std::string all_shards_path;
328327
#endif
329328
for (auto i = 0; i < num_shards; ++i) {
330329
#ifdef FBGEMM_FBCODE
331-
int ssd_drive_idx = i % num_ssd_drives;
332-
std::string ssd_idx_tbe_id_str = "";
333-
if (!use_passed_in_path) {
334-
ssd_idx_tbe_id_str =
335-
std::to_string(ssd_drive_idx) + std::string("/") + tbe_uuid;
336-
}
337-
auto shard_path =
338-
path + ssd_idx_tbe_id_str + std::string("_shard") + std::to_string(i);
339-
used_path += shard_path + ", ";
330+
auto rocksdb_path = kv_db_utils::get_rocksdb_path(
331+
path_, i, tbe_uuid_, !use_passed_in_path);
332+
auto shard_path = kv_db_utils::get_rocksdb_shard_path(i, rocksdb_path);
333+
kv_db_utils::create_dir(shard_path);
334+
all_shards_path += shard_path + ", ";
340335
#else
341336
auto shard_path = path + std::string("/shard_") + std::to_string(i);
342337
#endif
@@ -369,7 +364,8 @@ class EmbeddingRocksDB : public kv_db::EmbeddingKVDB {
369364
dbs_.emplace_back(db);
370365
}
371366
#ifdef FBGEMM_FBCODE
372-
LOG(INFO) << "TBE actual used_path: " << used_path;
367+
LOG(INFO) << "TBE uuid: " << tbe_uuid_
368+
<< ", rocksdb shards paths: " << all_shards_path;
373369
#endif
374370
}
375371

@@ -1150,6 +1146,9 @@ class EmbeddingRocksDB : public kv_db::EmbeddingKVDB {
11501146
int64_t elem_size_;
11511147
std::vector<int64_t> sub_table_dims_;
11521148
std::vector<int64_t> sub_table_hash_cumsum_;
1149+
std::string tbe_uuid_;
1150+
std::string path_;
1151+
bool use_default_ssd_path_;
11531152
}; // class EmbeddingRocksDB
11541153

11551154
} // namespace ssd

fbgemm_gpu/test/tbe/ssd/embedding_cache/rocksdb_embedding_cache_test.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ TEST(RocksDbEmbeddingCacheTest, TestPutAndGet) {
3838
-0.01, // uniform_init_lower,
3939
0.01, // uniform_init_upper,
4040
32, // row_storage_bitwidth = 32,
41-
0 // cache_size = 0
41+
0, // cache_size = 0
42+
true // use_passed_in_path
4243
);
4344

4445
auto write_indices =

0 commit comments

Comments
 (0)