torch-ddp 0.1.4 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/examples/benchmark/training.rb +3 -4
- data/examples/mnist/distributed.rb +11 -10
- data/ext/torch_ddp/cuda.cpp +68 -0
- data/ext/torch_ddp/distributed.cpp +4 -4
- data/ext/torch_ddp/ext.cpp +2 -0
- data/ext/torch_ddp/extconf.rb +23 -6
- data/lib/torch/ddp/monkey_patch.rb +29 -37
- data/lib/torch/ddp/version.rb +1 -1
- data/lib/torch/ddp_ext.so +0 -0
- data/lib/torch/distributed.rb +15 -7
- metadata +10 -12
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 01c3dafea6b9ee6b691d59448137a325d54bd794c4004ac6cf519ac6d2961bc3
|
|
4
|
+
data.tar.gz: fbb84030108e52d0f54ce67ac43bb07ab1608d3878c8988bfcf91073e9e3f292
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f378128687e1c9db4deb53d01b5e10918d76456f586f1d9c35cca9ccdd3ac0f3effebf98724ad52d64c1ee38a4019e2996057791ddcc0cb6232e99a3263dc893
|
|
7
|
+
data.tar.gz: 2f028ae611ba90f2f664dbca9b37168f725d5bbe6743c2bd633e40e6d53e9083264e51407bb1365a699b17336a24454995866a492e01e16fb8a96cac0d89ce25
|
|
@@ -13,7 +13,7 @@ require "torchvision"
|
|
|
13
13
|
DEFAULT_BACKEND = if Torch.const_defined?(:CUDA) && Torch::CUDA.respond_to?(:available?) && Torch::CUDA.available?
|
|
14
14
|
"nccl"
|
|
15
15
|
else
|
|
16
|
-
Torch::Distributed.get_default_backend_for_device(
|
|
16
|
+
Torch::Distributed.get_default_backend_for_device(nil) || "gloo"
|
|
17
17
|
end
|
|
18
18
|
SPAWN_BACKEND_ENV = "TORCH_RB_BENCH_BACKEND".freeze
|
|
19
19
|
SPAWN_GROUP_ENV = "TORCH_RB_BENCH_GROUP_SIZE".freeze
|
|
@@ -181,8 +181,7 @@ def benchmark_worker(rank, world_size, port, options)
|
|
|
181
181
|
raise ArgumentError, "Unsupported architecture #{arch.inspect}" unless config
|
|
182
182
|
|
|
183
183
|
distributed = world_size > 1
|
|
184
|
-
|
|
185
|
-
selected_backend = options[:backend] || Torch::Distributed.get_default_backend_for_device(accelerator) || DEFAULT_BACKEND
|
|
184
|
+
selected_backend = options[:backend] || Torch::Distributed.get_default_backend_for_device(nil) || DEFAULT_BACKEND
|
|
186
185
|
if distributed
|
|
187
186
|
store = Torch::Distributed::TCPStore.new("127.0.0.1", port, world_size, rank.zero?)
|
|
188
187
|
Torch::Distributed.init_process_group(selected_backend, store: store, rank: rank, world_size: world_size)
|
|
@@ -350,7 +349,7 @@ results = []
|
|
|
350
349
|
|
|
351
350
|
backends.each do |backend|
|
|
352
351
|
unless backend_supported?(backend)
|
|
353
|
-
warn "Skipping backend=#{backend} because required
|
|
352
|
+
warn "Skipping backend=#{backend} because required CUDA support is unavailable."
|
|
354
353
|
next
|
|
355
354
|
end
|
|
356
355
|
|
|
@@ -17,7 +17,7 @@ DEFAULT_CHECKPOINT_PATH = File.join(Dir.tmpdir, "mnist_ddp_checkpoint.pt")
|
|
|
17
17
|
DEFAULT_BACKEND = if Torch.const_defined?(:CUDA) && Torch::CUDA.respond_to?(:available?) && Torch::CUDA.available?
|
|
18
18
|
"nccl"
|
|
19
19
|
else
|
|
20
|
-
Torch::Distributed.get_default_backend_for_device(
|
|
20
|
+
Torch::Distributed.get_default_backend_for_device(nil) || "gloo"
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
class MyNet < Torch::NN::Module
|
|
@@ -99,16 +99,18 @@ def subset_for_rank(dataset, rank, world_size)
|
|
|
99
99
|
end
|
|
100
100
|
|
|
101
101
|
def checkpoint_map_location(device, rank)
|
|
102
|
-
|
|
103
|
-
return nil unless
|
|
104
|
-
|
|
105
|
-
accelerator_type = accelerator_device.type
|
|
102
|
+
device_type = device&.type
|
|
103
|
+
return nil unless device_type && device_type != "cpu"
|
|
106
104
|
target_index = device.index
|
|
107
|
-
if target_index.nil?
|
|
108
|
-
count = Torch::
|
|
105
|
+
if target_index.nil?
|
|
106
|
+
count = if Torch.const_defined?(:CUDA) && Torch::CUDA.respond_to?(:device_count)
|
|
107
|
+
Torch::CUDA.device_count
|
|
108
|
+
else
|
|
109
|
+
0
|
|
110
|
+
end
|
|
109
111
|
target_index = count.positive? ? rank % count : 0
|
|
110
112
|
end
|
|
111
|
-
{ "#{
|
|
113
|
+
{ "#{device_type}:0" => "#{device_type}:#{target_index}" }
|
|
112
114
|
end
|
|
113
115
|
|
|
114
116
|
def load_checkpoint_if_present(ddp, device, rank, path)
|
|
@@ -173,8 +175,7 @@ end
|
|
|
173
175
|
|
|
174
176
|
def run_worker(rank, world_size, port, options)
|
|
175
177
|
store = Torch::Distributed::TCPStore.new("127.0.0.1", port, world_size, rank.zero?)
|
|
176
|
-
|
|
177
|
-
backend = options[:backend] || Torch::Distributed.get_default_backend_for_device(accelerator) || DEFAULT_BACKEND
|
|
178
|
+
backend = options[:backend] || Torch::Distributed.get_default_backend_for_device(nil) || DEFAULT_BACKEND
|
|
178
179
|
Torch::Distributed.init_process_group(backend, store: store, rank: rank, world_size: world_size)
|
|
179
180
|
|
|
180
181
|
device = if Torch::CUDA.available? && options[:gpus] > 0
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#include <torch/torch.h>
|
|
2
|
+
|
|
3
|
+
#include <rice/rice.hpp>
|
|
4
|
+
|
|
5
|
+
#if defined(WITH_CUDA)
|
|
6
|
+
#include <cuda_runtime_api.h>
|
|
7
|
+
#include <c10/cuda/CUDACachingAllocator.h>
|
|
8
|
+
#endif
|
|
9
|
+
|
|
10
|
+
namespace {
|
|
11
|
+
|
|
12
|
+
void register_cuda_helpers(Rice::Module& m) {
|
|
13
|
+
auto rb_mDDP = Rice::define_module_under(m, "DDP");
|
|
14
|
+
|
|
15
|
+
rb_mDDP.define_singleton_function(
|
|
16
|
+
"_cuda_set_device",
|
|
17
|
+
[](int device_id) {
|
|
18
|
+
#if defined(WITH_CUDA)
|
|
19
|
+
int count = 0;
|
|
20
|
+
auto status = cudaGetDeviceCount(&count);
|
|
21
|
+
if (status != cudaSuccess) {
|
|
22
|
+
rb_raise(
|
|
23
|
+
rb_eRuntimeError,
|
|
24
|
+
"cudaGetDeviceCount failed with code %d",
|
|
25
|
+
static_cast<int>(status));
|
|
26
|
+
}
|
|
27
|
+
if (device_id < 0 || device_id >= count) {
|
|
28
|
+
rb_raise(
|
|
29
|
+
rb_eArgError,
|
|
30
|
+
"Invalid device_id %d for CUDA (available devices: %d)",
|
|
31
|
+
device_id,
|
|
32
|
+
count);
|
|
33
|
+
}
|
|
34
|
+
status = cudaSetDevice(device_id);
|
|
35
|
+
if (status != cudaSuccess) {
|
|
36
|
+
rb_raise(
|
|
37
|
+
rb_eRuntimeError,
|
|
38
|
+
"cudaSetDevice(%d) failed with code %d",
|
|
39
|
+
device_id,
|
|
40
|
+
static_cast<int>(status));
|
|
41
|
+
}
|
|
42
|
+
#else
|
|
43
|
+
rb_raise(
|
|
44
|
+
rb_eRuntimeError,
|
|
45
|
+
"Torch::DDP._cuda_set_device requires CUDA support");
|
|
46
|
+
#endif
|
|
47
|
+
return Rice::Object(Qnil);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
rb_mDDP.define_singleton_function(
|
|
51
|
+
"_cuda_empty_cache",
|
|
52
|
+
[]() {
|
|
53
|
+
#if defined(WITH_CUDA)
|
|
54
|
+
c10::cuda::CUDACachingAllocator::emptyCache();
|
|
55
|
+
#else
|
|
56
|
+
rb_raise(
|
|
57
|
+
rb_eRuntimeError,
|
|
58
|
+
"Torch::DDP._cuda_empty_cache requires CUDA support");
|
|
59
|
+
#endif
|
|
60
|
+
return Rice::Object(Qnil);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
} // namespace
|
|
65
|
+
|
|
66
|
+
void init_cuda_helpers(Rice::Module& m) {
|
|
67
|
+
register_cuda_helpers(m);
|
|
68
|
+
}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
#endif
|
|
18
18
|
|
|
19
19
|
static_assert(
|
|
20
|
-
TORCH_VERSION_MAJOR == 2 && TORCH_VERSION_MINOR ==
|
|
20
|
+
TORCH_VERSION_MAJOR == 2 && TORCH_VERSION_MINOR == 13,
|
|
21
21
|
"Incompatible LibTorch version");
|
|
22
22
|
|
|
23
23
|
#ifdef USE_C10D
|
|
@@ -254,7 +254,7 @@ void init_distributed(Rice::Module& m) {
|
|
|
254
254
|
"_destroy_process_group",
|
|
255
255
|
[]() {
|
|
256
256
|
shutdown_default_process_group();
|
|
257
|
-
return Rice::
|
|
257
|
+
return Rice::Object(Qnil);
|
|
258
258
|
});
|
|
259
259
|
|
|
260
260
|
rb_mDistributed.define_singleton_function(
|
|
@@ -267,7 +267,7 @@ void init_distributed(Rice::Module& m) {
|
|
|
267
267
|
"_default_process_group",
|
|
268
268
|
[rb_cProcessGroup]() -> Rice::Object {
|
|
269
269
|
if (!default_process_group) {
|
|
270
|
-
return Rice::
|
|
270
|
+
return Rice::Object(Qnil);
|
|
271
271
|
}
|
|
272
272
|
return Rice::Data_Object<ProcessGroupWrapper>(new ProcessGroupWrapper(default_process_group), true, rb_cProcessGroup);
|
|
273
273
|
});
|
|
@@ -293,7 +293,7 @@ void init_distributed(Rice::Module& m) {
|
|
|
293
293
|
::c10d::BarrierOptions opts;
|
|
294
294
|
auto work = pg->barrier(opts);
|
|
295
295
|
work->wait();
|
|
296
|
-
return Rice::
|
|
296
|
+
return Rice::Object(Qnil);
|
|
297
297
|
});
|
|
298
298
|
|
|
299
299
|
rb_mDistributed.define_singleton_function(
|
data/ext/torch_ddp/ext.cpp
CHANGED
data/ext/torch_ddp/extconf.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require "mkmf-rice"
|
|
2
2
|
|
|
3
|
-
$CXXFLAGS += " -std=c++
|
|
3
|
+
$CXXFLAGS += " -std=c++20 $(optflags)"
|
|
4
4
|
|
|
5
5
|
# change to 0 for Linux pre-cxx11 ABI version
|
|
6
6
|
$CXXFLAGS += " -D_GLIBCXX_USE_CXX11_ABI=1"
|
|
@@ -38,7 +38,6 @@ cuda_inc ||= "/usr/include"
|
|
|
38
38
|
|
|
39
39
|
cudnn_inc, cudnn_lib = dir_config("cudnn")
|
|
40
40
|
cudnn_lib ||= "/usr/local/cuda/lib"
|
|
41
|
-
abort "cuda.h not found" unless find_header("cuda.h")
|
|
42
41
|
|
|
43
42
|
gloo_inc, _ = dir_config("gloo")
|
|
44
43
|
gloo_inc ||= "./vendor/gloo"
|
|
@@ -56,12 +55,25 @@ if Dir["#{lib}/*torch_cuda*"].any?
|
|
|
56
55
|
$LDFLAGS += " -L#{cudnn_lib}" if Dir.exist?(cudnn_lib) && cudnn_lib != cuda_lib
|
|
57
56
|
with_cuda = have_library("cuda") && have_library("cudnn")
|
|
58
57
|
end
|
|
58
|
+
abort "cuda.h not found" if with_cuda && !find_header("cuda.h")
|
|
59
|
+
$defs << "-DWITH_CUDA" if with_cuda
|
|
59
60
|
|
|
60
61
|
$INCFLAGS += " -I#{inc}"
|
|
61
62
|
$INCFLAGS += " -I#{inc}/torch/csrc/api/include"
|
|
62
63
|
|
|
63
64
|
CONFIG["CC"] = CONFIG["CXX"]
|
|
65
|
+
CONFIG["CXXFLAGS"] = $CXXFLAGS
|
|
66
|
+
RbConfig::CONFIG["CXXFLAGS"] = $CXXFLAGS
|
|
64
67
|
$CFLAGS = $CXXFLAGS
|
|
68
|
+
$CFLAGS += " -std=c++20"
|
|
69
|
+
|
|
70
|
+
def try_link_with_cppflags(source, flags)
|
|
71
|
+
original_cppflags = $CPPFLAGS
|
|
72
|
+
$CPPFLAGS = [original_cppflags, flags].compact.join(" ")
|
|
73
|
+
try_link(source)
|
|
74
|
+
ensure
|
|
75
|
+
$CPPFLAGS = original_cppflags
|
|
76
|
+
end
|
|
65
77
|
|
|
66
78
|
$LDFLAGS += " -Wl,-rpath,#{lib}"
|
|
67
79
|
if RbConfig::CONFIG["host_os"] =~ /darwin/i && RbConfig::CONFIG["host_cpu"] =~ /arm|aarch64/i && Dir.exist?("/opt/homebrew/opt/libomp/lib")
|
|
@@ -69,7 +81,7 @@ if RbConfig::CONFIG["host_os"] =~ /darwin/i && RbConfig::CONFIG["host_cpu"] =~ /
|
|
|
69
81
|
end
|
|
70
82
|
$LDFLAGS += ":#{cuda_lib}/stubs:#{cuda_lib}" if with_cuda
|
|
71
83
|
|
|
72
|
-
# https://github.com/pytorch/pytorch/blob/v2.
|
|
84
|
+
# https://github.com/pytorch/pytorch/blob/v2.13.0/torch/utils/cpp_extension.py#L1351-L1364
|
|
73
85
|
$LDFLAGS += " -lc10 -ltorch_cpu -ltorch"
|
|
74
86
|
if with_cuda
|
|
75
87
|
$LDFLAGS += " -lcuda -lnvrtc"
|
|
@@ -79,7 +91,10 @@ if with_cuda
|
|
|
79
91
|
$LDFLAGS += " -Wl,--no-as-needed,#{lib}/libtorch.so"
|
|
80
92
|
end
|
|
81
93
|
|
|
82
|
-
supports_c10d =
|
|
94
|
+
supports_c10d = try_link_with_cppflags(<<~CPP, "-DUSE_C10D")
|
|
95
|
+
// Ruby's headers define `_` as a compatibility macro, which collides with
|
|
96
|
+
// LibTorch 2.13's TensorAccessor headers.
|
|
97
|
+
#undef _
|
|
83
98
|
#include <torch/torch.h>
|
|
84
99
|
#include <torch/csrc/distributed/c10d/FileStore.hpp>
|
|
85
100
|
|
|
@@ -102,7 +117,8 @@ else
|
|
|
102
117
|
puts "Building without distributed support"
|
|
103
118
|
end
|
|
104
119
|
|
|
105
|
-
supports_c10d_gloo = supports_c10d &&
|
|
120
|
+
supports_c10d_gloo = supports_c10d && try_link_with_cppflags(<<~CPP, "-DUSE_C10D -DUSE_C10D_GLOO")
|
|
121
|
+
#undef _
|
|
106
122
|
#include <torch/torch.h>
|
|
107
123
|
#include <torch/csrc/distributed/c10d/ProcessGroupGloo.hpp>
|
|
108
124
|
#include <torch/csrc/distributed/c10d/FileStore.hpp>
|
|
@@ -116,7 +132,8 @@ supports_c10d_gloo = supports_c10d && try_link(<<~CPP, "-DUSE_C10D -DUSE_C10D_GL
|
|
|
116
132
|
}
|
|
117
133
|
CPP
|
|
118
134
|
|
|
119
|
-
supports_c10d_nccl = with_cuda &&
|
|
135
|
+
supports_c10d_nccl = with_cuda && try_link_with_cppflags(<<~CPP, "-DUSE_C10D -DUSE_C10D_NCCL")
|
|
136
|
+
#undef _
|
|
120
137
|
#include <torch/torch.h>
|
|
121
138
|
#include <torch/csrc/distributed/c10d/ProcessGroupNCCL.hpp>
|
|
122
139
|
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require "fiddle"
|
|
2
|
-
|
|
3
1
|
module Torch
|
|
4
2
|
module DDP
|
|
5
3
|
module MonkeyPatch
|
|
@@ -14,7 +12,8 @@ module Torch
|
|
|
14
12
|
|
|
15
13
|
warn("#{WARNING_PREFIX} Applying torch compatibility patch for: #{missing.join(', ')}. Please upgrade the torch gem for native support.")
|
|
16
14
|
patch_cuda_set_device if missing.include?(:cuda_set_device)
|
|
17
|
-
|
|
15
|
+
patch_cuda_empty_cache if missing.include?(:cuda_empty_cache)
|
|
16
|
+
patch_device_helpers if missing.include?(:device_helpers)
|
|
18
17
|
patch_load if missing.include?(:load_keywords)
|
|
19
18
|
patch_tensor_item if missing.include?(:tensor_item_scalar)
|
|
20
19
|
@applied = true
|
|
@@ -25,11 +24,19 @@ module Torch
|
|
|
25
24
|
def missing_features
|
|
26
25
|
missing = []
|
|
27
26
|
missing << :cuda_set_device unless Torch.const_defined?(:CUDA) && Torch::CUDA.respond_to?(:set_device)
|
|
27
|
+
missing << :cuda_empty_cache unless Torch.const_defined?(:CUDA) && Torch::CUDA.respond_to?(:empty_cache)
|
|
28
|
+
missing << :device_helpers unless native_device_helpers?
|
|
28
29
|
missing << :load_keywords unless load_supports_map_location_and_weights_only?
|
|
29
30
|
missing << :tensor_item_scalar unless tensor_item_returns_scalar?
|
|
30
31
|
missing
|
|
31
32
|
end
|
|
32
33
|
|
|
34
|
+
def native_device_helpers?
|
|
35
|
+
Torch.tensor([0]).device.is_a?(Torch::Device)
|
|
36
|
+
rescue StandardError
|
|
37
|
+
false
|
|
38
|
+
end
|
|
39
|
+
|
|
33
40
|
def load_supports_map_location_and_weights_only?
|
|
34
41
|
params = Torch.method(:load).parameters
|
|
35
42
|
keyword_names = params.select { |kind, _| [:key, :keyreq].include?(kind) }.map(&:last)
|
|
@@ -56,48 +63,33 @@ module Torch
|
|
|
56
63
|
end
|
|
57
64
|
|
|
58
65
|
def cuda_set_device!(device_id)
|
|
59
|
-
|
|
66
|
+
unless Torch.const_defined?(:DDP) && Torch::DDP.respond_to?(:_cuda_set_device)
|
|
67
|
+
raise Torch::Error, "Torch::CUDA.set_device is unavailable; ensure torch is built with CUDA or upgrade torch."
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
Torch::DDP._cuda_set_device(Integer(device_id))
|
|
60
71
|
end
|
|
61
72
|
public :cuda_set_device!
|
|
62
73
|
|
|
63
|
-
def
|
|
64
|
-
|
|
65
|
-
candidates = [
|
|
66
|
-
ENV["LIBCUDART_PATH"],
|
|
67
|
-
"/usr/local/cuda/lib64/libcudart.so",
|
|
68
|
-
"/usr/local/cuda/lib/libcudart.so",
|
|
69
|
-
"/usr/local/cuda/lib/libcudart.dylib",
|
|
70
|
-
"libcudart.so.12",
|
|
71
|
-
"libcudart.so.11",
|
|
72
|
-
"libcudart.so",
|
|
73
|
-
"libcudart.dylib"
|
|
74
|
-
].compact
|
|
75
|
-
|
|
76
|
-
function = nil
|
|
77
|
-
candidates.each do |path|
|
|
78
|
-
begin
|
|
79
|
-
handle = Fiddle.dlopen(path)
|
|
80
|
-
function = Fiddle::Function.new(handle["cudaSetDevice"], [Fiddle::TYPE_INT], Fiddle::TYPE_INT)
|
|
81
|
-
break
|
|
82
|
-
rescue Fiddle::DLError
|
|
83
|
-
next
|
|
84
|
-
end
|
|
85
|
-
end
|
|
74
|
+
def patch_cuda_empty_cache
|
|
75
|
+
return unless Torch.const_defined?(:CUDA)
|
|
86
76
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
raise Torch::Error, "cudaSetDevice(#{device_id}) failed with code #{result}" unless result.zero?
|
|
91
|
-
nil
|
|
92
|
-
end
|
|
93
|
-
else
|
|
94
|
-
->(device_id) do
|
|
95
|
-
raise Torch::Error, "Torch::CUDA.set_device is unavailable; ensure torch is built with CUDA or upgrade torch."
|
|
96
|
-
end
|
|
77
|
+
Torch::CUDA.singleton_class.class_eval do
|
|
78
|
+
define_method(:empty_cache) do
|
|
79
|
+
Torch::DDP::MonkeyPatch.cuda_empty_cache!
|
|
97
80
|
end
|
|
98
81
|
end
|
|
99
82
|
end
|
|
100
83
|
|
|
84
|
+
def cuda_empty_cache!
|
|
85
|
+
unless Torch.const_defined?(:DDP) && Torch::DDP.respond_to?(:_cuda_empty_cache)
|
|
86
|
+
raise Torch::Error, "Torch::CUDA.empty_cache is unavailable; ensure torch is built with CUDA or upgrade torch."
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
Torch::DDP._cuda_empty_cache
|
|
90
|
+
end
|
|
91
|
+
public :cuda_empty_cache!
|
|
92
|
+
|
|
101
93
|
def patch_device_helpers
|
|
102
94
|
Torch::Device.class_eval do
|
|
103
95
|
alias_method :_torch_ddp_original_to_s, :to_s unless method_defined?(:_torch_ddp_original_to_s)
|
data/lib/torch/ddp/version.rb
CHANGED
|
Binary file
|
data/lib/torch/distributed.rb
CHANGED
|
@@ -264,17 +264,17 @@ module Torch
|
|
|
264
264
|
when Torch::Device
|
|
265
265
|
device.type
|
|
266
266
|
when NilClass
|
|
267
|
-
|
|
267
|
+
device_type_fallback || "cpu"
|
|
268
268
|
when String
|
|
269
269
|
Torch.device(device).type
|
|
270
270
|
when Integer
|
|
271
|
-
return
|
|
271
|
+
return device_type_fallback || "cpu" if device.negative?
|
|
272
272
|
if Torch.const_defined?(:CUDA) && Torch::CUDA.respond_to?(:device_count)
|
|
273
273
|
max = Torch::CUDA.device_count
|
|
274
|
-
return
|
|
274
|
+
return device_type_fallback || "cpu" if max <= 0 || device >= max
|
|
275
275
|
return Torch.device("cuda:#{device}").type
|
|
276
276
|
end
|
|
277
|
-
|
|
277
|
+
device_type_fallback || "cpu"
|
|
278
278
|
else
|
|
279
279
|
return device.type if device.respond_to?(:type)
|
|
280
280
|
Torch.device(device).type
|
|
@@ -283,9 +283,17 @@ module Torch
|
|
|
283
283
|
raise ArgumentError, "Invalid device #{device.inspect}: #{e.message}"
|
|
284
284
|
end
|
|
285
285
|
|
|
286
|
-
def
|
|
287
|
-
|
|
288
|
-
|
|
286
|
+
def device_type_fallback
|
|
287
|
+
if Torch.const_defined?(:CUDA) && Torch::CUDA.respond_to?(:available?) && Torch::CUDA.available?
|
|
288
|
+
return "cuda"
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
if Torch.const_defined?(:Backends) && Torch::Backends.const_defined?(:MPS) &&
|
|
292
|
+
Torch::Backends::MPS.respond_to?(:available?) && Torch::Backends::MPS.available?
|
|
293
|
+
return "mps"
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
"cpu"
|
|
289
297
|
rescue
|
|
290
298
|
nil
|
|
291
299
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: torch-ddp
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ivan Razuvaev
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: torch-rb
|
|
@@ -16,29 +15,28 @@ dependencies:
|
|
|
16
15
|
requirements:
|
|
17
16
|
- - ">="
|
|
18
17
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: 0.
|
|
18
|
+
version: 0.25.0
|
|
20
19
|
type: :runtime
|
|
21
20
|
prerelease: false
|
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
22
|
requirements:
|
|
24
23
|
- - ">="
|
|
25
24
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: 0.
|
|
25
|
+
version: 0.25.0
|
|
27
26
|
- !ruby/object:Gem::Dependency
|
|
28
27
|
name: rice
|
|
29
28
|
requirement: !ruby/object:Gem::Requirement
|
|
30
29
|
requirements:
|
|
31
30
|
- - ">="
|
|
32
31
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '4.
|
|
32
|
+
version: '4.8'
|
|
34
33
|
type: :runtime
|
|
35
34
|
prerelease: false
|
|
36
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
36
|
requirements:
|
|
38
37
|
- - ">="
|
|
39
38
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '4.
|
|
41
|
-
description:
|
|
39
|
+
version: '4.8'
|
|
42
40
|
email: i@orlando-labs.com
|
|
43
41
|
executables:
|
|
44
42
|
- torchrun
|
|
@@ -51,12 +49,14 @@ files:
|
|
|
51
49
|
- bin/torchrun
|
|
52
50
|
- examples/benchmark/training.rb
|
|
53
51
|
- examples/mnist/distributed.rb
|
|
52
|
+
- ext/torch_ddp/cuda.cpp
|
|
54
53
|
- ext/torch_ddp/distributed.cpp
|
|
55
54
|
- ext/torch_ddp/ext.cpp
|
|
56
55
|
- ext/torch_ddp/extconf.rb
|
|
57
56
|
- lib/torch-ddp.rb
|
|
58
57
|
- lib/torch/ddp/monkey_patch.rb
|
|
59
58
|
- lib/torch/ddp/version.rb
|
|
59
|
+
- lib/torch/ddp_ext.so
|
|
60
60
|
- lib/torch/distributed.rb
|
|
61
61
|
- lib/torch/nn/parallel/distributed_data_parallel.rb
|
|
62
62
|
- lib/torch/torchrun.rb
|
|
@@ -70,7 +70,6 @@ homepage: https://github.com/ankane/torch.rb
|
|
|
70
70
|
licenses:
|
|
71
71
|
- BSD-3-Clause
|
|
72
72
|
metadata: {}
|
|
73
|
-
post_install_message:
|
|
74
73
|
rdoc_options: []
|
|
75
74
|
require_paths:
|
|
76
75
|
- lib
|
|
@@ -78,15 +77,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
78
77
|
requirements:
|
|
79
78
|
- - ">="
|
|
80
79
|
- !ruby/object:Gem::Version
|
|
81
|
-
version: '3.
|
|
80
|
+
version: '3.3'
|
|
82
81
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
83
82
|
requirements:
|
|
84
83
|
- - ">="
|
|
85
84
|
- !ruby/object:Gem::Version
|
|
86
85
|
version: '0'
|
|
87
86
|
requirements: []
|
|
88
|
-
rubygems_version:
|
|
89
|
-
signing_key:
|
|
87
|
+
rubygems_version: 4.0.1
|
|
90
88
|
specification_version: 4
|
|
91
89
|
summary: Distributed data parallel support for torch-rb
|
|
92
90
|
test_files: []
|