Skip to content

Conversation

@yf225
Copy link
Contributor

@yf225 yf225 commented Nov 12, 2019

Stack from ghstack:

This PR is BC-breaking in the following way:

Previously, C++ torch::tensor with an integer type (e.g. torch::tensor(1)) or a (nested) braced-init-list of integer types (e.g. torch::tensor({{1, 2}})) produces a tensor with the same dtype. Now it always produces a tensor of dtype torch::kLong (aka. int64_t). matching Python torch.tensor behavior.

Differential Revision: D18465819

…:tensor(empty braced-init-list) when dtype is not specified
@yf225 yf225 mentioned this pull request Nov 12, 2019
@kostmo
Copy link
Member

kostmo commented Nov 12, 2019

CircleCI build failures summary

As of commit 16137e2:

  • 1/1 failures introduced in this PR
  • 0/1 recognized as flaky

Here are the reasons each build failed:

Job Step Log excerpt
pytorch_xla_linux_xenial_py3_6_clang7_build Build Failed to run '['/var/lib/jenkins/workspace/xla/scripts/generate_code.sh']'

This comment was automatically generated by Dr. CI.
Follow this link to opt-out of these comments for your Pull Requests.

Please report bugs/suggestions on the GitHub issue tracker.

This comment has been revised 30 time(s).

Will Feng added 2 commits November 12, 2019 00:44
… and torch::tensor(empty braced-init-list) when dtype is not specified"

Use default dtype for torch::tensor(floating_point_values) and torch::tensor(empty braced-init-list) when dtype is not specified

gh-metadata: pytorch pytorch 29632 gh/yf225/66/head
… and torch::tensor(empty braced-init-list) when dtype is not specified"

Use default dtype for torch::tensor(floating_point_values) and torch::tensor(empty braced-init-list) when dtype is not specified

gh-metadata: pytorch pytorch 29632 gh/yf225/66/head
@yf225 yf225 added module: bc-breaking Related to a BC-breaking change module: cpp Related to C++ API labels Nov 12, 2019
@yf225 yf225 requested review from zou3519 and removed request for ebetica and goldsborough November 12, 2019 06:13
return count;
}

// A RAII, thread local (!) guard that changes default dtype upon
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just checking, torch::set_default_dtype changes the default dtype locally?

Copy link
Contributor

@zou3519 zou3519 Nov 12, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems global: https://github.com/pytorch/pytorch/blob/master/c10/core/DefaultDtype.cpp. Orthogonal to this PR, does this need synchronization?

