-
Notifications
You must be signed in to change notification settings - Fork 25.6k
Fix torch.normal ignores default_device #144070
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/144070
Note: Links to docs will display an error until the docs builds have been completed. ❗ 1 Active SEVsThere are 1 currently active SEVs. If your PR is affected, please view them below: ✅ No FailuresAs of commit 7fcad7e with merge base e141cb9 ( This comment was automatically generated by Dr. CI and updates every 15 minutes. |
@pytorchbot label "topic: not user facing" |
b74bac0
to
dea591d
Compare
torch.logspace, | ||
torch.nested.nested_tensor, | ||
# This function doesn't actually take a device argument | ||
# torch.normal, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ezyang Hello, need help reviewing restriction in here, seems it works now, any other need to be aware? Thanks!
Seems normal
has device
argument now
pytorch/aten/src/ATen/native/TensorFactories.cpp
Lines 1278 to 1294 in 00df63f
Tensor normal( | |
double mean, | |
double std, | |
IntArrayRef size, | |
std::optional<Generator> generator, | |
std::optional<ScalarType> dtype, | |
std::optional<Layout> layout, | |
std::optional<Device> device, | |
std::optional<bool> pin_memory) { | |
// See [Note: hacky wrapper removal for TensorOptions] | |
TensorOptions options = | |
TensorOptions().dtype(dtype).layout(layout).device(device).pinned_memory( | |
pin_memory); | |
auto result = at::empty(size, options); | |
return result.normal_(mean, std, std::move(generator)); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure how useful this is but the following refs to normal don't include a device:
pytorch/torch/csrc/utils/schema_info.cpp
Lines 234 to 268 in 6e77d7c
std::vector<c10::FunctionSchema> SchemaInfo::getNonDeterministicOps() { | |
// This list of nondeterministic ops is copied from JIT ir.cpp. | |
static const std::vector<std::string> nondeterministic_op_strings = { | |
"aten::dropout(Tensor input, float p, bool train) -> Tensor", | |
"aten::_fused_dropout(Tensor self, float p, Generator? generator) -> (Tensor, Tensor)", | |
"aten::_standard_gamma(Tensor self, Generator? generator) -> Tensor", | |
"aten::bernoulli(Tensor self, *, Generator? generator) -> Tensor", | |
"aten::bernoulli(Tensor self, float p, *, Generator? generator) -> Tensor", | |
"aten::multinomial(Tensor self, int num_samples, bool replacement, *, Generator? generator) -> Tensor", | |
"aten::native_dropout(Tensor input, float p, bool? train) -> (Tensor, Tensor)", | |
"aten::normal(Tensor mean, Tensor std, *, Generator? generator) -> Tensor", | |
"aten::normal(float mean, Tensor std, *, Generator? generator) -> Tensor", | |
"aten::normal(Tensor mean, float std, *, Generator? generator) -> Tensor", | |
"aten::poisson(Tensor self, Generator? generator) -> Tensor", | |
"aten::binomial(Tensor count, Tensor prob, Generator? generator=None) -> Tensor", | |
"aten::rrelu(Tensor self, Scalar lower, Scalar upper, bool training, Generator? generator) -> Tensor", | |
"aten::rrelu_with_noise(Tensor self, Tensor noise, Scalar lower, Scalar upper, bool training, Generator? generator) -> Tensor", | |
"aten::rand(int[] size, *, int? dtype, int? layout, Device? device, bool? pin_memory) -> Tensor", | |
"aten::rand_like(Tensor self, *, int? dtype=None, int? layout=None, Device? device=None, bool? pin_memory=None, MemoryFormat? memory_format=None) -> Tensor", | |
"aten::randint(int high, int[] size, *, int? dtype, int? layout, Device? device, bool? pin_memory) -> Tensor", | |
"aten::randint(int low, int high, int[] size, *, int? dtype, int? layout, Device? device, bool? pin_memory) -> Tensor", | |
"aten::randint_like(Tensor self, int high, *, int? dtype=None, int? layout=None, Device? device=None, bool? pin_memory=None, MemoryFormat? memory_format=None) -> Tensor", | |
"aten::randint_like(Tensor self, int low, int high, *, int? dtype=None, int? layout=None, Device? device=None, bool? pin_memory=None, MemoryFormat? memory_format=None) -> Tensor", | |
"aten::randn(int[] size, *, int? dtype, int? layout, Device? device, bool? pin_memory) -> Tensor", | |
"aten::randn_like(Tensor self, *, int? dtype=None, int? layout=None, Device? device=None, bool? pin_memory=None, MemoryFormat? memory_format=None) -> Tensor", | |
"aten::randperm(int n, *, int? dtype, int? layout, Device? device, bool? pin_memory) -> Tensor"}; | |
std::vector<c10::FunctionSchema> nondeterministic_ops; | |
nondeterministic_ops.reserve(nondeterministic_op_strings.size()); | |
for (const std::string& signature : nondeterministic_op_strings) { | |
nondeterministic_ops.emplace_back(torch::jit::parseSchema(signature)); | |
} | |
return nondeterministic_ops; | |
} |
pytorch/torch/csrc/jit/passes/shape_analysis.cpp
Lines 862 to 863 in 00df63f
"aten::normal(float mean, Tensor std, *, Generator? generator) -> Tensor", | |
"aten::normal(Tensor mean, float std, *, Generator? generator) -> Tensor", |
pytorch/torch/csrc/jit/passes/shape_analysis.cpp
Line 1109 in 00df63f
"aten::normal(Tensor mean, Tensor std, *, Generator? generator) -> Tensor", |
@pytorchbot merge |
Merge startedYour change will be merged once all checks pass (ETA 0-4 Hours). Learn more about merging in the wiki. Questions? Feedback? Please reach out to the PyTorch DevX Team |
I believe this causes an issue with a cm is used: import torch
with torch.device("cpu"):
torch.normal(torch.zeros(()), torch.ones(())) results in
|
def test_normal_default_device(self, device): | ||
try: | ||
torch.set_default_device(device) | ||
t = torch.normal(0, 1, (10, 10)) | ||
finally: | ||
torch.set_default_device(None) | ||
self.assertEqual(str(t.device), device) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't you set back the previous default device instead?
Like
def test_normal_default_device(self, device): | |
try: | |
torch.set_default_device(device) | |
t = torch.normal(0, 1, (10, 10)) | |
finally: | |
torch.set_default_device(None) | |
self.assertEqual(str(t.device), device) | |
default_device = torch.default_device() | |
try: | |
torch.set_default_device(device) | |
t = torch.normal(0, 1, (10, 10)) | |
finally: | |
torch.set_default_device(default_device) | |
self.assertEqual(str(t.device), device) |
Also, note that this works
torch.normal(0, 1, (10, 10))
but this doesn't
torch.normal(0, 1)
@vmoens Hello, sorry about that, please helping revert this one if needed, and let me check how to fix it. Thanks! |
Maybe @ezyang can advise - IMO if we can get a quick fix and additional tests it's not necessary to revert |
@pytorchbot revert -c nosignal -m "broken a specific use case" |
@pytorchbot successfully started a revert job. Check the current status here. |
@zeshengzong your PR has been successfully reverted. |
This reverts commit 184549b. Reverted #144070 on behalf of https://github.com/ezyang due to broken a specific use case ([comment](#144070 (comment)))
@zeshengzong do you mind reopening a new PR? Thanks |
Sure, thanks for help! |
Fixes #122886
torch.normal
working withDeviceContext
to get default device which set viaset_default_device
.set_default_device
doc, suggest usetorch.Tensor.to
method move to desired device explicitly.Test Result
Doc Preview

Local Test
cc @fritzo @neerajprad @alicanb @nikitaved