|
1 | 1 | #include "layer_split_utils.h" |
2 | 2 |
|
| 3 | +#include "common/peer_access.h" |
| 4 | +#include "common/snapshot_backend.h" |
| 5 | +#include "ggml-cuda.h" |
| 6 | + |
3 | 7 | #include <algorithm> |
4 | 8 | #include <cmath> |
| 9 | +#include <cstdio> |
5 | 10 | #include <set> |
6 | 11 |
|
7 | 12 | namespace dflash::common { |
8 | 13 |
|
9 | | -std::vector<std::pair<int,int>> compute_layer_ranges( |
| 14 | +std::vector<LayerSplitRange> compute_layer_ranges( |
10 | 15 | int n_layer, |
11 | 16 | int n_gpus, |
12 | 17 | const std::vector<double> & weights) |
13 | 18 | { |
14 | | - std::vector<std::pair<int,int>> ranges; |
| 19 | + std::vector<LayerSplitRange> ranges; |
15 | 20 | if (n_layer <= 0 || n_gpus <= 0 || n_gpus > n_layer) return ranges; |
16 | 21 |
|
17 | 22 | std::vector<double> w = weights; |
@@ -39,6 +44,72 @@ std::vector<std::pair<int,int>> compute_layer_ranges( |
39 | 44 | return ranges; |
40 | 45 | } |
41 | 46 |
|
| 47 | +bool init_layer_split_shard_metas( |
| 48 | + std::vector<LayerSplitShardMeta *> shards, |
| 49 | + const std::vector<int> & gpus, |
| 50 | + const std::vector<LayerSplitRange> & ranges, |
| 51 | + const char * log_prefix) { |
| 52 | + if (shards.size() != gpus.size() || shards.size() != ranges.size()) return false; |
| 53 | + const char * prefix = log_prefix ? log_prefix : "target-split"; |
| 54 | + for (size_t i = 0; i < shards.size(); ++i) { |
| 55 | + auto * shard = shards[i]; |
| 56 | + if (!shard) return false; |
| 57 | + shard->gpu = gpus[i]; |
| 58 | + shard->layer_begin = ranges[i].begin; |
| 59 | + shard->layer_end = ranges[i].end; |
| 60 | + shard->backend = ggml_backend_cuda_init(shard->gpu); |
| 61 | + if (!shard->backend) { |
| 62 | + std::fprintf(stderr, "[%s] backend init failed gpu=%d\n", |
| 63 | + prefix, shard->gpu); |
| 64 | + return false; |
| 65 | + } |
| 66 | + } |
| 67 | + return true; |
| 68 | +} |
| 69 | + |
| 70 | +bool enable_layer_split_peer_access( |
| 71 | + const std::vector<int> & gpus, |
| 72 | + bool peer_access) { |
| 73 | + if (!peer_access) return true; |
| 74 | + for (size_t i = 0; i < gpus.size(); ++i) { |
| 75 | + for (size_t j = i + 1; j < gpus.size(); ++j) { |
| 76 | + (void)enable_peer_access_pair(gpus[i], gpus[j]); |
| 77 | + } |
| 78 | + } |
| 79 | + return true; |
| 80 | +} |
| 81 | + |
| 82 | +bool init_layer_split_snapshot_backends( |
| 83 | + const std::vector<LayerSplitShardMeta *> & shards, |
| 84 | + std::vector<ggml_backend_t> & snapshot_backends, |
| 85 | + const char * log_prefix) { |
| 86 | + const char * prefix = log_prefix ? log_prefix : "target-split"; |
| 87 | + snapshot_backends.assign(shards.size(), nullptr); |
| 88 | + for (size_t i = 0; i < shards.size(); ++i) { |
| 89 | + const auto * shard = shards[i]; |
| 90 | + if (!shard || !shard->backend) return false; |
| 91 | + snapshot_backends[i] = create_snapshot_backend(shard->backend); |
| 92 | + if (!snapshot_backends[i]) { |
| 93 | + std::fprintf(stderr, |
| 94 | + "[%s] snapshot backend init failed gpu=%d\n", |
| 95 | + prefix, shard->gpu); |
| 96 | + return false; |
| 97 | + } |
| 98 | + } |
| 99 | + return true; |
| 100 | +} |
| 101 | + |
| 102 | +void free_layer_split_snapshot_backends( |
| 103 | + const std::vector<LayerSplitShardMeta *> & shards, |
| 104 | + std::vector<ggml_backend_t> & snapshot_backends) { |
| 105 | + const size_t n = std::min(shards.size(), snapshot_backends.size()); |
| 106 | + for (size_t i = 0; i < n; ++i) { |
| 107 | + if (!shards[i]) continue; |
| 108 | + free_snapshot_backend(snapshot_backends[i], shards[i]->backend); |
| 109 | + } |
| 110 | + snapshot_backends.clear(); |
| 111 | +} |
| 112 | + |
42 | 113 | std::string validate_device_placement( |
43 | 114 | const DevicePlacement & dp, |
44 | 115 | int device_count) |
|
0 commit comments