pytorch/torch
Mike Ruberry e66445878d Adds dynamic versioning pattern (#40279)
Summary:
BC NOTE:

This change makes it so modules saved with torch.jit.save in PyTorch 1.6 can be loaded by previous versions of PyTorch unless they use torch.div or (soon) torch.full. It also lets tensors saved using torch.save be loaded by previous versions. So this is the opposite of BC-breaking, but I'm using that label to highlight this issue since we don't have a "BC-improving" label.

PR NOTE:
When an operator's semantics change in PyTorch we want to do two things:

1) Preserve the semantics of older serialized Torchscript programs that use the operator
2) Ensure the new semantics are respected

Historically, this meant writing a Versioned Symbol that would remap older versions of the operator into current PyTorch code (1), and bumping the produced file format version (2). Unfortunately, bumping the produced file format version is a nuclear option for ensuring semantics are respected, since it also prevents older versions of PyTorch from loading anything (even tensors!) from newer versions.

Dynamic versioning addresses the nuclear consequences of bumping the produced file format version by only bumping it when necessary. That is, when an operator with changed semantics is detected in the serialized Torchscript. This will prevent Torchscript programs that use the changed operator from loading on earlier versions of PyTorch, as desired, but will have no impact on programs that don't use the changed operator.

Note that this change is only applicable when using torch.jit.save and torch.jit.load. torch.save pickles the given object using pickle (by default), which saves a function's Python directly.

No new tests for this behavior are added since the existing tests for versioned division in test_save_load already validate that models with div are loaded correctly at version 4.
Pull Request resolved: https://github.com/pytorch/pytorch/pull/40279

Reviewed By: dzhulgakov

Differential Revision: D22168291

Pulled By: mruberry

fbshipit-source-id: e71d6380e727e25123c7eedf6d80e5d7f1fe9f95
2020-06-24 12:52:50 -07:00
..
_C Add typing for _CudaStreamBase and _CudaEventBase classes (#40256) 2020-06-19 11:29:41 -07:00
autograd Increase shapes column length (#40440) 2020-06-23 10:49:01 -07:00
backends
contrib
csrc Adds dynamic versioning pattern (#40279) 2020-06-24 12:52:50 -07:00
cuda Allow torch.cuda.amp.GradScaler to support sparse gradients (#36786) 2020-06-24 09:10:49 -07:00
distributed [JIT x RPC] Consolidate Future type class and Future impl class (#40406) 2020-06-24 01:44:49 -07:00
distributions fix typo "normal" -> "Cauchy" (#40334) 2020-06-24 07:45:35 -07:00
for_onnx
futures [JIT x RPC] Consolidate Future type class and Future impl class (#40406) 2020-06-24 01:44:49 -07:00
jit Adds dynamic versioning pattern (#40279) 2020-06-24 12:52:50 -07:00
legacy
lib [RELAND2] Change AccumulateGrad to yield .grads that match weights' memory layout (#40358) 2020-06-22 17:13:21 -07:00
multiprocessing
nn [doc] fix typo in formula of MarginRankingLoss (#40285) 2020-06-24 07:24:51 -07:00
onnx Fix typo. in error message (#39958) 2020-06-24 07:17:10 -07:00
optim Fix typo in warning message (#39854) 2020-06-23 16:47:35 -07:00
quantization Remove print (#40475) 2020-06-24 00:42:25 -07:00
sparse
testing [JIT x RPC] Consolidate Future type class and Future impl class (#40406) 2020-06-24 01:44:49 -07:00
utils Revert D22102408: DNNL: enable conv3d 2020-06-22 15:41:51 -07:00
__config__.py
__future__.py
__init__.py Initial vmap frontend API (#40172) 2020-06-24 08:14:24 -07:00
_appdirs.py Delete Python <= 3.5 specific checks from the code (#39879) 2020-06-15 08:16:06 -07:00
_classes.py
_jit_internal.py [JIT x RPC] Consolidate Future type class and Future impl class (#40406) 2020-06-24 01:44:49 -07:00
_linalg_utils.py
_lobpcg.py
_lowrank.py
_namedtensor_internals.py
_ops.py
_overrides.py Revert D22102406: DNNL: enable max_pool3d and avg_pool3d 2020-06-22 15:23:01 -07:00
_six.py Delete Python <= 3.5 specific checks from the code (#39879) 2020-06-15 08:16:06 -07:00
_storage_docs.py
_tensor_docs.py Meta tensors, but without code deduplication (#38490) 2020-06-22 09:18:33 -07:00
_tensor_str.py Meta tensors, but without code deduplication (#38490) 2020-06-22 09:18:33 -07:00
_torch_docs.py Throws runtime error when torch.full would infer a float dtype from a bool or integral fill value (#40364) 2020-06-23 23:27:22 -07:00
_utils.py
_utils_internal.py
_VF.py
_vmap_internals.py Initial vmap frontend API (#40172) 2020-06-24 08:14:24 -07:00
abi-check.cpp
CMakeLists.txt
custom_class.h
custom_class_detail.h
extension.h
functional.py
hub.py
library.h Assert that kernels are called with the right signature (#40251) 2020-06-18 21:54:05 -07:00
py.typed
quasirandom.py
random.py
README.txt
script.h
serialization.py Adds dynamic versioning pattern (#40279) 2020-06-24 12:52:50 -07:00
storage.py
tensor.py [RELAND2] Change AccumulateGrad to yield .grads that match weights' memory layout (#40358) 2020-06-22 17:13:21 -07:00
types.py

Note [TH abstraction violation]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

TH/THC provide some hpp headers, which are proper C++ headers rather than
C headers.  These headers serve double duty as *internal implementation
detail* headers, whose contents should largely not be used by external
clients.

Ideally, we would not install these headers at all; instead, you should
use public functions (in headers like `THTensor.h`, NOT `THTensor.hpp`)
to manipulate these structs.  However, there are a few places
in torch/csrc where we violate this abstraction.  They are marked with
a pointer to this note.  Each of those sites will have to be refactored
when we refactor the guts of THTensor and related structures.