EDIT: Do people design global guards like this in general? I'm only really familiar with pytorch's use of thread-local guards.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh sorry, I totally did not realize this was in test code. This is fine in testing code, I was wondering if it was OK as an API.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the catch - I think this AutoDefaultDtypeMode guard in its original form was not safe to use if we ever run C++ tests in parallel in multiple threads, since a test in thread A might not have finished when another test in thread B changes the default dtype using torch::set_default_dtype. To address this problem, I made the following two changes:

  1. Add static std::mutex default_dtype_mutex to AutoDefaultDtypeMode, so that usage of AutoDefaultDtypeMode is synchronized and thus always thread-safe.
  2. Change other C++ tests that have set_default_dtype(...) to always use AutoDefaultDtypeMode to guard the whole scope of the test, so that access to set_default_dtype(...) is effectively synchronized within the C++ test suite. (It won't protect us against running a C++ test while changing default dtype through Python within the same process, but such usage seems more intentional than accidental, and the author of that test mechanism should be responsible for making sure such usage is sane.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the AutoDefaultDtypeMode guard is pretty ad-hoc - for now it's only used for the C++ tests, and its RAII mechanism should work :D

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does gtest run tests in parallel / is it able to?

Copy link
Contributor Author

@yf225 yf225 Nov 13, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on the design of the tests (they only run single-threaded), it might be better to simplify the data structure by removing the mutex and writing a quick comment that this isn't thread-safe and that it doesn't matter because we only use one thread

@zou3519
Copy link
Contributor

zou3519 commented Nov 12, 2019

Does it make sense to use the default dtype when the user does torch.tensor(1.0)? 1.0 is "always" a double when it's used in C++

@zou3519
Copy link
Contributor

zou3519 commented Nov 12, 2019

Does it make sense to use the default dtype when the user does torch.tensor(1.0)? 1.0 is "always" a double when it's used in C++

On second thought, python floats also have double-precision and we use the default dtype for them.

// When `scalar_type == at::kDouble`, we know that the user is passing in
// a floating-point literal without specifying its type (e.g. `1.0` instead of `1.0f`).
// In Python, the dtype of `torch.tensor(1.0)` depends on the value of
// `torch.get_default_dtype()`, and we should do the same for C++ `torch::tensor(1.0)`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be nice to have a parity test for this behavior. i.e., if we ever change the default tensor type behavior then we know to change it in both APIs. I don't see this changing anytime soon though so this is more of a nit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed - I will add it in a follow-up PR to improve the parity test mechanism.

Will Feng added 6 commits November 12, 2019 17:46
… and torch::tensor(empty braced-init-list) when dtype is not specified"

Use default dtype for torch::tensor(floating_point_values) and torch::tensor(empty braced-init-list) when dtype is not specified

gh-metadata: pytorch pytorch 29632 gh/yf225/66/head
… and torch::tensor(empty braced-init-list) when dtype is not specified"

Use default dtype for torch::tensor(floating_point_values) and torch::tensor(empty braced-init-list) when dtype is not specified

gh-metadata: pytorch pytorch 29632 gh/yf225/66/head
… and torch::tensor(empty braced-init-list) when dtype is not specified"

Use default dtype for torch::tensor(floating_point_values) and torch::tensor(empty braced-init-list) when dtype is not specified

gh-metadata: pytorch pytorch 29632 gh/yf225/66/head
… and torch::tensor(empty braced-init-list) when dtype is not specified"

Use default dtype for torch::tensor(floating_point_values) and torch::tensor(empty braced-init-list) when dtype is not specified

gh-metadata: pytorch pytorch 29632 gh/yf225/66/head
… and torch::tensor(empty braced-init-list) when dtype is not specified"

Use default dtype for torch::tensor(floating_point_values) and torch::tensor(empty braced-init-list) when dtype is not specified

gh-metadata: pytorch pytorch 29632 gh/yf225/66/head
… and torch::tensor(empty braced-init-list) when dtype is not specified"

Use default dtype for torch::tensor(floating_point_values) and torch::tensor(empty braced-init-list) when dtype is not specified

gh-metadata: pytorch pytorch 29632 gh/yf225/66/head
Will Feng added 2 commits November 12, 2019 23:30
… and torch::tensor(empty braced-init-list) when dtype is not specified"

Use default dtype for torch::tensor(floating_point_values) and torch::tensor(empty braced-init-list) when dtype is not specified

gh-metadata: pytorch pytorch 29632 gh/yf225/66/head
… and torch::tensor(empty braced-init-list) when dtype is not specified"

Use default dtype for torch::tensor(floating_point_values) and torch::tensor(empty braced-init-list) when dtype is not specified

gh-metadata: pytorch pytorch 29632 gh/yf225/66/head
Copy link
Contributor

@zou3519 zou3519 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. I think it would be nice to remove the mutex to simplify the logic (since our tests are single-threaded anyways and probably won't change anytime soon) but let me know your thoughts

return count;
}

// A RAII, thread local (!) guard that changes default dtype upon
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on the design of the tests (they only run single-threaded), it might be better to simplify the data structure by removing the mutex and writing a quick comment that this isn't thread-safe and that it doesn't matter because we only use one thread

@yf225
Copy link
Contributor Author

yf225 commented Nov 13, 2019

Looks good. I think it would be nice to remove the mutex to simplify the logic (since our tests are single-threaded anyways and probably won't change anytime soon) but let me know your thoughts

Thanks! I feel that it's probably worth keeping the mutex because changing the global state back and forth in the tests does seems a bit worrying to me, and it might cause hard-to-debug flaky tests if we ever run them in parallel without the mutex.

@zou3519
Copy link
Contributor

zou3519 commented Nov 13, 2019

Looks good. I think it would be nice to remove the mutex to simplify the logic (since our tests are single-threaded anyways and probably won't change anytime soon) but let me know your thoughts

Thanks! I feel that it's probably worth keeping the mutex because changing the global state back and forth in the tests does seems a bit worrying to me, and it might cause hard-to-debug flaky tests if we ever run them in parallel without the mutex.

That's reasonable, let's keep it then.

@facebook-github-bot
Copy link
Contributor

@yf225 merged this pull request in 2bcac59.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Merged module: bc-breaking Related to a BC-breaking change module: cpp Related to C++ API

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants