xref: /aosp_15_r20/external/pytorch/test/test_serialization.py (revision da0073e96a02ea20f0ac840b70461e3646d07c45)
1# Owner(s): ["module: serialization"]
2
3import torch
4import unittest
5import io
6import tempfile
7import os
8import gc
9import sys
10import zipfile
11import warnings
12import gzip
13import copy
14import pickle
15import shutil
16import pathlib
17import platform
18from collections import namedtuple, OrderedDict
19from copy import deepcopy
20from itertools import product
21
22from torch._utils_internal import get_file_path_2
23from torch._utils import _rebuild_tensor
24from torch.utils._import_utils import import_dill
25from torch.serialization import check_module_version_greater_or_equal, get_default_load_endianness, \
26    set_default_load_endianness, LoadEndianness, SourceChangeWarning
27
28from torch.testing._internal.common_utils import (
29    IS_FILESYSTEM_UTF8_ENCODING, TemporaryDirectoryName,
30    TestCase, IS_FBCODE, IS_WINDOWS, TEST_DILL, run_tests, download_file, BytesIOContext, TemporaryFileName,
31    parametrize, instantiate_parametrized_tests, AlwaysWarnTypedStorageRemoval, serialTest, skipIfTorchDynamo)
32from torch.testing._internal.common_device_type import instantiate_device_type_tests
33from torch.testing._internal.common_dtype import all_types_and_complex_and
34from torch.testing._internal.two_tensor import TwoTensor  # noqa: F401
35
36if not IS_WINDOWS:
37    from mmap import MAP_SHARED, MAP_PRIVATE
38else:
39    MAP_SHARED, MAP_PRIVATE = None, None
40
41# These tests were all copied from `test/test_torch.py` at some point, so see
42# the actual blame, see this revision
43# https://github.com/pytorch/pytorch/blame/9a2691f2fc948b9792686085b493c61793c2de30/test/test_torch.py
44
45dill = import_dill()
46HAS_DILL_AT_LEAST_0_3_1 = dill is not None and check_module_version_greater_or_equal(dill, (0, 3, 1))
47
48can_retrieve_source = True
49with warnings.catch_warnings(record=True) as warns:
50    with tempfile.NamedTemporaryFile() as checkpoint:
51        x = torch.save(torch.nn.Module(), checkpoint)
52        for warn in warns:
53            if "Couldn't retrieve source code" in warn.message.args[0]:
54                can_retrieve_source = False
55                break
56
57
58class FilelikeMock:
59    def __init__(self, data, has_fileno=True, has_readinto=False):
60        if has_readinto:
61            self.readinto = self.readinto_opt
62        if has_fileno:
63            # Python 2's StringIO.StringIO has no fileno attribute.
64            # This is used to test that.
65            self.fileno = self.fileno_opt
66
67        self.calls = set()
68        self.bytesio = io.BytesIO(data)
69
70        def trace(fn, name):
71            def result(*args, **kwargs):
72                self.calls.add(name)
73                return fn(*args, **kwargs)
74            return result
75
76        for attr in ['read', 'readline', 'seek', 'tell', 'write', 'flush']:
77            traced_fn = trace(getattr(self.bytesio, attr), attr)
78            setattr(self, attr, traced_fn)
79
80    def fileno_opt(self):
81        raise io.UnsupportedOperation('Not a real file')
82
83    def readinto_opt(self, view):
84        self.calls.add('readinto')
85        return self.bytesio.readinto(view)
86
87    def was_called(self, name):
88        return name in self.calls
89
90
91class SerializationMixin:
92    def _test_serialization_data(self):
93        a = [torch.randn(5, 5).float() for i in range(2)]
94        b = [a[i % 2] for i in range(4)]  # 0-3
95        b += [a[0].storage()]  # 4
96        b += [a[0].reshape(-1)[1:4].storage()]  # 5
97        b += [torch.arange(1, 11).int()]  # 6
98        t1 = torch.FloatTensor().set_(a[0].reshape(-1)[1:4].clone().storage(), 0, (3,), (1,))
99        t2 = torch.FloatTensor().set_(a[0].reshape(-1)[1:4].clone().storage(), 0, (3,), (1,))
100        b += [(t1.storage(), t1.storage(), t2.storage())]  # 7
101        b += [a[0].reshape(-1)[0:2].storage()]  # 8
102        return b
103
104    def _test_serialization_assert(self, b, c):
105        self.assertEqual(b, c, atol=0, rtol=0)
106        self.assertTrue(isinstance(c[0], torch.FloatTensor))
107        self.assertTrue(isinstance(c[1], torch.FloatTensor))
108        self.assertTrue(isinstance(c[2], torch.FloatTensor))
109        self.assertTrue(isinstance(c[3], torch.FloatTensor))
110        self.assertTrue(isinstance(c[4], torch.storage.TypedStorage))
111        self.assertEqual(c[4].dtype, torch.float)
112        c[0].fill_(10)
113        self.assertEqual(c[0], c[2], atol=0, rtol=0)
114        self.assertEqual(c[4], torch.FloatStorage(25).fill_(10), atol=0, rtol=0)
115        c[1].fill_(20)
116        self.assertEqual(c[1], c[3], atol=0, rtol=0)
117        # I have to do it in this roundabout fashion, because there's no
118        # way to slice storages
119        for i in range(4):
120            self.assertEqual(c[4][i + 1], c[5][i])
121
122        # check that serializing the same storage view object unpickles
123        # it as one object not two (and vice versa)
124        views = c[7]
125        self.assertEqual(views[0]._cdata, views[1]._cdata)
126        self.assertEqual(views[0], views[2])
127        self.assertNotEqual(views[0]._cdata, views[2]._cdata)
128
129        rootview = c[8]
130        self.assertEqual(rootview.data_ptr(), c[0].data_ptr())
131
132    def test_serialization_zipfile_utils(self):
133        data = {
134            'a': b'12039810948234589',
135            'b': b'1239081209484958',
136            'c/d': b'94589480984058'
137        }
138
139        def test(name_or_buffer):
140            with torch.serialization._open_zipfile_writer(name_or_buffer) as zip_file:
141                for key in data:
142                    zip_file.write_record(key, data[key], len(data[key]))
143
144            if hasattr(name_or_buffer, 'seek'):
145                name_or_buffer.seek(0)
146
147            with torch.serialization._open_zipfile_reader(name_or_buffer) as zip_file:
148                for key in data:
149                    actual = zip_file.get_record(key)
150                    expected = data[key]
151                    self.assertEqual(expected, actual)
152
153        with tempfile.NamedTemporaryFile() as f:
154            test(f)
155
156        with TemporaryFileName() as fname:
157            test(fname)
158
159        test(io.BytesIO())
160
161    def _test_serialization(self, weights_only):
162        # Test serialization with a real file
163        b = self._test_serialization_data()
164        with tempfile.NamedTemporaryFile() as f:
165            torch.save(b, f)
166            f.seek(0)
167            c = torch.load(f, weights_only=weights_only)
168            self._test_serialization_assert(b, c)
169        with TemporaryFileName() as fname:
170            torch.save(b, fname)
171            c = torch.load(fname, weights_only=weights_only)
172            self._test_serialization_assert(b, c)
173        # test non-ascii encoding of bytes arrays/strings
174        # The following bytes are produced by serializing
175        #   [b'\xc5\xbc\xc4\x85\xc4\x85\xc3\xb3\xc5\xbc\xc4\x85\xc5\xbc', torch.zeros(1, dtype=torch.float), 2]
176        # in Python 2.7.12 and PyTorch 0.4.1, where the first element contains
177        # bytes of some utf-8 characters (i.e., `utf8_str.encode('utf-8')`).
178        serialized = (
179            b'\x80\x02\x8a\nl\xfc\x9cF\xf9 j\xa8P\x19.\x80\x02M\xe9\x03.'
180            b'\x80\x02}q\x01(U\x10protocol_versionq\x02M\xe9\x03U\n'
181            b'type_sizesq\x03}q\x04(U\x03intq\x05K\x04U\x05shortq\x06K\x02U'
182            b'\x04longq\x07K\x04uU\rlittle_endianq\x08\x88u.\x80\x02]q'
183            b'\x01(U\x0e\xc5\xbc\xc4\x85\xc4\x85\xc3\xb3\xc5\xbc\xc4\x85'
184            b'\xc5\xbcq\x02ctorch._utils\n_rebuild_tensor_v2\nq\x03((U'
185            b'\x07storageq\x04ctorch\nFloatStorage\nq\x05U\x0845640624q'
186            b'\x06U\x03cpuq\x07\x8a\x01\x01NtQK\x00K\x01\x85K\x01\x85'
187            b'\x89NtRq\x08K\x02e.\x80\x02]q\x01U\x0845640624q\x02a.\x01\x00'
188            b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
189        )
190        buf = io.BytesIO(serialized)
191        utf8_bytes = b'\xc5\xbc\xc4\x85\xc4\x85\xc3\xb3\xc5\xbc\xc4\x85\xc5\xbc'
192        utf8_str = utf8_bytes.decode('utf-8')
193        loaded_utf8 = torch.load(buf, weights_only=weights_only, encoding='utf-8')
194        self.assertEqual(loaded_utf8, [utf8_str, torch.zeros(1, dtype=torch.float), 2])
195        buf.seek(0)
196        loaded_bytes = torch.load(buf, weights_only=weights_only, encoding='bytes')
197        self.assertEqual(loaded_bytes, [utf8_bytes, torch.zeros(1, dtype=torch.float), 2])
198
199    def test_serialization(self):
200        self._test_serialization(False)
201
202    def test_serialization_safe(self):
203        self._test_serialization(True)
204
205    def test_serialization_filelike(self):
206        # Test serialization (load and save) with a filelike object
207        b = self._test_serialization_data()
208        with BytesIOContext() as f:
209            torch.save(b, f)
210            f.seek(0)
211            c = torch.load(f)
212        self._test_serialization_assert(b, c)
213
214    def test_serialization_fake_zip(self):
215        data = [
216            ord('P'),
217            ord('K'),
218            5,
219            6
220        ]
221        for i in range(0, 100):
222            data.append(0)
223        t = torch.tensor(data, dtype=torch.uint8)
224
225        with tempfile.NamedTemporaryFile() as f:
226            torch.save(t, f)
227
228            # If this check is False for all Python versions (i.e. the fix
229            # has been backported), this test and torch.serialization._is_zipfile
230            # can be deleted
231            self.assertTrue(zipfile.is_zipfile(f))
232            self.assertFalse(torch.serialization._is_zipfile(f))
233            f.seek(0)
234            self.assertEqual(torch.load(f), t)
235
236    def test_serialization_gzip(self):
237        # Test serialization with gzip file
238        b = self._test_serialization_data()
239        f1 = tempfile.NamedTemporaryFile(delete=False)
240        f2 = tempfile.NamedTemporaryFile(delete=False)
241        torch.save(b, f1)
242        with open(f1.name, 'rb') as f_in, gzip.open(f2.name, 'wb') as f_out:
243            shutil.copyfileobj(f_in, f_out)
244
245        with gzip.open(f2.name, 'rb') as f:
246            c = torch.load(f)
247        self._test_serialization_assert(b, c)
248
249    @unittest.skipIf(
250        not TEST_DILL or HAS_DILL_AT_LEAST_0_3_1,
251        '"dill" not found or is correct version'
252    )
253    def test_serialization_dill_version_not_supported(self):
254        x = torch.randn(5, 5)
255
256        with tempfile.NamedTemporaryFile() as f:
257            with self.assertRaisesRegex(ValueError, 'supports dill >='):
258                torch.save(x, f, pickle_module=dill)
259            f.seek(0)
260            with self.assertRaisesRegex(ValueError, 'supports dill >='):
261                x2 = torch.load(f, pickle_module=dill, encoding='utf-8')
262
263    def test_pickle_module(self):
264        class ThrowingUnpickler(pickle.Unpickler):
265            def load(self, *args, **kwargs):
266                raise RuntimeError("rumpelstiltskin")
267
268        class ThrowingModule:
269            Unpickler = ThrowingUnpickler
270            load = ThrowingUnpickler.load
271
272        x = torch.eye(3)
273        with tempfile.NamedTemporaryFile() as f:
274            torch.save(x, f)
275            f.seek(0)
276            with self.assertRaisesRegex(RuntimeError, "rumpelstiltskin"):
277                torch.load(f, pickle_module=ThrowingModule)
278            f.seek(0)
279            z = torch.load(f)
280        self.assertEqual(x, z)
281
282    @unittest.skipIf(
283        not TEST_DILL or not HAS_DILL_AT_LEAST_0_3_1,
284        '"dill" not found or not correct version'
285    )
286    def test_serialization_dill(self):
287        x = torch.randn(5, 5)
288
289        with tempfile.NamedTemporaryFile() as f:
290            torch.save(x, f, pickle_module=dill)
291            f.seek(0)
292            x2 = torch.load(f, pickle_module=dill, encoding='utf-8')
293            self.assertIsInstance(x2, type(x))
294            self.assertEqual(x, x2)
295            f.seek(0)
296            x3 = torch.load(f, pickle_module=dill)
297            self.assertIsInstance(x3, type(x))
298            self.assertEqual(x, x3)
299
300    def test_serialization_offset_gzip(self):
301        a = torch.randn(5, 5)
302        i = 41
303        f1 = tempfile.NamedTemporaryFile(delete=False)
304        f2 = tempfile.NamedTemporaryFile(delete=False)
305        with open(f1.name, 'wb') as f:
306            pickle.dump(i, f)
307            torch.save(a, f)
308        with open(f1.name, 'rb') as f_in, gzip.open(f2.name, 'wb') as f_out:
309            shutil.copyfileobj(f_in, f_out)
310
311        with gzip.open(f2.name, 'rb') as f:
312            j = pickle.load(f)
313            b = torch.load(f)
314        self.assertTrue(torch.equal(a, b))
315        self.assertEqual(i, j)
316
317    def _test_serialization_sparse(self, weights_only):
318        def _test_serialization(conversion):
319            x = torch.zeros(3, 3)
320            x[1][1] = 1
321            x = conversion(x)
322            with tempfile.NamedTemporaryFile() as f:
323                torch.save({"tensor": x}, f)
324                f.seek(0)
325                y = torch.load(f, weights_only=weights_only)
326                self.assertEqual(x, y["tensor"], exact_is_coalesced=True)
327        _test_serialization(lambda x: x.to_sparse())
328        _test_serialization(lambda x: x.to_sparse_csr())
329        _test_serialization(lambda x: x.to_sparse_csc())
330        _test_serialization(lambda x: x.to_sparse_bsr((1, 1)))
331        _test_serialization(lambda x: x.to_sparse_bsc((1, 1)))
332
333    def test_serialization_sparse(self):
334        self._test_serialization(False)
335
336    def test_serialization_sparse_safe(self):
337        self._test_serialization(True)
338
339    def test_serialization_sparse_invalid(self):
340        x = torch.zeros(3, 3)
341        x[1][1] = 1
342        x = x.to_sparse()
343
344        class TensorSerializationSpoofer:
345            def __init__(self, tensor):
346                self.tensor = tensor
347
348            def __reduce_ex__(self, proto):
349                invalid_indices = self.tensor._indices().clone()
350                invalid_indices[0][0] = 3
351                return (
352                    torch._utils._rebuild_sparse_tensor,
353                    (
354                        self.tensor.layout,
355                        (
356                            invalid_indices,
357                            self.tensor._values(),
358                            self.tensor.size())))
359
360        with tempfile.NamedTemporaryFile() as f:
361            torch.save({"spoofed": TensorSerializationSpoofer(x)}, f)
362            f.seek(0)
363            with self.assertRaisesRegex(
364                    RuntimeError,
365                    "size is inconsistent with indices"):
366                y = torch.load(f)
367
368    def _test_serialization_sparse_compressed_invalid(self,
369                                                      conversion,
370                                                      get_compressed_indices,
371                                                      get_plain_indices):
372        x = torch.zeros(3, 3)
373        x[1][1] = 1
374        x = conversion(x)
375
376        class TensorSerializationSpoofer:
377            def __init__(self, tensor):
378                self.tensor = tensor
379
380            def __reduce_ex__(self, proto):
381                invalid_compressed_indices = get_compressed_indices(self.tensor).clone()
382                invalid_compressed_indices[0] = 3
383                return (
384                    torch._utils._rebuild_sparse_tensor,
385                    (
386                        self.tensor.layout,
387                        (
388                            invalid_compressed_indices,
389                            get_plain_indices(self.tensor),
390                            self.tensor.values(),
391                            self.tensor.size())))
392
393        if x.layout in {torch.sparse_csr, torch.sparse_bsr}:
394            compressed_indices_name = 'crow_indices'
395        else:
396            compressed_indices_name = 'ccol_indices'
397
398        with tempfile.NamedTemporaryFile() as f:
399            torch.save({"spoofed": TensorSerializationSpoofer(x)}, f)
400            f.seek(0)
401            with self.assertRaisesRegex(
402                    RuntimeError,
403                    f"`{compressed_indices_name}[[]..., 0[]] == 0` is not satisfied."):
404                y = torch.load(f)
405
406    def test_serialization_sparse_csr_invalid(self):
407        self._test_serialization_sparse_compressed_invalid(
408            torch.Tensor.to_sparse_csr, torch.Tensor.crow_indices, torch.Tensor.col_indices)
409
410    def test_serialization_sparse_csc_invalid(self):
411        self._test_serialization_sparse_compressed_invalid(
412            torch.Tensor.to_sparse_csc, torch.Tensor.ccol_indices, torch.Tensor.row_indices)
413
414    def test_serialization_sparse_bsr_invalid(self):
415        self._test_serialization_sparse_compressed_invalid(
416            lambda x: x.to_sparse_bsr((1, 1)), torch.Tensor.crow_indices, torch.Tensor.col_indices)
417
418    def test_serialization_sparse_bsc_invalid(self):
419        self._test_serialization_sparse_compressed_invalid(
420            lambda x: x.to_sparse_bsc((1, 1)), torch.Tensor.ccol_indices, torch.Tensor.row_indices)
421
422    def test_serialize_device(self):
423        device_str = ['cpu', 'cpu:0', 'cuda', 'cuda:0']
424        device_obj = [torch.device(d) for d in device_str]
425        for device in device_obj:
426            device_copied = copy.deepcopy(device)
427            self.assertEqual(device, device_copied)
428
429    def _test_serialization_backwards_compat(self, weights_only):
430        a = [torch.arange(1 + i, 26 + i).view(5, 5).float() for i in range(2)]
431        b = [a[i % 2] for i in range(4)]
432        b += [a[0].storage()]
433        b += [a[0].reshape(-1)[1:4].clone().storage()]
434        path = download_file('https://download.pytorch.org/test_data/legacy_serialized.pt')
435        c = torch.load(path, weights_only=weights_only)
436        self.assertEqual(b, c, atol=0, rtol=0)
437        self.assertTrue(isinstance(c[0], torch.FloatTensor))
438        self.assertTrue(isinstance(c[1], torch.FloatTensor))
439        self.assertTrue(isinstance(c[2], torch.FloatTensor))
440        self.assertTrue(isinstance(c[3], torch.FloatTensor))
441        self.assertTrue(isinstance(c[4], torch.storage.TypedStorage))
442        self.assertEqual(c[4].dtype, torch.float32)
443        c[0].fill_(10)
444        self.assertEqual(c[0], c[2], atol=0, rtol=0)
445        self.assertEqual(c[4], torch.FloatStorage(25).fill_(10), atol=0, rtol=0)
446        c[1].fill_(20)
447        self.assertEqual(c[1], c[3], atol=0, rtol=0)
448
449        # test some old tensor serialization mechanism
450        class OldTensorBase:
451            def __init__(self, new_tensor):
452                self.new_tensor = new_tensor
453
454            def __getstate__(self):
455                return (self.new_tensor.storage(),
456                        self.new_tensor.storage_offset(),
457                        tuple(self.new_tensor.size()),
458                        self.new_tensor.stride())
459
460        class OldTensorV1(OldTensorBase):
461            def __reduce__(self):
462                return (torch.Tensor, (), self.__getstate__())
463
464        class OldTensorV2(OldTensorBase):
465            def __reduce__(self):
466                return (_rebuild_tensor, self.__getstate__())
467
468        x = torch.randn(30).as_strided([2, 3], [9, 3], 2)
469        for old_cls in [OldTensorV1, OldTensorV2]:
470            with tempfile.NamedTemporaryFile() as f:
471                old_x = old_cls(x)
472                torch.save(old_x, f)
473                f.seek(0)
474                load_x = torch.load(f, weights_only=weights_only)
475                self.assertEqual(x.storage(), load_x.storage())
476                self.assertEqual(x.storage_offset(), load_x.storage_offset())
477                self.assertEqual(x.size(), load_x.size())
478                self.assertEqual(x.stride(), load_x.stride())
479
480    def test_serialization_backwards_compat(self):
481        self._test_serialization_backwards_compat(False)
482
483    def test_serialization_backwards_compat_safe(self):
484        self._test_serialization_backwards_compat(True)
485
486    def test_serialization_save_warnings(self):
487        with warnings.catch_warnings(record=True) as warns:
488            with tempfile.NamedTemporaryFile() as checkpoint:
489                x = torch.save(torch.nn.Linear(2, 3), checkpoint)
490                self.assertEqual(len(warns), 0)
491
492    def test_serialization_map_location(self):
493        test_file_path = download_file('https://download.pytorch.org/test_data/gpu_tensors.pt')
494
495        def map_location(storage, loc):
496            return storage
497
498        def generate_map_locations(device_type):
499            return [
500                {'cuda:0': device_type + ':0'},
501                device_type,
502                device_type + ':0',
503                torch.device(device_type),
504                torch.device(device_type, 0)
505            ]
506
507        def load_bytes():
508            with open(test_file_path, 'rb') as f:
509                return io.BytesIO(f.read())
510
511        fileobject_lambdas = [lambda: test_file_path, load_bytes]
512        cpu_map_locations = [
513            map_location,
514            {'cuda:0': 'cpu'},
515            'cpu',
516            torch.device('cpu'),
517        ]
518        gpu_0_map_locations = generate_map_locations('cuda')
519        gpu_last_map_locations = [
520            f'cuda:{torch.cuda.device_count() - 1}',
521        ]
522        xpu_0_map_locations = generate_map_locations('xpu')
523        xpu_last_map_locations = [
524            f'xpu:{torch.xpu.device_count() - 1}',
525        ]
526
527        def check_map_locations(map_locations, dtype, intended_device):
528            for fileobject_lambda in fileobject_lambdas:
529                for map_location in map_locations:
530                    tensor = torch.load(fileobject_lambda(), map_location=map_location)
531
532                    self.assertEqual(tensor.device, intended_device)
533                    self.assertEqual(tensor.dtype, dtype)
534                    self.assertEqual(tensor, torch.tensor([[1.0, 2.0], [3.0, 4.0]], dtype=dtype, device=intended_device))
535
536        check_map_locations(cpu_map_locations, torch.float, torch.device('cpu'))
537        if torch.cuda.is_available():
538            check_map_locations(gpu_0_map_locations, torch.float, torch.device('cuda', 0))
539            check_map_locations(
540                gpu_last_map_locations,
541                torch.float,
542                torch.device('cuda', torch.cuda.device_count() - 1)
543            )
544        if torch.xpu.is_available():
545            check_map_locations(xpu_0_map_locations, torch.float, torch.device('xpu', 0))
546            check_map_locations(
547                xpu_last_map_locations,
548                torch.float,
549                torch.device('xpu', torch.xpu.device_count() - 1)
550            )
551
552    @unittest.skipIf(torch.cuda.is_available(), "Testing torch.load on CPU-only machine")
553    def test_load_nonexistent_device(self):
554        # Setup: create a serialized file object with a 'cuda:0' restore location
555        # The following was generated by saving a torch.randn(2, device='cuda') tensor.
556        serialized = (b'\x80\x02\x8a\nl\xfc\x9cF\xf9 j\xa8P\x19.\x80\x02M\xe9'
557                      b'\x03.\x80\x02}q\x00(X\x10\x00\x00\x00protocol_versionq'
558                      b'\x01M\xe9\x03X\r\x00\x00\x00little_endianq\x02\x88X\n'
559                      b'\x00\x00\x00type_sizesq\x03}q\x04(X\x05\x00\x00\x00shortq'
560                      b'\x05K\x02X\x03\x00\x00\x00intq\x06K\x04X\x04\x00\x00\x00'
561                      b'longq\x07K\x04uu.\x80\x02ctorch._utils\n_rebuild_tensor_v2'
562                      b'\nq\x00((X\x07\x00\x00\x00storageq\x01ctorch\nFloatStorage'
563                      b'\nq\x02X\x0e\x00\x00\x0094919395964320q\x03X\x06\x00\x00'
564                      b'\x00cuda:0q\x04K\x02Ntq\x05QK\x00K\x02\x85q\x06K\x01\x85q'
565                      b'\x07\x89Ntq\x08Rq\t.\x80\x02]q\x00X\x0e\x00\x00\x00'
566                      b'94919395964320q\x01a.\x02\x00\x00\x00\x00\x00\x00\x00\xbb'
567                      b'\x1f\x82\xbe\xea\x81\xd1>')
568
569        buf = io.BytesIO(serialized)
570
571        error_msg = r'Attempting to deserialize object on a CUDA device'
572        with self.assertRaisesRegex(RuntimeError, error_msg):
573            _ = torch.load(buf)
574
575    @unittest.skipIf((3, 8, 0) <= sys.version_info < (3, 8, 2), "See https://bugs.python.org/issue39681")
576    def test_serialization_filelike_api_requirements(self):
577        filemock = FilelikeMock(b'', has_readinto=False)
578        tensor = torch.randn(3, 5)
579        torch.save(tensor, filemock)
580        expected_superset = {'write', 'flush'}
581        self.assertTrue(expected_superset.issuperset(filemock.calls))
582
583        # Reset between save and load
584        filemock.seek(0)
585        filemock.calls.clear()
586
587        _ = torch.load(filemock)
588        expected_superset = {'read', 'readline', 'seek', 'tell'}
589        self.assertTrue(expected_superset.issuperset(filemock.calls))
590
591    def _test_serialization_filelike(self, tensor, mock, desc):
592        f = mock(b'')
593        torch.save(tensor, f)
594        f.seek(0)
595        data = mock(f.read())
596
597        msg = 'filelike serialization with {}'
598
599        b = torch.load(data)
600        self.assertTrue(torch.equal(tensor, b), msg.format(desc))
601
602    @unittest.skipIf((3, 8, 0) <= sys.version_info < (3, 8, 2), "See https://bugs.python.org/issue39681")
603    def test_serialization_filelike_missing_attrs(self):
604        # Test edge cases where filelike objects are missing attributes.
605        # The Python io docs suggests that these attributes should really exist
606        # and throw io.UnsupportedOperation, but that isn't always the case.
607        mocks = [
608            ('no readinto', lambda x: FilelikeMock(x)),
609            ('has readinto', lambda x: FilelikeMock(x, has_readinto=True)),
610            ('no fileno', lambda x: FilelikeMock(x, has_fileno=False)),
611        ]
612
613        to_serialize = torch.randn(3, 10)
614        for desc, mock in mocks:
615            self._test_serialization_filelike(to_serialize, mock, desc)
616
617    @unittest.skipIf((3, 8, 0) <= sys.version_info < (3, 8, 2), "See https://bugs.python.org/issue39681")
618    def test_serialization_filelike_stress(self):
619        a = torch.randn(11 * (2 ** 9) + 1, 5 * (2 ** 9))
620
621        # This one should call python read multiple times
622        self._test_serialization_filelike(a, lambda x: FilelikeMock(x, has_readinto=False),
623                                          'read() stress test')
624        self._test_serialization_filelike(a, lambda x: FilelikeMock(x, has_readinto=True),
625                                          'readinto() stress test')
626
627    def test_serialization_filelike_uses_readinto(self):
628        # For maximum effiency, when reading a file-like object,
629        # ensure the C API calls readinto instead of read.
630        a = torch.randn(5, 4)
631
632        f = io.BytesIO()
633        torch.save(a, f)
634        f.seek(0)
635        data = FilelikeMock(f.read(), has_readinto=True)
636
637        b = torch.load(data)
638        self.assertTrue(data.was_called('readinto'))
639
640    def test_serialization_filelike_exceptions(self):
641        # Try to serialize to buffers that does not have write method
642        # Or have a malfrormed one, and make sure it does not cause an abort
643        # See https://github.com/pytorch/pytorch/issues/87997
644        x = torch.rand(10)
645        with self.assertRaises(AttributeError):
646            # Tries to serialize str into tensor
647            torch.save('foo', x)
648        x.write = "bar"
649        x.flush = "baz"
650        with self.assertRaises(TypeError):
651            # Tries to serialize str into tensor with write property
652            torch.save('foo', x)
653        x.write = str.__add__
654        x.flush = str.__mul__
655        with self.assertRaises(TypeError):
656            # Tries to serialize str into tensor with wrong callable write property
657            torch.save('foo', x)
658        s_data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
659        s = torch.CharStorage(s_data)
660        with self.assertRaises(AttributeError):
661            # Tries to serialize list into CharStorage
662            torch.save(s_data, s)
663        x = torch.randint(10, (3, 3), dtype=torch.float).cpu().numpy()
664        with self.assertRaises(AttributeError):
665            # Tries to serialize ndarray into ndarray
666            torch.save(x, x)
667
668
669    def test_serialization_storage_slice(self):
670        # Generated using:
671        #
672        # t = torch.zeros(2);
673        # s1 = t.storage()[:1]
674        # s2 = t.storage()[1:]
675        # torch.save((s1, s2), 'foo.ser')
676        #
677        # with PyTorch 0.3.1
678        serialized = (b'\x80\x02\x8a\nl\xfc\x9cF\xf9 j\xa8P\x19.\x80\x02M\xe9\x03'
679                      b'.\x80\x02}q\x00(X\n\x00\x00\x00type_sizesq\x01}q\x02(X\x03'
680                      b'\x00\x00\x00intq\x03K\x04X\x05\x00\x00\x00shortq\x04K\x02X'
681                      b'\x04\x00\x00\x00longq\x05K\x04uX\x10\x00\x00\x00protocol_versionq'
682                      b'\x06M\xe9\x03X\r\x00\x00\x00little_endianq\x07\x88u.\x80\x02'
683                      b'(X\x07\x00\x00\x00storageq\x00ctorch\nFloatStorage\nq\x01X\x0e'
684                      b'\x00\x00\x0094279043900432q\x02X\x03\x00\x00\x00cpuq\x03K\x02'
685                      b'X\x0e\x00\x00\x0094279029750368q\x04K\x00K\x01\x87q\x05tq\x06'
686                      b'Q(h\x00h\x01X\x0e\x00\x00\x0094279043900432q\x07h\x03K\x02X'
687                      b'\x0e\x00\x00\x0094279029750432q\x08K\x01K\x01\x87q\ttq\nQ'
688                      b'\x86q\x0b.\x80\x02]q\x00X\x0e\x00\x00\x0094279043900432q'
689                      b'\x01a.\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
690                      b'\x00\x00\x00\x00')
691
692        buf = io.BytesIO(serialized)
693        (s1, s2) = torch.load(buf)
694        self.assertEqual(s1[0], 0)
695        self.assertEqual(s2[0], 0)
696        self.assertEqual(s1.data_ptr() + 4, s2.data_ptr())
697
698    def test_load_unicode_error_msg(self):
699        # This Pickle contains a Python 2 module with Unicode data and the
700        # loading should fail if the user explicitly specifies ascii encoding!
701        path = download_file('https://download.pytorch.org/test_data/legacy_conv2d.pt')
702        self.assertRaises(UnicodeDecodeError, lambda: torch.load(path, encoding='ascii'))
703
704    def test_load_python2_unicode_module(self):
705        # This Pickle contains some Unicode data!
706        path = download_file('https://download.pytorch.org/test_data/legacy_conv2d.pt')
707        with warnings.catch_warnings(record=True) as w:
708            self.assertIsNotNone(torch.load(path))
709
710    def test_load_error_msg(self):
711        expected_err_msg = (".*You can only torch.load from a file that is seekable. " +
712                            "Please pre-load the data into a buffer like io.BytesIO and " +
713                            "try to load from it instead.")
714
715        resource = FilelikeMock(data=b"data")
716        delattr(resource, "tell")
717        delattr(resource, "seek")
718        with self.assertRaisesRegex(AttributeError, expected_err_msg):
719            torch.load(resource)
720
721    def test_save_different_dtype_unallocated(self):
722        devices = ['cpu']
723        if torch.cuda.is_available():
724            devices.append('cuda')
725
726        def save_load_check(a, b):
727            with io.BytesIO() as f:
728                torch.save([a, b], f)
729                f.seek(0)
730                a_loaded, b_loaded = torch.load(f)
731            self.assertEqual(a, a_loaded)
732            self.assertEqual(b, b_loaded)
733
734        for device, dtype in product(devices, all_types_and_complex_and(torch.half,
735                                                                        torch.bfloat16, torch.bool)):
736            a = torch.tensor([], dtype=dtype, device=device)
737
738            for other_dtype in all_types_and_complex_and(torch.half, torch.bfloat16, torch.bool):
739                s = torch.TypedStorage(
740                    wrap_storage=a.storage().untyped(),
741                    dtype=other_dtype)
742                save_load_check(a, s)
743                save_load_check(a.storage(), s)
744                b = torch.tensor([], dtype=other_dtype, device=device)
745                save_load_check(a, b)
746
747    def test_save_different_dtype_error(self):
748        error_msg = r"Cannot save multiple tensors or storages that view the same data as different types"
749
750        devices = ['cpu']
751        if torch.cuda.is_available():
752            devices.append('cuda')
753
754        for device in devices:
755            a = torch.randn(10, dtype=torch.complex128, device=device)
756            f = io.BytesIO()
757
758            with self.assertRaisesRegex(RuntimeError, error_msg):
759                torch.save([a, a.imag], f)
760
761            with self.assertRaisesRegex(RuntimeError, error_msg):
762                torch.save([a.storage(), a.imag], f)
763
764            with self.assertRaisesRegex(RuntimeError, error_msg):
765                torch.save([a, a.imag.storage()], f)
766
767            with self.assertRaisesRegex(RuntimeError, error_msg):
768                torch.save([a.storage(), a.imag.storage()], f)
769
770            a = torch.randn(10, device=device)
771            s_bytes = torch.TypedStorage(
772                wrap_storage=a.storage().untyped(),
773                dtype=torch.uint8)
774
775            with self.assertRaisesRegex(RuntimeError, error_msg):
776                torch.save([a, s_bytes], f)
777
778            with self.assertRaisesRegex(RuntimeError, error_msg):
779                torch.save([a.storage(), s_bytes], f)
780
781    def test_safe_load_basic_types(self):
782        with tempfile.NamedTemporaryFile() as f:
783            data = {"int": 123, "str": "world", "float": 3.14, "bool": False}
784            torch.save(data, f)
785            f.seek(0)
786            loaded_data = torch.load(f, weights_only=True)
787            self.assertEqual(data, loaded_data)
788
789
790class serialization_method:
791    def __init__(self, use_zip):
792        self.use_zip = use_zip
793        self.torch_save = torch.save
794
795    def __enter__(self, *args, **kwargs):
796        def wrapper(*args, **kwargs):
797            if '_use_new_zipfile_serialization' in kwargs:
798                raise RuntimeError("Cannot set method manually")
799            kwargs['_use_new_zipfile_serialization'] = self.use_zip
800            return self.torch_save(*args, **kwargs)
801
802        torch.save = wrapper
803
804    def __exit__(self, *args, **kwargs):
805        torch.save = self.torch_save
806
807Point = namedtuple('Point', ['x', 'y'])
808
809class ClassThatUsesBuildInstruction:
810    def __init__(self, num):
811        self.num = num
812
813    def __reduce_ex__(self, proto):
814        # Third item, state here will cause pickle to push a BUILD instruction
815        return ClassThatUsesBuildInstruction, (self.num,), {'foo': 'bar'}
816
817
818@unittest.skipIf(IS_WINDOWS, "NamedTemporaryFile on windows")
819class TestBothSerialization(TestCase):
820    @parametrize("weights_only", (True, False))
821    def test_serialization_new_format_old_format_compat(self, device, weights_only):
822        x = [torch.ones(200, 200, device=device) for i in range(30)]
823
824        def test(f_new, f_old):
825            torch.save(x, f_new, _use_new_zipfile_serialization=True)
826            f_new.seek(0)
827            x_new_load = torch.load(f_new, weights_only=weights_only)
828            self.assertEqual(x, x_new_load)
829
830            torch.save(x, f_old, _use_new_zipfile_serialization=False)
831            f_old.seek(0)
832            x_old_load = torch.load(f_old, weights_only=weights_only)
833            self.assertEqual(x_old_load, x_new_load)
834
835        with AlwaysWarnTypedStorageRemoval(True), warnings.catch_warnings(record=True) as w:
836            with tempfile.NamedTemporaryFile() as f_new, tempfile.NamedTemporaryFile() as f_old:
837                test(f_new, f_old)
838            self.assertTrue(len(w) == 0, msg=f"Expected no warnings but got {[str(x) for x in w]}")
839
840
841class TestOldSerialization(TestCase, SerializationMixin):
842    # unique_key is necessary because on Python 2.7, if a warning passed to
843    # the warning module is the same, it is not raised again.
844    def _test_serialization_container(self, unique_key, filecontext_lambda):
845
846        tmpmodule_name = f'tmpmodule{unique_key}'
847
848        def import_module(name, filename):
849            import importlib.util
850            spec = importlib.util.spec_from_file_location(name, filename)
851            module = importlib.util.module_from_spec(spec)
852            spec.loader.exec_module(module)
853            sys.modules[module.__name__] = module
854            return module
855
856        with filecontext_lambda() as checkpoint:
857            fname = get_file_path_2(os.path.dirname(os.path.dirname(torch.__file__)), 'torch', 'testing',
858                                    '_internal', 'data', 'network1.py')
859            module = import_module(tmpmodule_name, fname)
860            torch.save(module.Net(), checkpoint)
861
862            # First check that the checkpoint can be loaded without warning about unsafe loads
863            checkpoint.seek(0)
864            with warnings.catch_warnings(record=True) as w:
865                loaded = torch.load(checkpoint)
866                self.assertTrue(isinstance(loaded, module.Net))
867                if can_retrieve_source:
868                    self.assertEqual(len(w), 1)
869                    self.assertEqual(w[0].category, FutureWarning)
870                    self.assertTrue("You are using `torch.load` with `weights_only=False`" in str(w[0].message))
871
872            # Replace the module with different source
873            fname = get_file_path_2(os.path.dirname(os.path.dirname(torch.__file__)), 'torch', 'testing',
874                                    '_internal', 'data', 'network2.py')
875            module = import_module(tmpmodule_name, fname)
876            checkpoint.seek(0)
877            with warnings.catch_warnings(record=True) as w:
878                loaded = torch.load(checkpoint)
879                self.assertTrue(isinstance(loaded, module.Net))
880                if can_retrieve_source:
881                    self.assertEqual(len(w), 2)
882                    self.assertEqual(w[0].category, FutureWarning)
883                    self.assertEqual(w[1].category, SourceChangeWarning)
884
885    def test_serialization_container(self):
886        self._test_serialization_container('file', tempfile.NamedTemporaryFile)
887
888    def test_serialization_container_filelike(self):
889        self._test_serialization_container('filelike', BytesIOContext)
890
891    def test_serialization_offset(self):
892        a = torch.randn(5, 5)
893        b = torch.randn(1024, 1024, 512, dtype=torch.float32)
894        m = torch.nn.Conv2d(1, 1, (1, 3))
895        i, j = 41, 43
896        with tempfile.NamedTemporaryFile() as f:
897            pickle.dump(i, f)
898            torch.save(a, f)
899            pickle.dump(j, f)
900            torch.save(b, f)
901            torch.save(m, f)
902            self.assertTrue(f.tell() > 2 * 1024 * 1024 * 1024)
903            f.seek(0)
904            i_loaded = pickle.load(f)
905            a_loaded = torch.load(f)
906            j_loaded = pickle.load(f)
907            b_loaded = torch.load(f)
908            m_loaded = torch.load(f)
909        self.assertTrue(torch.equal(a, a_loaded))
910        self.assertTrue(torch.equal(b, b_loaded))
911        self.assertTrue(m.kernel_size == m_loaded.kernel_size)
912        self.assertEqual(i, i_loaded)
913        self.assertEqual(j, j_loaded)
914
915    @parametrize('weights_only', (True, False))
916    def test_serialization_offset_filelike(self, weights_only):
917        a = torch.randn(5, 5)
918        b = torch.randn(1024, 1024, 512, dtype=torch.float32)
919        i, j = 41, 43
920        with BytesIOContext() as f:
921            pickle.dump(i, f)
922            torch.save(a, f)
923            pickle.dump(j, f)
924            torch.save(b, f)
925            self.assertTrue(f.tell() > 2 * 1024 * 1024 * 1024)
926            f.seek(0)
927            i_loaded = pickle.load(f)
928            a_loaded = torch.load(f, weights_only=weights_only)
929            j_loaded = pickle.load(f)
930            b_loaded = torch.load(f, weights_only=weights_only)
931        self.assertTrue(torch.equal(a, a_loaded))
932        self.assertTrue(torch.equal(b, b_loaded))
933        self.assertEqual(i, i_loaded)
934        self.assertEqual(j, j_loaded)
935
936    def run(self, *args, **kwargs):
937        with serialization_method(use_zip=False):
938            return super().run(*args, **kwargs)
939
940
941class TestSerialization(TestCase, SerializationMixin):
942    @parametrize('weights_only', (True, False))
943    def test_serialization_zipfile(self, weights_only):
944        data = self._test_serialization_data()
945
946        def test(name_or_buffer):
947            torch.save(data, name_or_buffer)
948
949            if hasattr(name_or_buffer, 'seek'):
950                name_or_buffer.seek(0)
951
952            result = torch.load(name_or_buffer, weights_only=weights_only)
953            self.assertEqual(result, data)
954
955        with tempfile.NamedTemporaryFile() as f:
956            test(f)
957
958        with TemporaryFileName() as fname:
959            test(fname)
960
961        if IS_FILESYSTEM_UTF8_ENCODING:
962            with TemporaryDirectoryName(suffix='\u975eASCII\u30d1\u30b9') as dname:
963                with TemporaryFileName(dir=dname) as fname:
964                    test(fname)
965
966        test(io.BytesIO())
967
968    def test_serialization_zipfile_actually_jit(self):
969        with tempfile.NamedTemporaryFile() as f:
970            torch.jit.save(torch.jit.script(torch.nn.Linear(3, 4)), f)
971            f.seek(0)
972            torch.load(f)
973
974    # Ensure large zip64 serialization works properly
975    @serialTest()
976    def test_serialization_2gb_file(self):
977        # Run GC to clear up as much memory as possible before running this test
978        gc.collect()
979        big_model = torch.nn.Conv2d(20000, 3200, kernel_size=3)
980
981        with BytesIOContext() as f:
982            torch.save(big_model.state_dict(), f)
983            f.seek(0)
984            state = torch.load(f)
985
986    @parametrize('weights_only', (True, False))
987    def test_pathlike_serialization(self, weights_only):
988        model = torch.nn.Conv2d(20, 3200, kernel_size=3)
989
990        with TemporaryFileName() as fname:
991            path = pathlib.Path(fname)
992            torch.save(model.state_dict(), path)
993            torch.load(path, weights_only=weights_only)
994
995    @parametrize('weights_only', (True, False))
996    def test_meta_serialization(self, weights_only):
997        big_model = torch.nn.Conv2d(20000, 320000, kernel_size=3, device='meta')
998
999        with BytesIOContext() as f:
1000            torch.save(big_model.state_dict(), f)
1001            f.seek(0)
1002            state = torch.load(f, weights_only=weights_only)
1003
1004        self.assertEqual(state['weight'].size(), big_model.weight.size())
1005
1006    def test_lr_scheduler_serialization(self):
1007        sgd = torch.optim.SGD([
1008            torch.tensor(torch.randn(100, 100, 2000), requires_grad=True)
1009        ], lr=0.1, momentum=0.9)
1010        lr_scheduler = torch.optim.lr_scheduler.OneCycleLR(sgd, 6.0, total_steps=10)
1011
1012        with BytesIOContext() as f:
1013            torch.save(lr_scheduler.state_dict(), f)
1014            f.seek(0, os.SEEK_END)
1015            size = f.tell()
1016            f.seek(0)
1017            lr_scheduler_state = torch.load(f)
1018
1019        self.assertEqual(lr_scheduler_state['base_lrs'], lr_scheduler.base_lrs)
1020        if 'anneal_func' in lr_scheduler_state:
1021            self.assertFalse(hasattr(lr_scheduler_state['anneal_func'], '__self__'))  # check method is not bound
1022        else:
1023            self.assertTrue('_anneal_func_type' in lr_scheduler_state)
1024        self.assertTrue(size < 1024 * 1024)  # Must be less than 1MB
1025
1026    @parametrize('weights_only', (True, False))
1027    def test_serialization_python_attr(self, weights_only):
1028        def _test_save_load_attr(t):
1029            t.foo = 'foo'
1030            t.pi = 3.14
1031
1032            with BytesIOContext() as f:
1033                torch.save(t, f)
1034                f.seek(0)
1035                loaded_t = torch.load(f, weights_only=weights_only)
1036
1037            self.assertEqual(t, loaded_t)
1038            self.assertEqual(t.foo, loaded_t.foo)
1039            self.assertEqual(t.pi, loaded_t.pi)
1040
1041        t = torch.zeros(3, 3)
1042        _test_save_load_attr(t)
1043        _test_save_load_attr(torch.nn.Parameter(t))
1044
1045    def test_weights_only_assert(self):
1046        class HelloWorld:
1047            def __reduce__(self):
1048                return (print, ("Hello World!",))
1049
1050        with BytesIOContext() as f:
1051            torch.save(HelloWorld(), f)
1052            f.seek(0)
1053            # Unsafe load should work
1054            self.assertIsNone(torch.load(f, weights_only=False))
1055            f.seek(0)
1056            # Safe load should assert
1057            with self.assertRaisesRegex(pickle.UnpicklingError, "Unsupported global: GLOBAL builtins.print"):
1058                torch.load(f, weights_only=True)
1059            try:
1060                torch.serialization.add_safe_globals([print])
1061                f.seek(0)
1062                torch.load(f, weights_only=True)
1063            finally:
1064                torch.serialization.clear_safe_globals()
1065
1066    def test_weights_only_safe_globals_newobj(self):
1067        # This will use NEWOBJ
1068        p = Point(x=1, y=2)
1069        with BytesIOContext() as f:
1070            torch.save(p, f)
1071            f.seek(0)
1072            with self.assertRaisesRegex(pickle.UnpicklingError,
1073                                        "GLOBAL __main__.Point was not an allowed global by default"):
1074                torch.load(f, weights_only=True)
1075            f.seek(0)
1076            try:
1077                torch.serialization.add_safe_globals([Point])
1078                loaded_p = torch.load(f, weights_only=True)
1079                self.assertEqual(loaded_p, p)
1080            finally:
1081                torch.serialization.clear_safe_globals()
1082
1083    def test_weights_only_safe_globals_build(self):
1084        counter = 0
1085
1086        def fake_set_state(obj, *args):
1087            nonlocal counter
1088            counter += 1
1089
1090        c = ClassThatUsesBuildInstruction(2)
1091        with BytesIOContext() as f:
1092            torch.save(c, f)
1093            f.seek(0)
1094            with self.assertRaisesRegex(pickle.UnpicklingError,
1095                                        "GLOBAL __main__.ClassThatUsesBuildInstruction was not an allowed global by default"):
1096                torch.load(f, weights_only=True)
1097            try:
1098                torch.serialization.add_safe_globals([ClassThatUsesBuildInstruction])
1099                # Test dict update path
1100                f.seek(0)
1101                loaded_c = torch.load(f, weights_only=True)
1102                self.assertEqual(loaded_c.num, 2)
1103                self.assertEqual(loaded_c.foo, 'bar')
1104                # Test setstate path
1105                ClassThatUsesBuildInstruction.__setstate__ = fake_set_state
1106                f.seek(0)
1107                loaded_c = torch.load(f, weights_only=True)
1108                self.assertEqual(loaded_c.num, 2)
1109                self.assertEqual(counter, 1)
1110                self.assertFalse(hasattr(loaded_c, 'foo'))
1111            finally:
1112                torch.serialization.clear_safe_globals()
1113                ClassThatUsesBuildInstruction.__setstate__ = None
1114
1115    @parametrize("unsafe_global", [True, False])
1116    def test_weights_only_error(self, unsafe_global):
1117        sd = {'t': TwoTensor(torch.randn(2), torch.randn(2))}
1118        pickle_protocol = torch.serialization.DEFAULT_PROTOCOL if unsafe_global else 5
1119        with BytesIOContext() as f:
1120            torch.save(sd, f, pickle_protocol=pickle_protocol)
1121            f.seek(0)
1122            if unsafe_global:
1123                with self.assertRaisesRegex(pickle.UnpicklingError,
1124                                            r"use `torch.serialization.add_safe_globals\(\[TwoTensor\]\)` to allowlist"):
1125                    torch.load(f, weights_only=True)
1126            else:
1127                with self.assertRaisesRegex(pickle.UnpicklingError,
1128                                            "file an issue with the following so that we can make `weights_only=True`"):
1129                    torch.load(f, weights_only=True)
1130
1131    @parametrize('weights_only', (False, True))
1132    def test_serialization_math_bits(self, weights_only):
1133        t = torch.randn(1, dtype=torch.cfloat)
1134
1135        def _save_load_check(t):
1136            with BytesIOContext() as f:
1137                torch.save(t, f)
1138                f.seek(0)
1139                # Unsafe load should work
1140                self.assertEqual(torch.load(f, weights_only=weights_only), t)
1141
1142        t_conj = torch.conj(t)
1143        _save_load_check(t_conj)
1144
1145        t_neg = torch._neg_view(t)
1146        _save_load_check(t_neg)
1147
1148        t_n_c = torch._neg_view(torch.conj(t))
1149        _save_load_check(t_n_c)
1150
1151    @parametrize('weights_only', (False, True))
1152    def test_serialization_efficient_zerotensor(self, weights_only):
1153        # We don't support serializing `ZeroTensor` as it is not public
1154        # facing yet.
1155        # If in future, `ZeroTensor` serialization is supported, this test
1156        # should start failing!
1157        t = torch._efficientzerotensor((4, 5))
1158
1159        def _save_load_check(t):
1160            with BytesIOContext() as f:
1161                torch.save(t, f)
1162                f.seek(0)
1163                # Unsafe load should work
1164                self.assertEqual(torch.load(f, weights_only=weights_only), t)
1165
1166        # NOTE: `torch.save` fails before we hit the TORCH_CHECK in `getTensoMetadata`
1167        #       as nullptr storage is disabled.
1168        with self.assertRaisesRegex(RuntimeError, 'ZeroTensor is not serializable'):
1169            _save_load_check(t)
1170
1171    def test_serialization_byteorder_mark(self):
1172        lstm = torch.nn.LSTM(3, 3)
1173        inputs = [torch.randn(1, 3) for _ in range(5)]
1174        inputs = torch.cat(inputs).view(len(inputs), 1, -1)
1175        hidden = (torch.randn(1, 1, 3), torch.randn(1, 1, 3))  # clean out hidden state
1176
1177        databuffer = io.BytesIO()
1178        torch.save(lstm.state_dict(), databuffer)
1179        databuffer.seek(0)
1180
1181        with torch.serialization._open_zipfile_reader(databuffer) as zip_file:
1182            byteordername = 'byteorder'
1183            self.assertTrue(zip_file.has_record(byteordername))
1184            byteorderdata = zip_file.get_record(byteordername)
1185            self.assertTrue(byteorderdata in [b'little', b'big'])
1186            self.assertEqual(byteorderdata.decode(), sys.byteorder)
1187
1188    def test_serialization_load_bom_data(self):
1189        # 1. Generated on LE system using following commands:
1190        #
1191        # import torch
1192        #
1193        # lstm = torch.nn.LSTM(3, 3)
1194        # inputs = [torch.randn(1, 3) for _ in range(5)]
1195        #
1196        # inputs = torch.cat(inputs).view(len(inputs), 1, -1)
1197        # hidden = (torch.randn(1, 1, 3), torch.randn(1, 1, 3))
1198        #
1199        # torch.save(lstm.state_dict(), "lstm.LE.pt", _disable_byteorder_record=True)
1200        # torch.save(lstm.state_dict(), "lstm.LE.BOM.pt")
1201        #
1202        # print(lstm.state_dict())
1203        #
1204        # 2. After that it is resaved on BE system with following commands:
1205        #
1206        # import torch
1207        #
1208        # lstm = torch.nn.LSTM(3, 3)
1209        # lstm.load_state_dict(torch.load("lstm.LE.BOM.pt"), strict=True)
1210        #
1211        # torch.save(lstm.state_dict(), "lstm.BE.pt", _disable_byteorder_record=True)
1212        # torch.save(lstm.state_dict(), "lstm.BE.BOM.pt")
1213        #
1214        # print(lstm.state_dict())
1215        #
1216        # Following commands and a bit of manual work were used to produce python bytes from resulting files:
1217        #
1218        # file = open('filename', 'rb')
1219        # data = file.read()
1220        # file.close()
1221        # print("\n".join(textwrap.wrap(str(data), 80)))
1222        #
1223        # BOM in this context is used as Byte Order Mark.
1224        #
1225        data_le_no_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1226                          b'\x00\x00\x00\x00\x00\r\x00\x15\x00lstm/data.pklFB\x11\x00ZZZZZZZZZZZZZZZZZ\x80\x02'
1227                          b'ccollections\nOrderedDict\nq\x00)Rq\x01(X\x0c\x00\x00\x00weight_ih_l0q\x02ctor'
1228                          b'ch._utils\n_rebuild_tensor_v2\nq\x03((X\x07\x00\x00\x00storageq\x04ctorch\nFloat'
1229                          b'Storage\nq\x05X\x01\x00\x00\x000q\x06X\x03\x00\x00\x00cpuq\x07K$tq\x08QK\x00K\x0c'
1230                          b'K\x03\x86q\tK\x03K\x01\x86q\n\x89h\x00)Rq\x0btq\x0cRq\rX\x0c\x00\x00\x00weight_'
1231                          b'hh_l0q\x0eh\x03((h\x04h\x05X\x01\x00\x00\x001q\x0fh\x07K$tq\x10QK\x00K\x0cK\x03\x86'
1232                          b'q\x11K\x03K\x01\x86q\x12\x89h\x00)Rq\x13tq\x14Rq\x15X\n\x00\x00\x00bias_ih_l0'
1233                          b'q\x16h\x03((h\x04h\x05X\x01\x00\x00\x002q\x17h\x07K\x0ctq\x18QK\x00K\x0c\x85q\x19'
1234                          b'K\x01\x85q\x1a\x89h\x00)Rq\x1btq\x1cRq\x1dX\n\x00\x00\x00bias_hh_l0q\x1eh\x03(('
1235                          b'h\x04h\x05X\x01\x00\x00\x003q\x1fh\x07K\x0ctq QK\x00K\x0c\x85q!K\x01\x85q"\x89h\x00'
1236                          b')Rq#tq$Rq%u}q&X\t\x00\x00\x00_metadataq\'h\x00)Rq(X\x00\x00\x00\x00q)}q*X\x07'
1237                          b'\x00\x00\x00versionq+K\x01sssb.PK\x07\x08\xab\xf1\xfb\x01\xb8\x01\x00\x00\xb8\x01'
1238                          b'\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1239                          b'\x00\x00\x00\x00\x00\x00\x0b\x00\x0f\x00lstm/data/0FB\x0b\x00ZZZZZZZZZZZ\nuJ\xbe'
1240                          b'X*\xa2\xbe\xc4\xea\x10>\xd4\n\x8d\xbe\x1c\x10\x8a\xbe\xb02\xe4\xbe,\xcb4>\x00'
1241                          b'\x17!>H\x9c\xe0\xbe\xd2\x15!\xbe6C\xc6>v\xc5\x89>\xae\x14\x81\xbeZ\xc7\x99>\x90P'
1242                          b'\x01?`\xb9\x9a<\xc0 <=\'\xc7\x9e\xbe\xaa\xf4\x02?\x00\xf3\x0e\xbc\xd8\xb7v\xbe\xa0'
1243                          b'\xcc\xcd=$/\xaf>\x00\xc4K=0\xb8\xe5\xbe\xb6\xc5U\xbe\xc4i\xf3\xbe\xa45\xdc>\x06'
1244                          b'g\x8d>N!\xae>2Fr\xbe0hb\xbd\xf0we\xbd g\xa0<\xb6\xbe\x9e\xbe\x14\xd1\xc2>PK\x07'
1245                          b'\x08j\xd9\xb9M\x90\x00\x00\x00\x90\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00'
1246                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x007\x00lst'
1247                          b'm/data/1FB3\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ|[\xe1>\xa2Yd\xbe'
1248                          b'\xa5o\t\xbfz\x1c\x05\xbe \xb1\xdb<\xf0\xcd\xfc>\xa2u\xcb>\x8c\x87{\xbe\x9c\x9b'
1249                          b'^>\xacmG>\xae\x17\x93>\x8e\xc5\xf0\xbet\x1c\xfc>\xcb\x84\x81\xbe\xc8\xa6 >\x88\xee'
1250                          b'\xaf=\n\xc9\x8d>\xc0\xc5\xee>\xf0E\x91>\xf4^\xa1>\xb8\xbbF>\x97\x97\xfe\xbe\xec'
1251                          b'\x85\x03?h\x9c\xf3=\xf2\xa8\x97>^\xfa\r?6i\x94\xbe\xbc1w\xbeh\xc4\x8a=\x94\xc8'
1252                          b'\x9f\xbd\x81\xb5\x89\xbe(K\xb0>\xf0:z\xbd\xb0\xc6\x9b\xbdX\x00\x88=\x05\xc7\x11\xbf'
1253                          b'PK\x07\x08\x12\xc0\x87\x96\x90\x00\x00\x00\x90\x00\x00\x00PK\x03\x04\x00\x00\x08'
1254                          b'\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b'
1255                          b'\x007\x00lstm/data/2FB3\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
1256                          b'Z\xb0\xc2f=@\xdd1<\x864\xd8\xbe\xa0\t\x13?+g\x8f\xbeu\xb1\r\xbfbl\xc3>\xa8\\\x82'
1257                          b'\xbe\xa4c\xf3\xbd,\x96\xdf\xbe\xfe\x05\xf1\xbe\xf8\xc9\x96>PK\x07\x08\x92\tK?0\x00'
1258                          b'\x00\x000\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00'
1259                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x17\x00lstm/data/3FB\x13\x00ZZ'
1260                          b'ZZZZZZZZZZZZZZZZZ\x04\xaai\xbe\xce\xd8\x8a\xbe\xe3O\xdf\xbe$\xc3\xd2\xbe\x06\xb1'
1261                          b'\x80\xbe^&\x08?\x00\x1a}\xbd\x06\xde\r?\x04\xe7\xac>Z@\xe9\xbe\x14\xc2)>\x9c\xe9'
1262                          b'/>PK\x07\x08\x1axU\xe80\x00\x00\x000\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00'
1263                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x16\x00'
1264                          b'lstm/versionFB\x12\x00ZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00\x00\x00'
1265                          b'\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xab\xf1'
1266                          b'\xfb\x01\xb8\x01\x00\x00\xb8\x01\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1267                          b'\x00\x00\x00\x00\x00\x00\x00\x00lstm/data.pklPK\x01\x02\x00\x00\x00\x00\x08\x08'
1268                          b'\x00\x00\x00\x00\x00\x00j\xd9\xb9M\x90\x00\x00\x00\x90\x00\x00\x00\x0b\x00\x00\x00'
1269                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x02\x00\x00lstm/data/0PK\x01\x02\x00'
1270                          b'\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x12\xc0\x87\x96\x90\x00\x00\x00\x90'
1271                          b'\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x02\x00'
1272                          b'\x00lstm/data/1PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x92'
1273                          b'\tK?0\x00\x00\x000\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1274                          b'\x00\xe0\x03\x00\x00lstm/data/2PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00'
1275                          b'\x00\x00\x1axU\xe80\x00\x00\x000\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00'
1276                          b'\x00\x00\x00\x00\x00\x80\x04\x00\x00lstm/data/3PK\x01\x02\x00\x00\x00\x00\x08'
1277                          b'\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00\x0c\x00\x00'
1278                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00lstm/versionPK\x06'
1279                          b'\x06,\x00\x00\x00\x00\x00\x00\x00\x1e\x03-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06'
1280                          b'\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00Y\x01\x00\x00\x00\x00'
1281                          b'\x00\x00R\x05\x00\x00\x00\x00\x00\x00PK\x06\x07\x00\x00\x00\x00\xab\x06\x00\x00'
1282                          b'\x00\x00\x00\x00\x01\x00\x00\x00PK\x05\x06\x00\x00\x00\x00\x06\x00\x06\x00Y\x01'
1283                          b'\x00\x00R\x05\x00\x00\x00\x00')
1284
1285        data_le_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1286                       b'\x00\x00\x00\x00\x00\x12\x00\x10\x00lstm.save/data.pklFB\x0c\x00ZZZZZZZZZZZZ\x80'
1287                       b'\x02ccollections\nOrderedDict\nq\x00)Rq\x01(X\x0c\x00\x00\x00weight_ih_l0q\x02ct'
1288                       b'orch._utils\n_rebuild_tensor_v2\nq\x03((X\x07\x00\x00\x00storageq\x04ctorch\nFlo'
1289                       b'atStorage\nq\x05X\x01\x00\x00\x000q\x06X\x03\x00\x00\x00cpuq\x07K$tq\x08QK\x00K\x0c'
1290                       b'K\x03\x86q\tK\x03K\x01\x86q\n\x89h\x00)Rq\x0btq\x0cRq\rX\x0c\x00\x00\x00weigh'
1291                       b't_hh_l0q\x0eh\x03((h\x04h\x05X\x01\x00\x00\x001q\x0fh\x07K$tq\x10QK\x00K\x0cK\x03'
1292                       b'\x86q\x11K\x03K\x01\x86q\x12\x89h\x00)Rq\x13tq\x14Rq\x15X\n\x00\x00\x00bias_ih_'
1293                       b'l0q\x16h\x03((h\x04h\x05X\x01\x00\x00\x002q\x17h\x07K\x0ctq\x18QK\x00K\x0c\x85q\x19'
1294                       b'K\x01\x85q\x1a\x89h\x00)Rq\x1btq\x1cRq\x1dX\n\x00\x00\x00bias_hh_l0q\x1eh\x03'
1295                       b'((h\x04h\x05X\x01\x00\x00\x003q\x1fh\x07K\x0ctq QK\x00K\x0c\x85q!K\x01\x85q"\x89'
1296                       b'h\x00)Rq#tq$Rq%u}q&X\t\x00\x00\x00_metadataq\'h\x00)Rq(X\x00\x00\x00\x00q)}q*X\x07'
1297                       b'\x00\x00\x00versionq+K\x01sssb.PK\x07\x08\xab\xf1\xfb\x01\xb8\x01\x00\x00\xb8\x01'
1298                       b'\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1299                       b'\x00\x00\x00\x00\x00\x00\x00\x13\x00\x07\x00lstm.save/byteorderFB\x03\x00ZZZlit'
1300                       b'tlePK\x07\x08\x85=\xe3\x19\x06\x00\x00\x00\x06\x00\x00\x00PK\x03\x04\x00\x00\x08'
1301                       b'\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10'
1302                       b'\x00<\x00lstm.save/data/0FB8\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
1303                       b'ZZZZZZZZ\nuJ\xbeX*\xa2\xbe\xc4\xea\x10>\xd4\n\x8d\xbe\x1c\x10\x8a\xbe\xb02\xe4\xbe'
1304                       b',\xcb4>\x00\x17!>H\x9c\xe0\xbe\xd2\x15!\xbe6C\xc6>v\xc5\x89>\xae\x14\x81\xbeZ\xc7'
1305                       b'\x99>\x90P\x01?`\xb9\x9a<\xc0 <=\'\xc7\x9e\xbe\xaa\xf4\x02?\x00\xf3\x0e\xbc\xd8'
1306                       b'\xb7v\xbe\xa0\xcc\xcd=$/\xaf>\x00\xc4K=0\xb8\xe5\xbe\xb6\xc5U\xbe\xc4i\xf3\xbe'
1307                       b'\xa45\xdc>\x06g\x8d>N!\xae>2Fr\xbe0hb\xbd\xf0we\xbd g\xa0<\xb6\xbe\x9e\xbe\x14\xd1'
1308                       b'\xc2>PK\x07\x08j\xd9\xb9M\x90\x00\x00\x00\x90\x00\x00\x00PK\x03\x04\x00\x00\x08'
1309                       b'\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10'
1310                       b'\x002\x00lstm.save/data/1FB.\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ|'
1311                       b'[\xe1>\xa2Yd\xbe\xa5o\t\xbfz\x1c\x05\xbe \xb1\xdb<\xf0\xcd\xfc>\xa2u\xcb>\x8c\x87'
1312                       b'{\xbe\x9c\x9b^>\xacmG>\xae\x17\x93>\x8e\xc5\xf0\xbet\x1c\xfc>\xcb\x84\x81\xbe\xc8'
1313                       b'\xa6 >\x88\xee\xaf=\n\xc9\x8d>\xc0\xc5\xee>\xf0E\x91>\xf4^\xa1>\xb8\xbbF>\x97\x97'
1314                       b'\xfe\xbe\xec\x85\x03?h\x9c\xf3=\xf2\xa8\x97>^\xfa\r?6i\x94\xbe\xbc1w\xbeh\xc4'
1315                       b'\x8a=\x94\xc8\x9f\xbd\x81\xb5\x89\xbe(K\xb0>\xf0:z\xbd\xb0\xc6\x9b\xbdX\x00\x88='
1316                       b'\x05\xc7\x11\xbfPK\x07\x08\x12\xc0\x87\x96\x90\x00\x00\x00\x90\x00\x00\x00PK\x03'
1317                       b'\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1318                       b'\x00\x00\x00\x10\x002\x00lstm.save/data/2FB.\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
1319                       b'ZZZZZZZZZZZZZZ\xb0\xc2f=@\xdd1<\x864\xd8\xbe\xa0\t\x13?+g\x8f\xbeu\xb1\r\xbfbl\xc3'
1320                       b'>\xa8\\\x82\xbe\xa4c\xf3\xbd,\x96\xdf\xbe\xfe\x05\xf1\xbe\xf8\xc9\x96>PK\x07\x08'
1321                       b'\x92\tK?0\x00\x00\x000\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00'
1322                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x12\x00lstm.save/'
1323                       b'data/3FB\x0e\x00ZZZZZZZZZZZZZZ\x04\xaai\xbe\xce\xd8\x8a\xbe\xe3O\xdf\xbe$\xc3\xd2'
1324                       b'\xbe\x06\xb1\x80\xbe^&\x08?\x00\x1a}\xbd\x06\xde\r?\x04\xe7\xac>Z@\xe9\xbe\x14\xc2'
1325                       b')>\x9c\xe9/>PK\x07\x08\x1axU\xe80\x00\x00\x000\x00\x00\x00PK\x03\x04\x00\x00\x08'
1326                       b'\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11'
1327                       b'\x00\x11\x00lstm.save/versionFB\r\x00ZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02'
1328                       b'\x00\x00\x00\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00'
1329                       b'\x00\xab\xf1\xfb\x01\xb8\x01\x00\x00\xb8\x01\x00\x00\x12\x00\x00\x00\x00\x00\x00'
1330                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00lstm.save/data.pklPK\x01\x02\x00\x00'
1331                       b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x85=\xe3\x19\x06\x00\x00\x00\x06\x00\x00'
1332                       b'\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x02\x00\x00l'
1333                       b'stm.save/byteorderPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00j\xd9'
1334                       b'\xb9M\x90\x00\x00\x00\x90\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1335                       b'\x00\x00\x00V\x02\x00\x00lstm.save/data/0PK\x01\x02\x00\x00\x00\x00\x08\x08\x00'
1336                       b'\x00\x00\x00\x00\x00\x12\xc0\x87\x96\x90\x00\x00\x00\x90\x00\x00\x00\x10\x00\x00'
1337                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`\x03\x00\x00lstm.save/data/1PK\x01'
1338                       b'\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x92\tK?0\x00\x00\x000\x00\x00'
1339                       b'\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`\x04\x00\x00lstm.'
1340                       b'save/data/2PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x1axU\xe80'
1341                       b'\x00\x00\x000\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1342                       b'\x00\x05\x00\x00lstm.save/data/3PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00'
1343                       b'\x00\x00\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00'
1344                       b'\x00\x00\x00\x00\x00\x00\x00\x80\x05\x00\x00lstm.save/versionPK\x06\x06,\x00\x00'
1345                       b'\x00\x00\x00\x00\x00\x1e\x03-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00'
1346                       b'\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\xb8\x01\x00\x00\x00\x00\x00\x00'
1347                       b'\xd2\x05\x00\x00\x00\x00\x00\x00PK\x06\x07\x00\x00\x00\x00\x8a\x07\x00\x00\x00'
1348                       b'\x00\x00\x00\x01\x00\x00\x00PK\x05\x06\x00\x00\x00\x00\x07\x00\x07\x00\xb8\x01\x00'
1349                       b'\x00\xd2\x05\x00\x00\x00\x00')
1350
1351        data_be_no_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1352                          b'\x00\x00\x00\x00\x00\x12\x00\x10\x00lstm.save/data.pklFB\x0c\x00ZZZZZZZZZZZZ\x80'
1353                          b'\x02ccollections\nOrderedDict\nq\x00)Rq\x01(X\x0c\x00\x00\x00weight_ih_l0q\x02ct'
1354                          b'orch._utils\n_rebuild_tensor_v2\nq\x03((X\x07\x00\x00\x00storageq\x04ctorch\nFlo'
1355                          b'atStorage\nq\x05X\x01\x00\x00\x000q\x06X\x03\x00\x00\x00cpuq\x07K$tq\x08QK\x00K\x0c'
1356                          b'K\x03\x86q\tK\x03K\x01\x86q\n\x89h\x00)Rq\x0btq\x0cRq\rX\x0c\x00\x00\x00weigh'
1357                          b't_hh_l0q\x0eh\x03((h\x04h\x05X\x01\x00\x00\x001q\x0fh\x07K$tq\x10QK\x00K\x0cK\x03'
1358                          b'\x86q\x11K\x03K\x01\x86q\x12\x89h\x00)Rq\x13tq\x14Rq\x15X\n\x00\x00\x00bias_ih_'
1359                          b'l0q\x16h\x03((h\x04h\x05X\x01\x00\x00\x002q\x17h\x07K\x0ctq\x18QK\x00K\x0c\x85q\x19'
1360                          b'K\x01\x85q\x1a\x89h\x00)Rq\x1btq\x1cRq\x1dX\n\x00\x00\x00bias_hh_l0q\x1eh\x03'
1361                          b'((h\x04h\x05X\x01\x00\x00\x003q\x1fh\x07K\x0ctq QK\x00K\x0c\x85q!K\x01\x85q"\x89'
1362                          b'h\x00)Rq#tq$Rq%u}q&X\t\x00\x00\x00_metadataq\'h\x00)Rq(X\x00\x00\x00\x00q)}q*X\x07'
1363                          b'\x00\x00\x00versionq+K\x01sssb.PK\x07\x08\xab\xf1\xfb\x01\xb8\x01\x00\x00\xb8\x01'
1364                          b'\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1365                          b'\x00\x00\x00\x00\x00\x00\x00\x10\x00\n\x00lstm.save/data/0FB\x06\x00ZZZZZZ\xbeJ'
1366                          b'u\n\xbe\xa2*X>\x10\xea\xc4\xbe\x8d\n\xd4\xbe\x8a\x10\x1c\xbe\xe42\xb0>4\xcb,>!\x17'
1367                          b'\x00\xbe\xe0\x9cH\xbe!\x15\xd2>\xc6C6>\x89\xc5v\xbe\x81\x14\xae>\x99\xc7Z?\x01'
1368                          b'P\x90<\x9a\xb9`=< \xc0\xbe\x9e\xc7\'?\x02\xf4\xaa\xbc\x0e\xf3\x00\xbev\xb7\xd8=\xcd'
1369                          b'\xcc\xa0>\xaf/$=K\xc4\x00\xbe\xe5\xb80\xbeU\xc5\xb6\xbe\xf3i\xc4>\xdc5\xa4>\x8d'
1370                          b'g\x06>\xae!N\xberF2\xbdbh0\xbdew\xf0<\xa0g \xbe\x9e\xbe\xb6>\xc2\xd1\x14PK\x07'
1371                          b'\x08\xc2yG\xba\x90\x00\x00\x00\x90\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00'
1372                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x002\x00lst'
1373                          b'm.save/data/1FB.\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ>\xe1[|\xbedY\xa2'
1374                          b'\xbf\to\xa5\xbe\x05\x1cz<\xdb\xb1 >\xfc\xcd\xf0>\xcbu\xa2\xbe{\x87\x8c>^\x9b\x9c'
1375                          b'>Gm\xac>\x93\x17\xae\xbe\xf0\xc5\x8e>\xfc\x1ct\xbe\x81\x84\xcb> \xa6\xc8=\xaf'
1376                          b'\xee\x88>\x8d\xc9\n>\xee\xc5\xc0>\x91E\xf0>\xa1^\xf4>F\xbb\xb8\xbe\xfe\x97\x97?\x03'
1377                          b'\x85\xec=\xf3\x9ch>\x97\xa8\xf2?\r\xfa^\xbe\x94i6\xbew1\xbc=\x8a\xc4h\xbd\x9f'
1378                          b'\xc8\x94\xbe\x89\xb5\x81>\xb0K(\xbdz:\xf0\xbd\x9b\xc6\xb0=\x88\x00X\xbf\x11\xc7\x05'
1379                          b'PK\x07\x08\xd0\xbftD\x90\x00\x00\x00\x90\x00\x00\x00PK\x03\x04\x00\x00\x08\x08'
1380                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00'
1381                          b'2\x00lstm.save/data/2FB.\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ=f\xc2'
1382                          b'\xb0<1\xdd@\xbe\xd84\x86?\x13\t\xa0\xbe\x8fg+\xbf\r\xb1u>\xc3lb\xbe\x82\\\xa8\xbd'
1383                          b'\xf3c\xa4\xbe\xdf\x96,\xbe\xf1\x05\xfe>\x96\xc9\xf8PK\x07\x08"\xc5\xc5O0\x00\x00'
1384                          b'\x000\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1385                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x12\x00lstm.save/data/3FB\x0e\x00Z'
1386                          b'ZZZZZZZZZZZZZ\xbei\xaa\x04\xbe\x8a\xd8\xce\xbe\xdfO\xe3\xbe\xd2\xc3$\xbe\x80\xb1'
1387                          b'\x06?\x08&^\xbd}\x1a\x00?\r\xde\x06>\xac\xe7\x04\xbe\xe9@Z>)\xc2\x14>/\xe9\x9cPK'
1388                          b'\x07\x08\xfb\xfd/\x920\x00\x00\x000\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00'
1389                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x11\x00'
1390                          b'lstm.save/versionFB\r\x00ZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00\x00\x00\x02'
1391                          b'\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xab\xf1'
1392                          b'\xfb\x01\xb8\x01\x00\x00\xb8\x01\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1393                          b'\x00\x00\x00\x00\x00\x00\x00\x00lstm.save/data.pklPK\x01\x02\x00\x00\x00\x00\x08'
1394                          b'\x08\x00\x00\x00\x00\x00\x00\xc2yG\xba\x90\x00\x00\x00\x90\x00\x00\x00\x10\x00\x00'
1395                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x02\x00\x00lstm.save/data/0PK'
1396                          b'\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd0\xbftD\x90\x00\x00\x00'
1397                          b'\x90\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x02'
1398                          b'\x00\x00lstm.save/data/1PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00'
1399                          b'\x00"\xc5\xc5O0\x00\x00\x000\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1400                          b'\x00\x00\x00\x00\xe0\x03\x00\x00lstm.save/data/2PK\x01\x02\x00\x00\x00\x00\x08\x08'
1401                          b'\x00\x00\x00\x00\x00\x00\xfb\xfd/\x920\x00\x00\x000\x00\x00\x00\x10\x00\x00\x00'
1402                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x04\x00\x00lstm.save/data/3PK\x01\x02'
1403                          b'\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00\x00\x02'
1404                          b'\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00'
1405                          b'\x00lstm.save/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00\x1e\x03-\x00\x00\x00'
1406                          b'\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00'
1407                          b'\x00\x00w\x01\x00\x00\x00\x00\x00\x00R\x05\x00\x00\x00\x00\x00\x00PK\x06\x07\x00'
1408                          b'\x00\x00\x00\xc9\x06\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05\x06\x00\x00'
1409                          b'\x00\x00\x06\x00\x06\x00w\x01\x00\x00R\x05\x00\x00\x00\x00')
1410
1411        data_be_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1412                       b'\x00\x00\x00\x00\x00\x12\x00\x10\x00lstm.save/data.pklFB\x0c\x00ZZZZZZZZZZZZ\x80'
1413                       b'\x02ccollections\nOrderedDict\nq\x00)Rq\x01(X\x0c\x00\x00\x00weight_ih_l0q\x02ct'
1414                       b'orch._utils\n_rebuild_tensor_v2\nq\x03((X\x07\x00\x00\x00storageq\x04ctorch\nFlo'
1415                       b'atStorage\nq\x05X\x01\x00\x00\x000q\x06X\x03\x00\x00\x00cpuq\x07K$tq\x08QK\x00K\x0c'
1416                       b'K\x03\x86q\tK\x03K\x01\x86q\n\x89h\x00)Rq\x0btq\x0cRq\rX\x0c\x00\x00\x00weigh'
1417                       b't_hh_l0q\x0eh\x03((h\x04h\x05X\x01\x00\x00\x001q\x0fh\x07K$tq\x10QK\x00K\x0cK\x03'
1418                       b'\x86q\x11K\x03K\x01\x86q\x12\x89h\x00)Rq\x13tq\x14Rq\x15X\n\x00\x00\x00bias_ih_'
1419                       b'l0q\x16h\x03((h\x04h\x05X\x01\x00\x00\x002q\x17h\x07K\x0ctq\x18QK\x00K\x0c\x85q\x19'
1420                       b'K\x01\x85q\x1a\x89h\x00)Rq\x1btq\x1cRq\x1dX\n\x00\x00\x00bias_hh_l0q\x1eh\x03'
1421                       b'((h\x04h\x05X\x01\x00\x00\x003q\x1fh\x07K\x0ctq QK\x00K\x0c\x85q!K\x01\x85q"\x89'
1422                       b'h\x00)Rq#tq$Rq%u}q&X\t\x00\x00\x00_metadataq\'h\x00)Rq(X\x00\x00\x00\x00q)}q*X\x07'
1423                       b'\x00\x00\x00versionq+K\x01sssb.PK\x07\x08\xab\xf1\xfb\x01\xb8\x01\x00\x00\xb8\x01'
1424                       b'\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1425                       b'\x00\x00\x00\x00\x00\x00\x00\x13\x00\x07\x00lstm.save/byteorderFB\x03\x00ZZZbig'
1426                       b'PK\x07\x08I\xe2\xfb\xd3\x03\x00\x00\x00\x03\x00\x00\x00PK\x03\x04\x00\x00\x08\x08'
1427                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00'
1428                       b'?\x00lstm.save/data/0FB;\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
1429                       b'ZZZZZZZZ\xbeJu\n\xbe\xa2*X>\x10\xea\xc4\xbe\x8d\n\xd4\xbe\x8a\x10\x1c\xbe\xe42\xb0'
1430                       b'>4\xcb,>!\x17\x00\xbe\xe0\x9cH\xbe!\x15\xd2>\xc6C6>\x89\xc5v\xbe\x81\x14\xae>\x99'
1431                       b'\xc7Z?\x01P\x90<\x9a\xb9`=< \xc0\xbe\x9e\xc7\'?\x02\xf4\xaa\xbc\x0e\xf3\x00\xbe'
1432                       b'v\xb7\xd8=\xcd\xcc\xa0>\xaf/$=K\xc4\x00\xbe\xe5\xb80\xbeU\xc5\xb6\xbe\xf3i\xc4'
1433                       b'>\xdc5\xa4>\x8dg\x06>\xae!N\xberF2\xbdbh0\xbdew\xf0<\xa0g \xbe\x9e\xbe\xb6>\xc2\xd1'
1434                       b'\x14PK\x07\x08\xc2yG\xba\x90\x00\x00\x00\x90\x00\x00\x00PK\x03\x04\x00\x00\x08'
1435                       b'\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10'
1436                       b'\x002\x00lstm.save/data/1FB.\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ>'
1437                       b'\xe1[|\xbedY\xa2\xbf\to\xa5\xbe\x05\x1cz<\xdb\xb1 >\xfc\xcd\xf0>\xcbu\xa2\xbe{\x87'
1438                       b'\x8c>^\x9b\x9c>Gm\xac>\x93\x17\xae\xbe\xf0\xc5\x8e>\xfc\x1ct\xbe\x81\x84\xcb> '
1439                       b'\xa6\xc8=\xaf\xee\x88>\x8d\xc9\n>\xee\xc5\xc0>\x91E\xf0>\xa1^\xf4>F\xbb\xb8\xbe\xfe'
1440                       b'\x97\x97?\x03\x85\xec=\xf3\x9ch>\x97\xa8\xf2?\r\xfa^\xbe\x94i6\xbew1\xbc=\x8a'
1441                       b'\xc4h\xbd\x9f\xc8\x94\xbe\x89\xb5\x81>\xb0K(\xbdz:\xf0\xbd\x9b\xc6\xb0=\x88\x00X'
1442                       b'\xbf\x11\xc7\x05PK\x07\x08\xd0\xbftD\x90\x00\x00\x00\x90\x00\x00\x00PK\x03\x04\x00'
1443                       b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1444                       b'\x00\x10\x002\x00lstm.save/data/2FB.\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
1445                       b'ZZZZZZZZ=f\xc2\xb0<1\xdd@\xbe\xd84\x86?\x13\t\xa0\xbe\x8fg+\xbf\r\xb1u>\xc3lb\xbe'
1446                       b'\x82\\\xa8\xbd\xf3c\xa4\xbe\xdf\x96,\xbe\xf1\x05\xfe>\x96\xc9\xf8PK\x07\x08"\xc5'
1447                       b'\xc5O0\x00\x00\x000\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00'
1448                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x12\x00lstm.save/data'
1449                       b'/3FB\x0e\x00ZZZZZZZZZZZZZZ\xbei\xaa\x04\xbe\x8a\xd8\xce\xbe\xdfO\xe3\xbe\xd2\xc3'
1450                       b'$\xbe\x80\xb1\x06?\x08&^\xbd}\x1a\x00?\r\xde\x06>\xac\xe7\x04\xbe\xe9@Z>)\xc2\x14'
1451                       b'>/\xe9\x9cPK\x07\x08\xfb\xfd/\x920\x00\x00\x000\x00\x00\x00PK\x03\x04\x00\x00\x08'
1452                       b'\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11'
1453                       b'\x00\x11\x00lstm.save/versionFB\r\x00ZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00'
1454                       b'\x00\x00\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00'
1455                       b'\x00\xab\xf1\xfb\x01\xb8\x01\x00\x00\xb8\x01\x00\x00\x12\x00\x00\x00\x00\x00\x00'
1456                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00lstm.save/data.pklPK\x01\x02\x00\x00'
1457                       b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00I\xe2\xfb\xd3\x03\x00\x00\x00\x03\x00\x00'
1458                       b'\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x02\x00\x00ls'
1459                       b'tm.save/byteorderPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xc2y'
1460                       b'G\xba\x90\x00\x00\x00\x90\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1461                       b'\x00\x00\x00S\x02\x00\x00lstm.save/data/0PK\x01\x02\x00\x00\x00\x00\x08\x08\x00'
1462                       b'\x00\x00\x00\x00\x00\xd0\xbftD\x90\x00\x00\x00\x90\x00\x00\x00\x10\x00\x00\x00\x00'
1463                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00`\x03\x00\x00lstm.save/data/1PK\x01\x02\x00'
1464                       b'\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00"\xc5\xc5O0\x00\x00\x000\x00\x00\x00'
1465                       b'\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`\x04\x00\x00lstm.save/'
1466                       b'data/2PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xfb\xfd/\x920\x00'
1467                       b'\x00\x000\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1468                       b'\x05\x00\x00lstm.save/data/3PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00'
1469                       b'\x00\x00\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00'
1470                       b'\x00\x00\x00\x00\x00\x00\x80\x05\x00\x00lstm.save/versionPK\x06\x06,\x00\x00\x00'
1471                       b'\x00\x00\x00\x00\x1e\x03-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00'
1472                       b'\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\xb8\x01\x00\x00\x00\x00\x00\x00'
1473                       b'\xd2\x05\x00\x00\x00\x00\x00\x00PK\x06\x07\x00\x00\x00\x00\x8a\x07\x00\x00\x00\x00'
1474                       b'\x00\x00\x01\x00\x00\x00PK\x05\x06\x00\x00\x00\x00\x07\x00\x07\x00\xb8\x01\x00'
1475                       b'\x00\xd2\x05\x00\x00\x00\x00')
1476
1477        current_load_endian = get_default_load_endianness()
1478
1479        buf_le_no_bom = io.BytesIO(data_le_no_bom)
1480        buf_le_bom = io.BytesIO(data_le_bom)
1481        buf_be_no_bom = io.BytesIO(data_be_no_bom)
1482        buf_be_bom = io.BytesIO(data_be_bom)
1483
1484        lstm_le_no_bom = torch.nn.LSTM(3, 3)
1485        lstm_le_bom = torch.nn.LSTM(3, 3)
1486        lstm_be_no_bom = torch.nn.LSTM(3, 3)
1487        lstm_be_bom = torch.nn.LSTM(3, 3)
1488
1489        lstm_le_no_bom_little = torch.nn.LSTM(3, 3)
1490        lstm_be_no_bom_little = torch.nn.LSTM(3, 3)
1491        lstm_le_no_bom_big = torch.nn.LSTM(3, 3)
1492        lstm_be_no_bom_big = torch.nn.LSTM(3, 3)
1493
1494        try:
1495            set_default_load_endianness(LoadEndianness.NATIVE)
1496            lstm_le_no_bom.load_state_dict(torch.load(buf_le_no_bom), strict=True)
1497            lstm_be_no_bom.load_state_dict(torch.load(buf_be_no_bom), strict=True)
1498        finally:
1499            set_default_load_endianness(current_load_endian)
1500
1501        lstm_le_bom.load_state_dict(torch.load(buf_le_bom), strict=True)
1502        lstm_be_bom.load_state_dict(torch.load(buf_be_bom), strict=True)
1503
1504        buf_le_no_bom.seek(0)
1505        buf_be_no_bom.seek(0)
1506
1507        try:
1508            set_default_load_endianness(LoadEndianness.LITTLE)
1509            lstm_le_no_bom_little.load_state_dict(torch.load(buf_le_no_bom), strict=True)
1510            lstm_be_no_bom_little.load_state_dict(torch.load(buf_be_no_bom), strict=True)
1511        finally:
1512            set_default_load_endianness(current_load_endian)
1513
1514        buf_le_no_bom.seek(0)
1515        buf_be_no_bom.seek(0)
1516
1517        try:
1518            set_default_load_endianness(LoadEndianness.BIG)
1519            lstm_le_no_bom_big.load_state_dict(torch.load(buf_le_no_bom), strict=True)
1520            lstm_be_no_bom_big.load_state_dict(torch.load(buf_be_no_bom), strict=True)
1521        finally:
1522            set_default_load_endianness(current_load_endian)
1523
1524        self.assertEqual(lstm_le_bom.state_dict(), lstm_be_bom.state_dict())
1525        self.assertNotEqual(lstm_le_no_bom.state_dict(), lstm_be_no_bom.state_dict())
1526        self.assertEqual(lstm_le_no_bom_little.state_dict(), lstm_le_bom.state_dict())
1527        self.assertNotEqual(lstm_be_no_bom_little.state_dict(), lstm_be_bom.state_dict())
1528        self.assertNotEqual(lstm_le_no_bom_big.state_dict(), lstm_le_bom.state_dict())
1529        self.assertEqual(lstm_be_no_bom_big.state_dict(), lstm_be_bom.state_dict())
1530
1531        if (sys.byteorder == 'little'):
1532            self.assertEqual(lstm_le_no_bom.state_dict(), lstm_le_bom.state_dict())
1533            self.assertEqual(lstm_le_no_bom.state_dict(), lstm_be_bom.state_dict())
1534            self.assertNotEqual(lstm_be_no_bom.state_dict(), lstm_le_bom.state_dict())
1535            self.assertNotEqual(lstm_be_no_bom.state_dict(), lstm_be_bom.state_dict())
1536        else:
1537            self.assertNotEqual(lstm_le_no_bom.state_dict(), lstm_le_bom.state_dict())
1538            self.assertNotEqual(lstm_le_no_bom.state_dict(), lstm_be_bom.state_dict())
1539            self.assertEqual(lstm_be_no_bom.state_dict(), lstm_le_bom.state_dict())
1540            self.assertEqual(lstm_be_no_bom.state_dict(), lstm_be_bom.state_dict())
1541
1542    def test_serialization_load_bom_data_double(self):
1543        # 1. Generated on LE system using following commands:
1544        #
1545        # import torch
1546        #
1547        # x = torch.randn(2,2, dtype=torch.double)
1548        #
1549        # torch.save(x, "tensor.double.LE.pt", _disable_byteorder_record=True)
1550        # torch.save(x, "tensor.double.LE.BOM.pt")
1551        #
1552        # print(x)
1553        #
1554        # 2. After that it is resaved on BE system with following commands:
1555        #
1556        # import torch
1557        #
1558        # x = torch.load('tensor.double.LE.BOM.pt')
1559        #
1560        # torch.save(x, 'tensor.double.BE.pt', _disable_byteorder_record=True)
1561        # torch.save(x, 'tensor.double.BE.BOM.pt')
1562        #
1563        # print(x)
1564        #
1565        # Following commands and a bit of manual work were used to produce python bytes from resulting files:
1566        #
1567        # file = open('filename', 'rb')
1568        # data = file.read()
1569        # file.close()
1570        # print("\n".join(textwrap.wrap(str(data), 80)))
1571        #
1572        # BOM in this context is used as Byte Order Mark.
1573        #
1574        data_le_no_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1575                          b'\x00\x00\x00\x00\x00\x19\x00\t\x00tensor.double.LE/data.pklFB\x05\x00ZZZZZ\x80\x02'
1576                          b'ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorch\n'
1577                          b'DoubleStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x04tq\x05'
1578                          b'QK\x00K\x02K\x02\x86q\x06K\x02K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08'
1579                          b')Rq\ttq\nRq\x0b.PK\x07\x08S\xd3\xba&\x9b\x00\x00\x00\x9b\x00\x00\x00PK\x03\x04\x00'
1580                          b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1581                          b'\x00\x17\x00 \x00tensor.double.LE/data/0FB\x1c\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
1582                          b'\x97v\xa4\xff|^\xc9?\xce\xbc\x8cP\x8d\xb0\xe9\xbf\xdc\x0e\xef[\xb7\xdb\xd3\xbf4\xb1'
1583                          b'\x08Q\xf9\x00\xde?PK\x07\x08\xae\x92t\x0f \x00\x00\x00 \x00\x00\x00PK\x03\x04'
1584                          b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1585                          b'\x00\x00\x18\x00\x1a\x00tensor.double.LE/versionFB\x16\x00ZZZZZZZZZZZZZZZZZZZZZZ'
1586                          b'3\nPK\x07\x08\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00'
1587                          b'\x08\x08\x00\x00\x00\x00\x00\x00S\xd3\xba&\x9b\x00\x00\x00\x9b\x00\x00\x00\x19\x00'
1588                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00tensor.double'
1589                          b'.LE/data.pklPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xae\x92t\x0f'
1590                          b' \x00\x00\x00 \x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1591                          b'\x00\xeb\x00\x00\x00tensor.double.LE/data/0PK\x01\x02\x00\x00\x00\x00\x08\x08\x00'
1592                          b'\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00\x18\x00\x00\x00'
1593                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\x01\x00\x00tensor.double.LE/versionPK\x06'
1594                          b'\x06,\x00\x00\x00\x00\x00\x00\x00\x1e\x03-\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1595                          b'\x03\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\xd2\x00\x00\x00'
1596                          b'\x00\x00\x00\x00\xd2\x01\x00\x00\x00\x00\x00\x00PK\x06\x07\x00\x00\x00\x00\xa4\x02'
1597                          b'\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05\x06\x00\x00\x00\x00\x03\x00\x03'
1598                          b'\x00\xd2\x00\x00\x00\xd2\x01\x00\x00\x00\x00')
1599
1600        data_le_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1601                       b'\x00\x00\x00\x00\x00\x1d\x00\x05\x00tensor.double.LE.BOM/data.pklFB\x01\x00Z\x80'
1602                       b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
1603                       b'h\nDoubleStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x04tq\x05'
1604                       b'QK\x00K\x02K\x02\x86q\x06K\x02K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08'
1605                       b')Rq\ttq\nRq\x0b.PK\x07\x08S\xd3\xba&\x9b\x00\x00\x00\x9b\x00\x00\x00PK\x03\x04'
1606                       b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1607                       b'\x00\x00\x1e\x00\x19\x00tensor.double.LE.BOM/byteorderFB\x15\x00ZZZZZZZZZZZZZZZZ'
1608                       b'ZZZZZlittlePK\x07\x08\x85=\xe3\x19\x06\x00\x00\x00\x06\x00\x00\x00PK\x03\x04\x00'
1609                       b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1610                       b'\x00\x1b\x001\x00tensor.double.LE.BOM/data/0FB-\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
1611                       b'ZZZZZZZZZZZZZZZZ\x97v\xa4\xff|^\xc9?\xce\xbc\x8cP\x8d\xb0\xe9\xbf\xdc\x0e\xef[\xb7'
1612                       b'\xdb\xd3\xbf4\xb1\x08Q\xf9\x00\xde?PK\x07\x08\xae\x92t\x0f \x00\x00\x00 \x00\x00'
1613                       b'\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1614                       b'\x00\x00\x00\x00\x00\x00\x1c\x00\x16\x00tensor.double.LE.BOM/versionFB\x12\x00ZZ'
1615                       b'ZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00PK\x01\x02'
1616                       b'\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00S\xd3\xba&\x9b\x00\x00\x00\x9b\x00'
1617                       b'\x00\x00\x1d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1618                       b'tensor.double.LE.BOM/data.pklPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00'
1619                       b'\x00\x00\x85=\xe3\x19\x06\x00\x00\x00\x06\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x00'
1620                       b'\x00\x00\x00\x00\x00\x00\x00\xeb\x00\x00\x00tensor.double.LE.BOM/byteorderPK\x01'
1621                       b'\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xae\x92t\x0f '
1622                       b'\x00\x00\x00 \x00\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1623                       b'V\x01\x00\x00tensor.double.LE.BOM/data/0PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00'
1624                       b'\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00\x1c\x00\x00\x00\x00'
1625                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x01\x00\x00tensor.double.LE.BOM/versio'
1626                       b'nPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00\x1e\x03-\x00\x00\x00\x00\x00\x00\x00\x00'
1627                       b'\x00\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00*\x01\x00\x00'
1628                       b'\x00\x00\x00\x00R\x02\x00\x00\x00\x00\x00\x00PK\x06\x07\x00\x00\x00\x00|\x03\x00'
1629                       b'\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05\x06\x00\x00\x00\x00\x04\x00\x04\x00'
1630                       b'*\x01\x00\x00R\x02\x00\x00\x00\x00')
1631
1632        data_be_no_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1633                          b'\x00\x00\x00\x00\x00\x19\x00\t\x00tensor.double.BE/data.pklFB\x05\x00ZZZZZ\x80\x02'
1634                          b'ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorch\n'
1635                          b'DoubleStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x04tq\x05'
1636                          b'QK\x00K\x02K\x02\x86q\x06K\x02K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08'
1637                          b')Rq\ttq\nRq\x0b.PK\x07\x08S\xd3\xba&\x9b\x00\x00\x00\x9b\x00\x00\x00PK\x03\x04\x00'
1638                          b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1639                          b'\x00\x17\x00 \x00tensor.double.BE/data/0FB\x1c\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
1640                          b'?\xc9^|\xff\xa4v\x97\xbf\xe9\xb0\x8dP\x8c\xbc\xce\xbf\xd3\xdb\xb7[\xef\x0e\xdc?\xde'
1641                          b'\x00\xf9Q\x08\xb14PK\x07\x083@\x82/ \x00\x00\x00 \x00\x00\x00PK\x03\x04\x00\x00'
1642                          b'\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1643                          b'\x18\x00\x1a\x00tensor.double.BE/versionFB\x16\x00ZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07'
1644                          b'\x08\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08'
1645                          b'\x00\x00\x00\x00\x00\x00S\xd3\xba&\x9b\x00\x00\x00\x9b\x00\x00\x00\x19\x00\x00'
1646                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00tensor.double.BE/da'
1647                          b'ta.pklPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x003@\x82/ '
1648                          b'\x00\x00\x00 \x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1649                          b'\xeb\x00\x00\x00tensor.double.BE/data/0PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00'
1650                          b'\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00\x18\x00\x00\x00\x00'
1651                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00p\x01\x00\x00tensor.double.BE/versionPK\x06\x06'
1652                          b',\x00\x00\x00\x00\x00\x00\x00\x1e\x03-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03'
1653                          b'\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\xd2\x00\x00\x00\x00'
1654                          b'\x00\x00\x00\xd2\x01\x00\x00\x00\x00\x00\x00PK\x06\x07\x00\x00\x00\x00\xa4\x02\x00'
1655                          b'\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05\x06\x00\x00\x00\x00\x03\x00\x03\x00'
1656                          b'\xd2\x00\x00\x00\xd2\x01\x00\x00\x00\x00')
1657
1658        data_be_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1659                       b'\x00\x00\x00\x00\x00\x1d\x00\x05\x00tensor.double.BE.BOM/data.pklFB\x01\x00Z\x80'
1660                       b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
1661                       b'h\nDoubleStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x04tq\x05'
1662                       b'QK\x00K\x02K\x02\x86q\x06K\x02K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08'
1663                       b')Rq\ttq\nRq\x0b.PK\x07\x08S\xd3\xba&\x9b\x00\x00\x00\x9b\x00\x00\x00PK\x03\x04'
1664                       b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1665                       b'\x00\x00\x1e\x00\x19\x00tensor.double.BE.BOM/byteorderFB\x15\x00ZZZZZZZZZZZZZZZZ'
1666                       b'ZZZZZbigPK\x07\x08I\xe2\xfb\xd3\x03\x00\x00\x00\x03\x00\x00\x00PK\x03\x04\x00\x00'
1667                       b'\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1668                       b'\x1b\x004\x00tensor.double.BE.BOM/data/0FB0\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
1669                       b'ZZZZZZZZZZZZZZZZ?\xc9^|\xff\xa4v\x97\xbf\xe9\xb0\x8dP\x8c\xbc\xce\xbf\xd3\xdb\xb7'
1670                       b'[\xef\x0e\xdc?\xde\x00\xf9Q\x08\xb14PK\x07\x083@\x82/ \x00\x00\x00 \x00\x00\x00'
1671                       b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1672                       b'\x00\x00\x00\x00\x1c\x00\x16\x00tensor.double.BE.BOM/versionFB\x12\x00ZZZZZZZZ'
1673                       b'ZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00PK\x01\x02\x00\x00'
1674                       b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00S\xd3\xba&\x9b\x00\x00\x00\x9b\x00\x00'
1675                       b'\x00\x1d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ten'
1676                       b'sor.double.BE.BOM/data.pklPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00'
1677                       b'\x00I\xe2\xfb\xd3\x03\x00\x00\x00\x03\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00'
1678                       b'\x00\x00\x00\x00\x00\x00\xeb\x00\x00\x00tensor.double.BE.BOM/byteorderPK\x01\x02'
1679                       b'\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x003@\x82/ \x00\x00\x00 \x00\x00\x00'
1680                       b'\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\x01\x00\x00tensor.do'
1681                       b'uble.BE.BOM/data/0PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1'
1682                       b'\x9egU\x02\x00\x00\x00\x02\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1683                       b'\x00\x00\x00\xf0\x01\x00\x00tensor.double.BE.BOM/versionPK\x06\x06,\x00\x00\x00'
1684                       b'\x00\x00\x00\x00\x1e\x03-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00'
1685                       b'\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00*\x01\x00\x00\x00\x00\x00\x00R\x02'
1686                       b'\x00\x00\x00\x00\x00\x00PK\x06\x07\x00\x00\x00\x00|\x03\x00\x00\x00\x00\x00\x00\x01'
1687                       b'\x00\x00\x00PK\x05\x06\x00\x00\x00\x00\x04\x00\x04\x00*\x01\x00\x00R\x02\x00\x00'
1688                       b'\x00\x00')
1689
1690        current_load_endian = get_default_load_endianness()
1691
1692        buf_le_no_bom = io.BytesIO(data_le_no_bom)
1693        buf_le_bom = io.BytesIO(data_le_bom)
1694        buf_be_no_bom = io.BytesIO(data_be_no_bom)
1695        buf_be_bom = io.BytesIO(data_be_bom)
1696
1697        try:
1698            set_default_load_endianness(LoadEndianness.NATIVE)
1699            tensor_le_no_bom = torch.load(buf_le_no_bom)
1700            tensor_be_no_bom = torch.load(buf_be_no_bom)
1701        finally:
1702            set_default_load_endianness(current_load_endian)
1703
1704        tensor_le_bom = torch.load(buf_le_bom)
1705        tensor_be_bom = torch.load(buf_be_bom)
1706
1707        buf_le_no_bom.seek(0)
1708        buf_be_no_bom.seek(0)
1709
1710        try:
1711            set_default_load_endianness(LoadEndianness.LITTLE)
1712            tensor_le_no_bom_little = torch.load(buf_le_no_bom)
1713            tensor_be_no_bom_little = torch.load(buf_be_no_bom)
1714        finally:
1715            set_default_load_endianness(current_load_endian)
1716
1717        buf_le_no_bom.seek(0)
1718        buf_be_no_bom.seek(0)
1719
1720        try:
1721            set_default_load_endianness(LoadEndianness.BIG)
1722            tensor_le_no_bom_big = torch.load(buf_le_no_bom)
1723            tensor_be_no_bom_big = torch.load(buf_be_no_bom)
1724        finally:
1725            set_default_load_endianness(current_load_endian)
1726
1727        self.assertTrue(torch.equal(tensor_le_bom, tensor_be_bom))
1728        self.assertFalse(torch.equal(tensor_le_no_bom, tensor_be_no_bom))
1729        self.assertTrue(torch.equal(tensor_le_no_bom_little, tensor_le_bom))
1730        self.assertFalse(torch.equal(tensor_be_no_bom_little, tensor_be_bom))
1731        self.assertFalse(torch.equal(tensor_le_no_bom_big, tensor_le_bom))
1732        self.assertTrue(torch.equal(tensor_be_no_bom_big, tensor_be_bom))
1733
1734        if (sys.byteorder == 'little'):
1735            self.assertTrue(torch.equal(tensor_le_no_bom, tensor_le_bom))
1736            self.assertTrue(torch.equal(tensor_le_no_bom, tensor_be_bom))
1737            self.assertFalse(torch.equal(tensor_be_no_bom, tensor_le_bom))
1738            self.assertFalse(torch.equal(tensor_be_no_bom, tensor_be_bom))
1739        else:
1740            self.assertFalse(torch.equal(tensor_le_no_bom, tensor_le_bom))
1741            self.assertFalse(torch.equal(tensor_le_no_bom, tensor_be_bom))
1742            self.assertTrue(torch.equal(tensor_be_no_bom, tensor_le_bom))
1743            self.assertTrue(torch.equal(tensor_be_no_bom, tensor_be_bom))
1744
1745    def test_serialization_load_bom_data_float(self):
1746        # 1. Generated on LE system using following commands:
1747        #
1748        # import torch
1749        #
1750        # x = torch.randn(2,2, dtype=torch.float)
1751        #
1752        # torch.save(x, "tensor.float.LE.pt", _disable_byteorder_record=True)
1753        # torch.save(x, "tensor.float.LE.BOM.pt")
1754        #
1755        # print(x)
1756        #
1757        # 2. After that it is resaved on BE system with following commands:
1758        #
1759        # import torch
1760        #
1761        # x = torch.load('tensor.float.LE.BOM.pt')
1762        #
1763        # torch.save(x, 'tensor.float.BE.pt', _disable_byteorder_record=True)
1764        # torch.save(x, 'tensor.float.BE.BOM.pt')
1765        #
1766        # print(x)
1767        #
1768        # Following commands and a bit of manual work were used to produce python bytes from resulting files:
1769        #
1770        # file = open('filename', 'rb')
1771        # data = file.read()
1772        # file.close()
1773        # print("\n".join(textwrap.wrap(str(data), 80)))
1774        #
1775        # BOM in this context is used as Byte Order Mark.
1776        #
1777        data_le_no_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1778                          b'\x00\x00\x00\x00\x00\x18\x00\n\x00tensor.float.LE/data.pklFB\x06\x00ZZZZZZ\x80\x02'
1779                          b'ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorch\n'
1780                          b'FloatStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x04tq\x05Q'
1781                          b'K\x00K\x02K\x02\x86q\x06K\x02K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08)'
1782                          b'Rq\ttq\nRq\x0b.PK\x07\x08%Y"N\x9a\x00\x00\x00\x9a\x00\x00\x00PK\x03\x04\x00\x00\x08'
1783                          b'\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16'
1784                          b'\x00"\x00tensor.float.LE/data/0FB\x1e\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ\x01h\x9e'
1785                          b'?\r\xb7A?\x1a\x1e\x07\xbf\xd4|\x02?PK\x07\x08\x8fq]\x8c\x10\x00\x00\x00\x10\x00'
1786                          b'\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1787                          b'\x00\x00\x00\x00\x00\x00\x00\x17\x00+\x00tensor.float.LE/versionFB\'\x00ZZZZZZZZ'
1788                          b'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00'
1789                          b'\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00%Y"N\x9a\x00\x00'
1790                          b'\x00\x9a\x00\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1791                          b'\x00\x00\x00tensor.float.LE/data.pklPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00'
1792                          b'\x00\x00\x00\x8fq]\x8c\x10\x00\x00\x00\x10\x00\x00\x00\x16\x00\x00\x00\x00\x00'
1793                          b'\x00\x00\x00\x00\x00\x00\x00\x00\xea\x00\x00\x00tensor.float.LE/data/0PK\x01\x02'
1794                          b'\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00\x00\x02\x00'
1795                          b'\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`\x01\x00\x00t'
1796                          b'ensor.float.LE/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00\x1e\x03-\x00\x00\x00'
1797                          b'\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00'
1798                          b'\x00\x00\xcf\x00\x00\x00\x00\x00\x00\x00\xd2\x01\x00\x00\x00\x00\x00\x00PK\x06'
1799                          b'\x07\x00\x00\x00\x00\xa1\x02\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05\x06\x00'
1800                          b'\x00\x00\x00\x03\x00\x03\x00\xcf\x00\x00\x00\xd2\x01\x00\x00\x00\x00')
1801
1802        data_le_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1803                       b'\x00\x00\x00\x00\x00\x1c\x00\x06\x00tensor.float.LE.BOM/data.pklFB\x02\x00ZZ\x80'
1804                       b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
1805                       b'h\nFloatStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x04tq\x05'
1806                       b'QK\x00K\x02K\x02\x86q\x06K\x02K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08'
1807                       b')Rq\ttq\nRq\x0b.PK\x07\x08%Y"N\x9a\x00\x00\x00\x9a\x00\x00\x00PK\x03\x04\x00\x00'
1808                       b'\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1809                       b'\x1d\x00\x1b\x00tensor.float.LE.BOM/byteorderFB\x17\x00ZZZZZZZZZZZZZZZZZZZZZZZl'
1810                       b'ittlePK\x07\x08\x85=\xe3\x19\x06\x00\x00\x00\x06\x00\x00\x00PK\x03\x04\x00\x00\x08'
1811                       b'\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1a'
1812                       b'\x002\x00tensor.float.LE.BOM/data/0FB.\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
1813                       b'ZZZZZZZZZZ\x01h\x9e?\r\xb7A?\x1a\x1e\x07\xbf\xd4|\x02?PK\x07\x08\x8fq]\x8c\x10\x00'
1814                       b'\x00\x00\x10\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00'
1815                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\x00\'\x00tensor.float.LE.BOM/ve'
1816                       b'rsionFB#\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00\x00'
1817                       b'\x00\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00'
1818                       b'%Y"N\x9a\x00\x00\x00\x9a\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1819                       b'\x00\x00\x00\x00\x00\x00\x00tensor.float.LE.BOM/data.pklPK\x01\x02\x00\x00\x00\x00'
1820                       b'\x08\x08\x00\x00\x00\x00\x00\x00\x85=\xe3\x19\x06\x00\x00\x00\x06\x00\x00\x00\x1d'
1821                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xea\x00\x00\x00tensor.fl'
1822                       b'oat.LE.BOM/byteorderPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x8f'
1823                       b'q]\x8c\x10\x00\x00\x00\x10\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1824                       b'\x00\x00\x00\x00V\x01\x00\x00tensor.float.LE.BOM/data/0PK\x01\x02\x00\x00\x00\x00'
1825                       b'\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00\x1b\x00'
1826                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x01\x00\x00tensor.float.'
1827                       b'LE.BOM/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00\x1e\x03-\x00\x00\x00\x00\x00'
1828                       b'\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00'
1829                       b'&\x01\x00\x00\x00\x00\x00\x00R\x02\x00\x00\x00\x00\x00\x00PK\x06\x07\x00\x00\x00'
1830                       b'\x00x\x03\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05\x06\x00\x00\x00\x00\x04'
1831                       b'\x00\x04\x00&\x01\x00\x00R\x02\x00\x00\x00\x00')
1832
1833        data_be_no_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1834                          b'\x00\x00\x00\x00\x00\x18\x00\n\x00tensor.float.BE/data.pklFB\x06\x00ZZZZZZ\x80\x02'
1835                          b'ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorch\n'
1836                          b'FloatStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x04tq\x05Q'
1837                          b'K\x00K\x02K\x02\x86q\x06K\x02K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08)'
1838                          b'Rq\ttq\nRq\x0b.PK\x07\x08%Y"N\x9a\x00\x00\x00\x9a\x00\x00\x00PK\x03\x04\x00\x00\x08'
1839                          b'\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16'
1840                          b'\x00"\x00tensor.float.BE/data/0FB\x1e\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ?\x9eh'
1841                          b'\x01?A\xb7\r\xbf\x07\x1e\x1a?\x02|\xd4PK\x07\x089D\xd6\x8a\x10\x00\x00\x00\x10\x00'
1842                          b'\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1843                          b'\x00\x00\x00\x00\x00\x00\x00\x17\x00+\x00tensor.float.BE/versionFB\'\x00ZZZZZZZZ'
1844                          b'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00'
1845                          b'\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00%Y"N\x9a\x00\x00'
1846                          b'\x00\x9a\x00\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1847                          b'\x00\x00\x00tensor.float.BE/data.pklPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00'
1848                          b'\x00\x00\x009D\xd6\x8a\x10\x00\x00\x00\x10\x00\x00\x00\x16\x00\x00\x00\x00\x00'
1849                          b'\x00\x00\x00\x00\x00\x00\x00\x00\xea\x00\x00\x00tensor.float.BE/data/0PK\x01\x02'
1850                          b'\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00\x00\x02\x00'
1851                          b'\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`\x01\x00\x00t'
1852                          b'ensor.float.BE/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00\x1e\x03-\x00\x00\x00'
1853                          b'\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00'
1854                          b'\x00\x00\xcf\x00\x00\x00\x00\x00\x00\x00\xd2\x01\x00\x00\x00\x00\x00\x00PK\x06'
1855                          b'\x07\x00\x00\x00\x00\xa1\x02\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05\x06\x00'
1856                          b'\x00\x00\x00\x03\x00\x03\x00\xcf\x00\x00\x00\xd2\x01\x00\x00\x00\x00')
1857
1858        data_be_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1859                       b'\x00\x00\x00\x00\x00\x1c\x00\x06\x00tensor.float.BE.BOM/data.pklFB\x02\x00ZZ\x80'
1860                       b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
1861                       b'h\nFloatStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x04tq\x05'
1862                       b'QK\x00K\x02K\x02\x86q\x06K\x02K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08'
1863                       b')Rq\ttq\nRq\x0b.PK\x07\x08%Y"N\x9a\x00\x00\x00\x9a\x00\x00\x00PK\x03\x04\x00\x00'
1864                       b'\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1865                       b'\x1d\x00\x1b\x00tensor.float.BE.BOM/byteorderFB\x17\x00ZZZZZZZZZZZZZZZZZZZZZZZb'
1866                       b'igPK\x07\x08I\xe2\xfb\xd3\x03\x00\x00\x00\x03\x00\x00\x00PK\x03\x04\x00\x00\x08\x08'
1867                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1a\x00'
1868                       b'5\x00tensor.float.BE.BOM/data/0FB1\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
1869                       b'ZZZZZZZZZZ?\x9eh\x01?A\xb7\r\xbf\x07\x1e\x1a?\x02|\xd4PK\x07\x089D\xd6\x8a\x10\x00'
1870                       b'\x00\x00\x10\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00'
1871                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\x00\'\x00tensor.float.BE.BOM/ve'
1872                       b'rsionFB#\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00\x00'
1873                       b'\x00\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00'
1874                       b'%Y"N\x9a\x00\x00\x00\x9a\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1875                       b'\x00\x00\x00\x00\x00\x00\x00tensor.float.BE.BOM/data.pklPK\x01\x02\x00\x00\x00\x00'
1876                       b'\x08\x08\x00\x00\x00\x00\x00\x00I\xe2\xfb\xd3\x03\x00\x00\x00\x03\x00\x00\x00\x1d'
1877                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xea\x00\x00\x00tensor.fl'
1878                       b'oat.BE.BOM/byteorderPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x009D'
1879                       b'\xd6\x8a\x10\x00\x00\x00\x10\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1880                       b'\x00\x00\x00\x00S\x01\x00\x00tensor.float.BE.BOM/data/0PK\x01\x02\x00\x00\x00\x00'
1881                       b'\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00\x1b\x00'
1882                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x01\x00\x00tensor.float.'
1883                       b'BE.BOM/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00\x1e\x03-\x00\x00\x00\x00\x00'
1884                       b'\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00'
1885                       b'&\x01\x00\x00\x00\x00\x00\x00R\x02\x00\x00\x00\x00\x00\x00PK\x06\x07\x00\x00\x00'
1886                       b'\x00x\x03\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05\x06\x00\x00\x00\x00\x04'
1887                       b'\x00\x04\x00&\x01\x00\x00R\x02\x00\x00\x00\x00')
1888
1889        current_load_endian = get_default_load_endianness()
1890
1891        buf_le_no_bom = io.BytesIO(data_le_no_bom)
1892        buf_le_bom = io.BytesIO(data_le_bom)
1893        buf_be_no_bom = io.BytesIO(data_be_no_bom)
1894        buf_be_bom = io.BytesIO(data_be_bom)
1895
1896        try:
1897            set_default_load_endianness(LoadEndianness.NATIVE)
1898            tensor_le_no_bom = torch.load(buf_le_no_bom)
1899            tensor_be_no_bom = torch.load(buf_be_no_bom)
1900        finally:
1901            set_default_load_endianness(current_load_endian)
1902
1903        tensor_le_bom = torch.load(buf_le_bom)
1904        tensor_be_bom = torch.load(buf_be_bom)
1905
1906        buf_le_no_bom.seek(0)
1907        buf_be_no_bom.seek(0)
1908
1909        try:
1910            set_default_load_endianness(LoadEndianness.LITTLE)
1911            tensor_le_no_bom_little = torch.load(buf_le_no_bom)
1912            tensor_be_no_bom_little = torch.load(buf_be_no_bom)
1913        finally:
1914            set_default_load_endianness(current_load_endian)
1915
1916        buf_le_no_bom.seek(0)
1917        buf_be_no_bom.seek(0)
1918
1919        try:
1920            set_default_load_endianness(LoadEndianness.BIG)
1921            tensor_le_no_bom_big = torch.load(buf_le_no_bom)
1922            tensor_be_no_bom_big = torch.load(buf_be_no_bom)
1923        finally:
1924            set_default_load_endianness(current_load_endian)
1925
1926        self.assertTrue(torch.equal(tensor_le_bom, tensor_be_bom))
1927        self.assertFalse(torch.equal(tensor_le_no_bom, tensor_be_no_bom))
1928        self.assertTrue(torch.equal(tensor_le_no_bom_little, tensor_le_bom))
1929        self.assertFalse(torch.equal(tensor_be_no_bom_little, tensor_be_bom))
1930        self.assertFalse(torch.equal(tensor_le_no_bom_big, tensor_le_bom))
1931        self.assertTrue(torch.equal(tensor_be_no_bom_big, tensor_be_bom))
1932
1933        if (sys.byteorder == 'little'):
1934            self.assertTrue(torch.equal(tensor_le_no_bom, tensor_le_bom))
1935            self.assertTrue(torch.equal(tensor_le_no_bom, tensor_be_bom))
1936            self.assertFalse(torch.equal(tensor_be_no_bom, tensor_le_bom))
1937            self.assertFalse(torch.equal(tensor_be_no_bom, tensor_be_bom))
1938        else:
1939            self.assertFalse(torch.equal(tensor_le_no_bom, tensor_le_bom))
1940            self.assertFalse(torch.equal(tensor_le_no_bom, tensor_be_bom))
1941            self.assertTrue(torch.equal(tensor_be_no_bom, tensor_le_bom))
1942            self.assertTrue(torch.equal(tensor_be_no_bom, tensor_be_bom))
1943
1944    def test_serialization_load_bom_data_half(self):
1945        # 1. Generated on LE system using following commands:
1946        #
1947        # import torch
1948        #
1949        # x = torch.randn(2,2, dtype=torch.half)
1950        #
1951        # torch.save(x, "tensor.half.LE.pt", _disable_byteorder_record=True)
1952        # torch.save(x, "tensor.half.LE.BOM.pt")
1953        #
1954        # print(x)
1955        #
1956        # 2. After that it is resaved on BE system with following commands:
1957        #
1958        # import torch
1959        #
1960        # x = torch.load('tensor.half.LE.BOM.pt')
1961        #
1962        # torch.save(x, 'tensor.half.BE.pt', _disable_byteorder_record=True)
1963        # torch.save(x, 'tensor.half.BE.BOM.pt')
1964        #
1965        # print(x)
1966        #
1967        # Following commands and a bit of manual work were used to produce python bytes from resulting files:
1968        #
1969        # file = open('filename', 'rb')
1970        # data = file.read()
1971        # file.close()
1972        # print("\n".join(textwrap.wrap(str(data), 80)))
1973        #
1974        # BOM in this context is used as Byte Order Mark.
1975        #
1976        data_le_no_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1977                          b'\x00\x00\x00\x00\x00\x17\x00\x0b\x00tensor.half.LE/data.pklFB\x07\x00ZZZZZZZ\x80'
1978                          b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
1979                          b'h\nHalfStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x04tq\x05'
1980                          b'QK\x00K\x02K\x02\x86q\x06K\x02K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08'
1981                          b')Rq\ttq\nRq\x0b.PK\x07\x08E\xabQ\x8c\x99\x00\x00\x00\x99\x00\x00\x00PK\x03\x04\x00'
1982                          b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1983                          b'\x00\x15\x00$\x00tensor.half.LE/data/0FB \x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ0'
1984                          b'\xbbf;\xcd\xbd\xab9PK\x07\x08,D\x96\x91\x08\x00\x00\x00\x08\x00\x00\x00PK\x03\x04'
1985                          b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1986                          b'\x00\x00\x16\x004\x00tensor.half.LE/versionFB0\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
1987                          b'ZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00PK\x01'
1988                          b'\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00E\xabQ\x8c\x99\x00\x00\x00\x99'
1989                          b'\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
1990                          b'\x00tensor.half.LE/data.pklPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00'
1991                          b'\x00,D\x96\x91\x08\x00\x00\x00\x08\x00\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00'
1992                          b'\x00\x00\x00\x00\x00\x00\xe9\x00\x00\x00tensor.half.LE/data/0PK\x01\x02\x00\x00'
1993                          b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00'
1994                          b'\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\x01\x00\x00tensor.ha'
1995                          b'lf.LE/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00\x1e\x03-\x00\x00\x00\x00\x00'
1996                          b'\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00'
1997                          b'\xcc\x00\x00\x00\x00\x00\x00\x00\xd2\x01\x00\x00\x00\x00\x00\x00PK\x06\x07\x00\x00'
1998                          b'\x00\x00\x9e\x02\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05\x06\x00\x00\x00'
1999                          b'\x00\x03\x00\x03\x00\xcc\x00\x00\x00\xd2\x01\x00\x00\x00\x00')
2000
2001        data_le_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2002                       b'\x00\x00\x00\x00\x00\x1b\x00\x07\x00tensor.half.LE.BOM/data.pklFB\x03\x00ZZZ\x80'
2003                       b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
2004                       b'h\nHalfStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x04tq\x05'
2005                       b'QK\x00K\x02K\x02\x86q\x06K\x02K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08'
2006                       b')Rq\ttq\nRq\x0b.PK\x07\x08E\xabQ\x8c\x99\x00\x00\x00\x99\x00\x00\x00PK\x03\x04\x00'
2007                       b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2008                       b'\x00\x1c\x00\x1d\x00tensor.half.LE.BOM/byteorderFB\x19\x00ZZZZZZZZZZZZZZZZZZZZ'
2009                       b'ZZZZZlittlePK\x07\x08\x85=\xe3\x19\x06\x00\x00\x00\x06\x00\x00\x00PK\x03\x04\x00'
2010                       b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2011                       b'\x00\x19\x003\x00tensor.half.LE.BOM/data/0FB/\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
2012                       b'ZZZZZZZZZZZZZZZZ0\xbbf;\xcd\xbd\xab9PK\x07\x08,D\x96\x91\x08\x00\x00\x00\x08\x00'
2013                       b'\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2014                       b'\x00\x00\x00\x00\x00\x00\x1a\x000\x00tensor.half.LE.BOM/versionFB,\x00ZZZZZZZZ'
2015                       b'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00\x00\x00\x02\x00'
2016                       b'\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00E\xabQ\x8c\x99'
2017                       b'\x00\x00\x00\x99\x00\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2018                       b'\x00\x00\x00\x00\x00tensor.half.LE.BOM/data.pklPK\x01\x02\x00\x00\x00\x00\x08'
2019                       b'\x08\x00\x00\x00\x00\x00\x00\x85=\xe3\x19\x06\x00\x00\x00\x06\x00\x00\x00\x1c\x00'
2020                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe9\x00\x00\x00tensor.half.LE.'
2021                       b'BOM/byteorderPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00,D\x96\x91'
2022                       b'\x08\x00\x00\x00\x08\x00\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2023                       b'\x00\x00V\x01\x00\x00tensor.half.LE.BOM/data/0PK\x01\x02\x00\x00\x00\x00\x08\x08'
2024                       b'\x00\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00\x1a\x00\x00\x00'
2025                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd8\x01\x00\x00tensor.half.LE.BOM/ve'
2026                       b'rsionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00\x1e\x03-\x00\x00\x00\x00\x00\x00\x00'
2027                       b'\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00"\x01\x00'
2028                       b'\x00\x00\x00\x00\x00R\x02\x00\x00\x00\x00\x00\x00PK\x06\x07\x00\x00\x00\x00t\x03'
2029                       b'\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05\x06\x00\x00\x00\x00\x04\x00\x04'
2030                       b'\x00"\x01\x00\x00R\x02\x00\x00\x00\x00')
2031
2032        data_be_no_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2033                          b'\x00\x00\x00\x00\x00\x17\x00\x0b\x00tensor.half.BE/data.pklFB\x07\x00ZZZZZZZ\x80'
2034                          b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
2035                          b'h\nHalfStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x04tq\x05'
2036                          b'QK\x00K\x02K\x02\x86q\x06K\x02K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08'
2037                          b')Rq\ttq\nRq\x0b.PK\x07\x08E\xabQ\x8c\x99\x00\x00\x00\x99\x00\x00\x00PK\x03\x04\x00'
2038                          b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2039                          b'\x00\x15\x00$\x00tensor.half.BE/data/0FB \x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ\xbb'
2040                          b'0;f\xbd\xcd9\xabPK\x07\x08\xc7\xa1\xfd\x07\x08\x00\x00\x00\x08\x00\x00\x00PK\x03'
2041                          b'\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2042                          b'\x00\x00\x00\x16\x004\x00tensor.half.BE/versionFB0\x00ZZZZZZZZZZZZZZZZZZZZZZZ'
2043                          b'ZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00'
2044                          b'PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00E\xabQ\x8c\x99\x00\x00'
2045                          b'\x00\x99\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2046                          b'\x00\x00\x00tensor.half.BE/data.pklPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00'
2047                          b'\x00\x00\x00\xc7\xa1\xfd\x07\x08\x00\x00\x00\x08\x00\x00\x00\x15\x00\x00\x00\x00'
2048                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe9\x00\x00\x00tensor.half.BE/data/0PK\x01'
2049                          b'\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00\x00\x02'
2050                          b'\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\x01\x00\x00'
2051                          b'tensor.half.BE/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00\x1e\x03-\x00\x00'
2052                          b'\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00'
2053                          b'\x00\x00\x00\xcc\x00\x00\x00\x00\x00\x00\x00\xd2\x01\x00\x00\x00\x00\x00\x00PK\x06'
2054                          b'\x07\x00\x00\x00\x00\x9e\x02\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05\x06'
2055                          b'\x00\x00\x00\x00\x03\x00\x03\x00\xcc\x00\x00\x00\xd2\x01\x00\x00\x00\x00')
2056
2057        data_be_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2058                       b'\x00\x00\x00\x00\x00\x1b\x00\x07\x00tensor.half.BE.BOM/data.pklFB\x03\x00ZZZ\x80'
2059                       b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
2060                       b'h\nHalfStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x04tq\x05'
2061                       b'QK\x00K\x02K\x02\x86q\x06K\x02K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08'
2062                       b')Rq\ttq\nRq\x0b.PK\x07\x08E\xabQ\x8c\x99\x00\x00\x00\x99\x00\x00\x00PK\x03\x04\x00'
2063                       b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2064                       b'\x00\x1c\x00\x1d\x00tensor.half.BE.BOM/byteorderFB\x19\x00ZZZZZZZZZZZZZZZZZZZZ'
2065                       b'ZZZZZbigPK\x07\x08I\xe2\xfb\xd3\x03\x00\x00\x00\x03\x00\x00\x00PK\x03\x04\x00\x00'
2066                       b'\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2067                       b'\x19\x006\x00tensor.half.BE.BOM/data/0FB2\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
2068                       b'ZZZZZZZZZZZZZZZZ\xbb0;f\xbd\xcd9\xabPK\x07\x08\xc7\xa1\xfd\x07\x08\x00\x00\x00\x08'
2069                       b'\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2070                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x1a\x000\x00tensor.half.BE.BOM/versionFB,\x00ZZ'
2071                       b'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00\x00\x00'
2072                       b'\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00E\xab'
2073                       b'Q\x8c\x99\x00\x00\x00\x99\x00\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2074                       b'\x00\x00\x00\x00\x00\x00\x00tensor.half.BE.BOM/data.pklPK\x01\x02\x00\x00\x00\x00'
2075                       b'\x08\x08\x00\x00\x00\x00\x00\x00I\xe2\xfb\xd3\x03\x00\x00\x00\x03\x00\x00\x00\x1c'
2076                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe9\x00\x00\x00tensor.ha'
2077                       b'lf.BE.BOM/byteorderPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xc7'
2078                       b'\xa1\xfd\x07\x08\x00\x00\x00\x08\x00\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00'
2079                       b'\x00\x00\x00\x00\x00S\x01\x00\x00tensor.half.BE.BOM/data/0PK\x01\x02\x00\x00\x00'
2080                       b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00\x1a'
2081                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd8\x01\x00\x00tensor.ha'
2082                       b'lf.BE.BOM/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00\x1e\x03-\x00\x00\x00\x00'
2083                       b'\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00'
2084                       b'\x00"\x01\x00\x00\x00\x00\x00\x00R\x02\x00\x00\x00\x00\x00\x00PK\x06\x07\x00\x00'
2085                       b'\x00\x00t\x03\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05\x06\x00\x00\x00\x00'
2086                       b'\x04\x00\x04\x00"\x01\x00\x00R\x02\x00\x00\x00\x00')
2087
2088        current_load_endian = get_default_load_endianness()
2089
2090        buf_le_no_bom = io.BytesIO(data_le_no_bom)
2091        buf_le_bom = io.BytesIO(data_le_bom)
2092        buf_be_no_bom = io.BytesIO(data_be_no_bom)
2093        buf_be_bom = io.BytesIO(data_be_bom)
2094
2095        try:
2096            set_default_load_endianness(LoadEndianness.NATIVE)
2097            tensor_le_no_bom = torch.load(buf_le_no_bom)
2098            tensor_be_no_bom = torch.load(buf_be_no_bom)
2099        finally:
2100            set_default_load_endianness(current_load_endian)
2101
2102        tensor_le_bom = torch.load(buf_le_bom)
2103        tensor_be_bom = torch.load(buf_be_bom)
2104
2105        buf_le_no_bom.seek(0)
2106        buf_be_no_bom.seek(0)
2107
2108        try:
2109            set_default_load_endianness(LoadEndianness.LITTLE)
2110            tensor_le_no_bom_little = torch.load(buf_le_no_bom)
2111            tensor_be_no_bom_little = torch.load(buf_be_no_bom)
2112        finally:
2113            set_default_load_endianness(current_load_endian)
2114
2115        buf_le_no_bom.seek(0)
2116        buf_be_no_bom.seek(0)
2117
2118        try:
2119            set_default_load_endianness(LoadEndianness.BIG)
2120            tensor_le_no_bom_big = torch.load(buf_le_no_bom)
2121            tensor_be_no_bom_big = torch.load(buf_be_no_bom)
2122        finally:
2123            set_default_load_endianness(current_load_endian)
2124
2125        self.assertTrue(torch.equal(tensor_le_bom, tensor_be_bom))
2126        self.assertFalse(torch.equal(tensor_le_no_bom, tensor_be_no_bom))
2127        self.assertTrue(torch.equal(tensor_le_no_bom_little, tensor_le_bom))
2128        self.assertFalse(torch.equal(tensor_be_no_bom_little, tensor_be_bom))
2129        self.assertFalse(torch.equal(tensor_le_no_bom_big, tensor_le_bom))
2130        self.assertTrue(torch.equal(tensor_be_no_bom_big, tensor_be_bom))
2131
2132        if (sys.byteorder == 'little'):
2133            self.assertTrue(torch.equal(tensor_le_no_bom, tensor_le_bom))
2134            self.assertTrue(torch.equal(tensor_le_no_bom, tensor_be_bom))
2135            self.assertFalse(torch.equal(tensor_be_no_bom, tensor_le_bom))
2136            self.assertFalse(torch.equal(tensor_be_no_bom, tensor_be_bom))
2137        else:
2138            self.assertFalse(torch.equal(tensor_le_no_bom, tensor_le_bom))
2139            self.assertFalse(torch.equal(tensor_le_no_bom, tensor_be_bom))
2140            self.assertTrue(torch.equal(tensor_be_no_bom, tensor_le_bom))
2141            self.assertTrue(torch.equal(tensor_be_no_bom, tensor_be_bom))
2142
2143    def test_serialization_load_bom_data_long(self):
2144        # 1. Generated on LE system using following commands:
2145        #
2146        # import torch
2147        #
2148        # x = torch.randint(-4294967295, 4294967295, [4, 4], dtype=torch.long)
2149        #
2150        # torch.save(x, "tensor.long.LE.pt", _disable_byteorder_record=True)
2151        # torch.save(x, "tensor.long.LE.BOM.pt")
2152        #
2153        # print(x)
2154        #
2155        # 2. After that it is resaved on BE system with following commands:
2156        #
2157        # import torch
2158        #
2159        # x = torch.load('tensor.long.LE.BOM.pt')
2160        #
2161        # torch.save(x, 'tensor.long.BE.pt', _disable_byteorder_record=True)
2162        # torch.save(x, 'tensor.long.BE.BOM.pt')
2163        #
2164        # print(x)
2165        #
2166        # Following commands and a bit of manual work were used to produce python bytes from resulting files:
2167        #
2168        # file = open('filename', 'rb')
2169        # data = file.read()
2170        # file.close()
2171        # print("\n".join(textwrap.wrap(str(data), 80)))
2172        #
2173        # BOM in this context is used as Byte Order Mark.
2174        #
2175        data_le_no_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2176                          b'\x00\x00\x00\x00\x00\x17\x00\x0b\x00tensor.long.LE/data.pklFB\x07\x00ZZZZZZZ\x80'
2177                          b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
2178                          b'h\nLongStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x10tq\x05'
2179                          b'QK\x00K\x04K\x04\x86q\x06K\x04K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08'
2180                          b')Rq\ttq\nRq\x0b.PK\x07\x08 \xbd\xd7\xb0\x99\x00\x00\x00\x99\x00\x00\x00PK\x03\x04'
2181                          b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2182                          b'\x00\x00\x15\x00$\x00tensor.long.LE/data/0FB \x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
2183                          b'ZZl\xfa\xda\xbe\x00\x00\x00\x00GQ^\xa9\xff\xff\xff\xff\xc5\xa4\x19\xa4\x00\x00\x00'
2184                          b'\x00\xda\x9f\x04\xdd\xff\xff\xff\xff\x9b\xfc\x98\r\x00\x00\x00\x00\x8e\xb3\xb6'
2185                          b'=\x00\x00\x00\x00n}\xd2\x8f\xff\xff\xff\xff\xe2\xfe\x14u\xff\xff\xff\xff\xf1\x01'
2186                          b'T\x07\xff\xff\xff\xff\x9b\xb3"\x7f\xff\xff\xff\xff\xb2p\x07\xfc\xff\xff\xff\xff\x1f'
2187                          b'1\xa6M\x00\x00\x00\x00a\xaa|u\xff\xff\xff\xff2Y\x12;\x00\x00\x00\x00\'J\xb7\xcb'
2188                          b'\x00\x00\x00\x00m\xb2\x1c\xe1\xff\xff\xff\xffPK\x07\x08\xd5\x00\xa1r\x80\x00\x00'
2189                          b'\x00\x80\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00'
2190                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16\x00<\x00tensor.long.LE/versionFB8\x00'
2191                          b'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9eg'
2192                          b'U\x02\x00\x00\x00\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00'
2193                          b'\x00\x00 \xbd\xd7\xb0\x99\x00\x00\x00\x99\x00\x00\x00\x17\x00\x00\x00\x00\x00'
2194                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00tensor.long.LE/data.pklPK\x01\x02'
2195                          b'\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd5\x00\xa1r\x80\x00\x00\x00\x80'
2196                          b'\x00\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe9\x00\x00'
2197                          b'\x00tensor.long.LE/data/0PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00'
2198                          b'\x00\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00'
2199                          b'\x00\x00\x00\x00\x00\xd0\x01\x00\x00tensor.long.LE/versionPK\x06\x06,\x00\x00'
2200                          b'\x00\x00\x00\x00\x00\x1e\x03-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00'
2201                          b'\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\xcc\x00\x00\x00\x00\x00\x00\x00'
2202                          b'R\x02\x00\x00\x00\x00\x00\x00PK\x06\x07\x00\x00\x00\x00\x1e\x03\x00\x00\x00\x00'
2203                          b'\x00\x00\x01\x00\x00\x00PK\x05\x06\x00\x00\x00\x00\x03\x00\x03\x00\xcc\x00\x00\x00'
2204                          b'R\x02\x00\x00\x00\x00')
2205
2206        data_le_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2207                       b'\x00\x00\x00\x00\x00\x1b\x00\x07\x00tensor.long.LE.BOM/data.pklFB\x03\x00ZZZ\x80'
2208                       b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
2209                       b'h\nLongStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x10tq\x05'
2210                       b'QK\x00K\x04K\x04\x86q\x06K\x04K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08'
2211                       b')Rq\ttq\nRq\x0b.PK\x07\x08 \xbd\xd7\xb0\x99\x00\x00\x00\x99\x00\x00\x00PK\x03\x04'
2212                       b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2213                       b'\x00\x00\x1c\x00\x1d\x00tensor.long.LE.BOM/byteorderFB\x19\x00ZZZZZZZZZZZZZZZZZ'
2214                       b'ZZZZZZZZlittlePK\x07\x08\x85=\xe3\x19\x06\x00\x00\x00\x06\x00\x00\x00PK\x03\x04\x00'
2215                       b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2216                       b'\x00\x19\x003\x00tensor.long.LE.BOM/data/0FB/\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
2217                       b'ZZZZZZZZZZZZZZZZZZZl\xfa\xda\xbe\x00\x00\x00\x00GQ^\xa9\xff\xff\xff\xff\xc5\xa4\x19'
2218                       b'\xa4\x00\x00\x00\x00\xda\x9f\x04\xdd\xff\xff\xff\xff\x9b\xfc\x98\r\x00\x00\x00'
2219                       b'\x00\x8e\xb3\xb6=\x00\x00\x00\x00n}\xd2\x8f\xff\xff\xff\xff\xe2\xfe\x14u\xff\xff'
2220                       b'\xff\xff\xf1\x01T\x07\xff\xff\xff\xff\x9b\xb3"\x7f\xff\xff\xff\xff\xb2p\x07\xfc'
2221                       b'\xff\xff\xff\xff\x1f1\xa6M\x00\x00\x00\x00a\xaa|u\xff\xff\xff\xff2Y\x12;\x00\x00'
2222                       b'\x00\x00\'J\xb7\xcb\x00\x00\x00\x00m\xb2\x1c\xe1\xff\xff\xff\xffPK\x07\x08\xd5\x00'
2223                       b'\xa1r\x80\x00\x00\x00\x80\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00'
2224                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1a\x008\x00tensor.lon'
2225                       b'g.LE.BOM/versionFB4\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK'
2226                       b'\x07\x08\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08'
2227                       b'\x08\x00\x00\x00\x00\x00\x00 \xbd\xd7\xb0\x99\x00\x00\x00\x99\x00\x00\x00\x1b\x00'
2228                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00tensor.long.LE.'
2229                       b'BOM/data.pklPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x85=\xe3\x19'
2230                       b'\x06\x00\x00\x00\x06\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2231                       b'\x00\x00\xe9\x00\x00\x00tensor.long.LE.BOM/byteorderPK\x01\x02\x00\x00\x00\x00'
2232                       b'\x08\x08\x00\x00\x00\x00\x00\x00\xd5\x00\xa1r\x80\x00\x00\x00\x80\x00\x00\x00\x19'
2233                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x01\x00\x00tensor.long.L'
2234                       b'E.BOM/data/0PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU'
2235                       b'\x02\x00\x00\x00\x02\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2236                       b'\x00\x00P\x02\x00\x00tensor.long.LE.BOM/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00'
2237                       b'\x00\x1e\x03-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00'
2238                       b'\x04\x00\x00\x00\x00\x00\x00\x00"\x01\x00\x00\x00\x00\x00\x00\xd2\x02\x00\x00'
2239                       b'\x00\x00\x00\x00PK\x06\x07\x00\x00\x00\x00\xf4\x03\x00\x00\x00\x00\x00\x00\x01\x00'
2240                       b'\x00\x00PK\x05\x06\x00\x00\x00\x00\x04\x00\x04\x00"\x01\x00\x00\xd2\x02\x00\x00'
2241                       b'\x00\x00')
2242
2243        data_be_no_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2244                          b'\x00\x00\x00\x00\x00\x17\x00\x0b\x00tensor.long.BE/data.pklFB\x07\x00ZZZZZZZ\x80'
2245                          b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
2246                          b'h\nLongStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x10tq\x05'
2247                          b'QK\x00K\x04K\x04\x86q\x06K\x04K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08'
2248                          b')Rq\ttq\nRq\x0b.PK\x07\x08 \xbd\xd7\xb0\x99\x00\x00\x00\x99\x00\x00\x00PK\x03\x04'
2249                          b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2250                          b'\x00\x00\x15\x00$\x00tensor.long.BE/data/0FB \x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
2251                          b'ZZ\x00\x00\x00\x00\xbe\xda\xfal\xff\xff\xff\xff\xa9^QG\x00\x00\x00\x00\xa4\x19\xa4'
2252                          b'\xc5\xff\xff\xff\xff\xdd\x04\x9f\xda\x00\x00\x00\x00\r\x98\xfc\x9b\x00\x00\x00'
2253                          b'\x00=\xb6\xb3\x8e\xff\xff\xff\xff\x8f\xd2}n\xff\xff\xff\xffu\x14\xfe\xe2\xff\xff'
2254                          b'\xff\xff\x07T\x01\xf1\xff\xff\xff\xff\x7f"\xb3\x9b\xff\xff\xff\xff\xfc\x07p\xb2\x00'
2255                          b'\x00\x00\x00M\xa61\x1f\xff\xff\xff\xffu|\xaaa\x00\x00\x00\x00;\x12Y2\x00\x00\x00'
2256                          b'\x00\xcb\xb7J\'\xff\xff\xff\xff\xe1\x1c\xb2mPK\x07\x08\xb9\x1b\x81j\x80\x00\x00'
2257                          b'\x00\x80\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00'
2258                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16\x00<\x00tensor.long.BE/versionFB8\x00'
2259                          b'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9eg'
2260                          b'U\x02\x00\x00\x00\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00'
2261                          b'\x00\x00 \xbd\xd7\xb0\x99\x00\x00\x00\x99\x00\x00\x00\x17\x00\x00\x00\x00\x00'
2262                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00tensor.long.BE/data.pklPK\x01\x02'
2263                          b'\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xb9\x1b\x81j\x80\x00\x00\x00\x80'
2264                          b'\x00\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe9\x00\x00'
2265                          b'\x00tensor.long.BE/data/0PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00'
2266                          b'\x00\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00'
2267                          b'\x00\x00\x00\x00\x00\xd0\x01\x00\x00tensor.long.BE/versionPK\x06\x06,\x00\x00'
2268                          b'\x00\x00\x00\x00\x00\x1e\x03-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00'
2269                          b'\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\xcc\x00\x00\x00\x00\x00\x00\x00'
2270                          b'R\x02\x00\x00\x00\x00\x00\x00PK\x06\x07\x00\x00\x00\x00\x1e\x03\x00\x00\x00\x00'
2271                          b'\x00\x00\x01\x00\x00\x00PK\x05\x06\x00\x00\x00\x00\x03\x00\x03\x00\xcc\x00\x00\x00'
2272                          b'R\x02\x00\x00\x00\x00')
2273
2274        data_be_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2275                       b'\x00\x00\x00\x00\x00\x1b\x00\x07\x00tensor.long.BE.BOM/data.pklFB\x03\x00ZZZ\x80'
2276                       b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
2277                       b'h\nLongStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x10tq\x05'
2278                       b'QK\x00K\x04K\x04\x86q\x06K\x04K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08'
2279                       b')Rq\ttq\nRq\x0b.PK\x07\x08 \xbd\xd7\xb0\x99\x00\x00\x00\x99\x00\x00\x00PK\x03\x04'
2280                       b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2281                       b'\x00\x00\x1c\x00\x1d\x00tensor.long.BE.BOM/byteorderFB\x19\x00ZZZZZZZZZZZZZZZZZ'
2282                       b'ZZZZZZZZbigPK\x07\x08I\xe2\xfb\xd3\x03\x00\x00\x00\x03\x00\x00\x00PK\x03\x04\x00'
2283                       b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2284                       b'\x00\x19\x006\x00tensor.long.BE.BOM/data/0FB2\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
2285                       b'ZZZZZZZZZZZZZZZZZZZ\x00\x00\x00\x00\xbe\xda\xfal\xff\xff\xff\xff\xa9^QG\x00\x00\x00'
2286                       b'\x00\xa4\x19\xa4\xc5\xff\xff\xff\xff\xdd\x04\x9f\xda\x00\x00\x00\x00\r\x98\xfc'
2287                       b'\x9b\x00\x00\x00\x00=\xb6\xb3\x8e\xff\xff\xff\xff\x8f\xd2}n\xff\xff\xff\xffu\x14'
2288                       b'\xfe\xe2\xff\xff\xff\xff\x07T\x01\xf1\xff\xff\xff\xff\x7f"\xb3\x9b\xff\xff\xff\xff'
2289                       b'\xfc\x07p\xb2\x00\x00\x00\x00M\xa61\x1f\xff\xff\xff\xffu|\xaaa\x00\x00\x00\x00'
2290                       b';\x12Y2\x00\x00\x00\x00\xcb\xb7J\'\xff\xff\xff\xff\xe1\x1c\xb2mPK\x07\x08\xb9\x1b'
2291                       b'\x81j\x80\x00\x00\x00\x80\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00'
2292                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1a\x008\x00tensor.lon'
2293                       b'g.BE.BOM/versionFB4\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK'
2294                       b'\x07\x08\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08'
2295                       b'\x08\x00\x00\x00\x00\x00\x00 \xbd\xd7\xb0\x99\x00\x00\x00\x99\x00\x00\x00\x1b\x00'
2296                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00tensor.long.BE.'
2297                       b'BOM/data.pklPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00I\xe2\xfb\xd3'
2298                       b'\x03\x00\x00\x00\x03\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2299                       b'\x00\x00\xe9\x00\x00\x00tensor.long.BE.BOM/byteorderPK\x01\x02\x00\x00\x00\x00'
2300                       b'\x08\x08\x00\x00\x00\x00\x00\x00\xb9\x1b\x81j\x80\x00\x00\x00\x80\x00\x00\x00\x19'
2301                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\x01\x00\x00tensor.long.B'
2302                       b'E.BOM/data/0PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU'
2303                       b'\x02\x00\x00\x00\x02\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2304                       b'\x00\x00P\x02\x00\x00tensor.long.BE.BOM/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00'
2305                       b'\x00\x1e\x03-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00'
2306                       b'\x04\x00\x00\x00\x00\x00\x00\x00"\x01\x00\x00\x00\x00\x00\x00\xd2\x02\x00\x00'
2307                       b'\x00\x00\x00\x00PK\x06\x07\x00\x00\x00\x00\xf4\x03\x00\x00\x00\x00\x00\x00\x01\x00'
2308                       b'\x00\x00PK\x05\x06\x00\x00\x00\x00\x04\x00\x04\x00"\x01\x00\x00\xd2\x02\x00\x00'
2309                       b'\x00\x00')
2310
2311        current_load_endian = get_default_load_endianness()
2312
2313        buf_le_no_bom = io.BytesIO(data_le_no_bom)
2314        buf_le_bom = io.BytesIO(data_le_bom)
2315        buf_be_no_bom = io.BytesIO(data_be_no_bom)
2316        buf_be_bom = io.BytesIO(data_be_bom)
2317
2318        try:
2319            set_default_load_endianness(LoadEndianness.NATIVE)
2320            tensor_le_no_bom = torch.load(buf_le_no_bom)
2321            tensor_be_no_bom = torch.load(buf_be_no_bom)
2322        finally:
2323            set_default_load_endianness(current_load_endian)
2324
2325        tensor_le_bom = torch.load(buf_le_bom)
2326        tensor_be_bom = torch.load(buf_be_bom)
2327
2328        buf_le_no_bom.seek(0)
2329        buf_be_no_bom.seek(0)
2330
2331        try:
2332            set_default_load_endianness(LoadEndianness.LITTLE)
2333            tensor_le_no_bom_little = torch.load(buf_le_no_bom)
2334            tensor_be_no_bom_little = torch.load(buf_be_no_bom)
2335        finally:
2336            set_default_load_endianness(current_load_endian)
2337
2338        buf_le_no_bom.seek(0)
2339        buf_be_no_bom.seek(0)
2340
2341        try:
2342            set_default_load_endianness(LoadEndianness.BIG)
2343            tensor_le_no_bom_big = torch.load(buf_le_no_bom)
2344            tensor_be_no_bom_big = torch.load(buf_be_no_bom)
2345        finally:
2346            set_default_load_endianness(current_load_endian)
2347
2348        self.assertTrue(torch.equal(tensor_le_bom, tensor_be_bom))
2349        self.assertFalse(torch.equal(tensor_le_no_bom, tensor_be_no_bom))
2350        self.assertTrue(torch.equal(tensor_le_no_bom_little, tensor_le_bom))
2351        self.assertFalse(torch.equal(tensor_be_no_bom_little, tensor_be_bom))
2352        self.assertFalse(torch.equal(tensor_le_no_bom_big, tensor_le_bom))
2353        self.assertTrue(torch.equal(tensor_be_no_bom_big, tensor_be_bom))
2354
2355        if (sys.byteorder == 'little'):
2356            self.assertTrue(torch.equal(tensor_le_no_bom, tensor_le_bom))
2357            self.assertTrue(torch.equal(tensor_le_no_bom, tensor_be_bom))
2358            self.assertFalse(torch.equal(tensor_be_no_bom, tensor_le_bom))
2359            self.assertFalse(torch.equal(tensor_be_no_bom, tensor_be_bom))
2360        else:
2361            self.assertFalse(torch.equal(tensor_le_no_bom, tensor_le_bom))
2362            self.assertFalse(torch.equal(tensor_le_no_bom, tensor_be_bom))
2363            self.assertTrue(torch.equal(tensor_be_no_bom, tensor_le_bom))
2364            self.assertTrue(torch.equal(tensor_be_no_bom, tensor_be_bom))
2365
2366    def test_serialization_load_bom_data_int(self):
2367        # 1. Generated on LE system using following commands:
2368        #
2369        # import torch
2370        #
2371        # x = torch.randint(-2147483648, 2147483648, [4, 4], dtype=torch.int)
2372        #
2373        # torch.save(x, "tensor.int.LE.pt", _disable_byteorder_record=True)
2374        # torch.save(x, "tensor.int.LE.BOM.pt")
2375        #
2376        # print(x)
2377        #
2378        # 2. After that it is resaved on BE system with following commands:
2379        #
2380        # import torch
2381        #
2382        # x = torch.load('tensor.int.LE.BOM.pt')
2383        #
2384        # torch.save(x, 'tensor.int.BE.pt', _disable_byteorder_record=True)
2385        # torch.save(x, 'tensor.int.BE.BOM.pt')
2386        #
2387        # print(x)
2388        #
2389        # Following commands and a bit of manual work were used to produce python bytes from resulting files:
2390        #
2391        # file = open('filename', 'rb')
2392        # data = file.read()
2393        # file.close()
2394        # print("\n".join(textwrap.wrap(str(data), 80)))
2395        #
2396        # BOM in this context is used as Byte Order Mark.
2397        #
2398        data_le_no_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2399                          b'\x00\x00\x00\x00\x00\x16\x00\x0c\x00tensor.int.LE/data.pklFB\x08\x00ZZZZZZZZ\x80'
2400                          b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
2401                          b'h\nIntStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x10tq\x05Q'
2402                          b'K\x00K\x04K\x04\x86q\x06K\x04K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08)'
2403                          b'Rq\ttq\nRq\x0b.PK\x07\x08\xdd\xa0\'\xa8\x98\x00\x00\x00\x98\x00\x00\x00PK\x03\x04'
2404                          b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2405                          b'\x00\x00\x14\x00&\x00tensor.int.LE/data/0FB"\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
2406                          b'ZZZ\xf6\x19\x95i\xfaL\x1f\t%\xa3\r\xb8\xe5\xcfN\xe2\xa2\xc7\x8f\xb4\xfd\xf5(2\xe3'
2407                          b'YX\xf5\x1dhO}\xeb\xba\xcf\x02\x8b\x84\xdd>L\xbc(\xc7\x92Q\x98\xa6\x1aQ^w\xea\x93'
2408                          b'2>\xad\x87D\xdd\x9el\xb6\x15PK\x07\x08W\x1c\xcd\x19@\x00\x00\x00@\x00\x00\x00PK'
2409                          b'\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2410                          b'\x00\x00\x00\x00\x15\x00=\x00tensor.int.LE/versionFB9\x00ZZZZZZZZZZZZZZZZZZZZZZZ'
2411                          b'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00\x00\x00\x02\x00'
2412                          b'\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xdd\xa0\'\xa8'
2413                          b'\x98\x00\x00\x00\x98\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2414                          b'\x00\x00\x00\x00\x00\x00tensor.int.LE/data.pklPK\x01\x02\x00\x00\x00\x00\x08\x08'
2415                          b'\x00\x00\x00\x00\x00\x00W\x1c\xcd\x19@\x00\x00\x00@\x00\x00\x00\x14\x00\x00\x00'
2416                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8\x00\x00\x00tensor.int.LE/data/0PK\x01'
2417                          b'\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00\x00'
2418                          b'\x02\x00\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\x01'
2419                          b'\x00\x00tensor.int.LE/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00\x1e\x03-\x00'
2420                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00'
2421                          b'\x00\x00\x00\x00\xc9\x00\x00\x00\x00\x00\x00\x00\x12\x02\x00\x00\x00\x00\x00\x00'
2422                          b'PK\x06\x07\x00\x00\x00\x00\xdb\x02\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05'
2423                          b'\x06\x00\x00\x00\x00\x03\x00\x03\x00\xc9\x00\x00\x00\x12\x02\x00\x00\x00\x00')
2424
2425        data_le_bom = (b"PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
2426                       b"\x00\x00\x00\x00\x00\x1a\x00\x08\x00tensor.int.LE.BOM/data.pklFB\x04\x00ZZZZ\x80"
2427                       b"\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc"
2428                       b"h\nIntStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x10tq\x05Q"
2429                       b"K\x00K\x04K\x04\x86q\x06K\x04K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08)"
2430                       b"Rq\ttq\nRq\x0b.PK\x07\x08\xdd\xa0'\xa8\x98\x00\x00\x00\x98\x00\x00\x00PK\x03\x04"
2431                       b"\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
2432                       b"\x00\x00\x1b\x00\x1f\x00tensor.int.LE.BOM/byteorderFB\x1b\x00ZZZZZZZZZZZZZZZZZZZ"
2433                       b"ZZZZZZZZlittlePK\x07\x08\x85=\xe3\x19\x06\x00\x00\x00\x06\x00\x00\x00PK\x03\x04\x00"
2434                       b"\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
2435                       b"\x00\x18\x004\x00tensor.int.LE.BOM/data/0FB0\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
2436                       b"ZZZZZZZZZZZZZZZZZZZ\xf6\x19\x95i\xfaL\x1f\t%\xa3\r\xb8\xe5\xcfN\xe2\xa2\xc7\x8f\xb4"
2437                       b"\xfd\xf5(2\xe3YX\xf5\x1dhO}\xeb\xba\xcf\x02\x8b\x84\xdd>L\xbc(\xc7\x92Q\x98\xa6"
2438                       b"\x1aQ^w\xea\x932>\xad\x87D\xdd\x9el\xb6\x15PK\x07\x08W\x1c\xcd\x19@\x00\x00\x00"
2439                       b"@\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
2440                       b"\x00\x00\x00\x00\x00\x00\x00\x00\x19\x009\x00tensor.int.LE.BOM/versionFB5\x00ZZZ"
2441                       b"ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00"
2442                       b"\x00\x00\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00"
2443                       b"\xdd\xa0'\xa8\x98\x00\x00\x00\x98\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00"
2444                       b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00tensor.int.LE.BOM/data.pklPK\x01\x02\x00"
2445                       b"\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x85=\xe3\x19\x06\x00\x00\x00\x06\x00"
2446                       b"\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8\x00\x00\x00"
2447                       b"tensor.int.LE.BOM/byteorderPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00"
2448                       b"\x00W\x1c\xcd\x19@\x00\x00\x00@\x00\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00"
2449                       b"\x00\x00\x00\x00\x00V\x01\x00\x00tensor.int.LE.BOM/data/0PK\x01\x02\x00\x00\x00"
2450                       b"\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00\x19"
2451                       b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x02\x00\x00tensor.int"
2452                       b".LE.BOM/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00\x1e\x03-\x00\x00\x00\x00\x00"
2453                       b"\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00"
2454                       b"\x1e\x01\x00\x00\x00\x00\x00\x00\x92\x02\x00\x00\x00\x00\x00\x00PK\x06\x07\x00"
2455                       b"\x00\x00\x00\xb0\x03\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05\x06\x00\x00\x00"
2456                       b"\x00\x04\x00\x04\x00\x1e\x01\x00\x00\x92\x02\x00\x00\x00\x00")
2457
2458        data_be_no_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2459                          b'\x00\x00\x00\x00\x00\x16\x00\x0c\x00tensor.int.BE/data.pklFB\x08\x00ZZZZZZZZ\x80'
2460                          b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
2461                          b'h\nIntStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x10tq\x05Q'
2462                          b'K\x00K\x04K\x04\x86q\x06K\x04K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08)'
2463                          b'Rq\ttq\nRq\x0b.PK\x07\x08\xdd\xa0\'\xa8\x98\x00\x00\x00\x98\x00\x00\x00PK\x03\x04'
2464                          b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2465                          b'\x00\x00\x14\x00&\x00tensor.int.BE/data/0FB"\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
2466                          b'ZZZi\x95\x19\xf6\t\x1fL\xfa\xb8\r\xa3%\xe2N\xcf\xe5\xb4\x8f\xc7\xa22(\xf5\xfd\xf5'
2467                          b'XY\xe3}Oh\x1d\x02\xcf\xba\xeb>\xdd\x84\x8b\xc7(\xbcL\xa6\x98Q\x92w^Q\x1a>2\x93\xea'
2468                          b'\xddD\x87\xad\x15\xb6l\x9ePK\x07\x08rq\x19^@\x00\x00\x00@\x00\x00\x00PK\x03\x04'
2469                          b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2470                          b'\x00\x00\x15\x00=\x00tensor.int.BE/versionFB9\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
2471                          b'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00'
2472                          b'PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xdd\xa0\'\xa8\x98\x00'
2473                          b'\x00\x00\x98\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2474                          b'\x00\x00\x00\x00tensor.int.BE/data.pklPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00'
2475                          b'\x00\x00\x00\x00rq\x19^@\x00\x00\x00@\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00'
2476                          b'\x00\x00\x00\x00\x00\x00\x00\xe8\x00\x00\x00tensor.int.BE/data/0PK\x01\x02\x00\x00'
2477                          b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00'
2478                          b'\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\x01\x00\x00tens'
2479                          b'or.int.BE/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00\x1e\x03-\x00\x00\x00\x00'
2480                          b'\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00'
2481                          b'\x00\xc9\x00\x00\x00\x00\x00\x00\x00\x12\x02\x00\x00\x00\x00\x00\x00PK\x06\x07\x00'
2482                          b'\x00\x00\x00\xdb\x02\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05\x06\x00\x00'
2483                          b'\x00\x00\x03\x00\x03\x00\xc9\x00\x00\x00\x12\x02\x00\x00\x00\x00')
2484
2485        data_be_bom = (b"PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
2486                       b"\x00\x00\x00\x00\x00\x1a\x00\x08\x00tensor.int.BE.BOM/data.pklFB\x04\x00ZZZZ\x80"
2487                       b"\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc"
2488                       b"h\nIntStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x10tq\x05Q"
2489                       b"K\x00K\x04K\x04\x86q\x06K\x04K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08)"
2490                       b"Rq\ttq\nRq\x0b.PK\x07\x08\xdd\xa0'\xa8\x98\x00\x00\x00\x98\x00\x00\x00PK\x03\x04"
2491                       b"\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
2492                       b"\x00\x00\x1b\x00\x1f\x00tensor.int.BE.BOM/byteorderFB\x1b\x00ZZZZZZZZZZZZZZZZZZZ"
2493                       b"ZZZZZZZZbigPK\x07\x08I\xe2\xfb\xd3\x03\x00\x00\x00\x03\x00\x00\x00PK\x03\x04\x00"
2494                       b"\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
2495                       b"\x00\x18\x007\x00tensor.int.BE.BOM/data/0FB3\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
2496                       b"ZZZZZZZZZZZZZZZZZZZi\x95\x19\xf6\t\x1fL\xfa\xb8\r\xa3%\xe2N\xcf\xe5\xb4\x8f\xc7\xa2"
2497                       b"2(\xf5\xfd\xf5XY\xe3}Oh\x1d\x02\xcf\xba\xeb>\xdd\x84\x8b\xc7(\xbcL\xa6\x98Q\x92"
2498                       b"w^Q\x1a>2\x93\xea\xddD\x87\xad\x15\xb6l\x9ePK\x07\x08rq\x19^@\x00\x00\x00@\x00"
2499                       b"\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
2500                       b"\x00\x00\x00\x00\x00\x00\x19\x009\x00tensor.int.BE.BOM/versionFB5\x00ZZZZZZZZZ"
2501                       b"ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00\x00\x00"
2502                       b"\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xdd"
2503                       b"\xa0'\xa8\x98\x00\x00\x00\x98\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00"
2504                       b"\x00\x00\x00\x00\x00\x00\x00\x00tensor.int.BE.BOM/data.pklPK\x01\x02\x00\x00\x00"
2505                       b"\x00\x08\x08\x00\x00\x00\x00\x00\x00I\xe2\xfb\xd3\x03\x00\x00\x00\x03\x00\x00\x00"
2506                       b"\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8\x00\x00\x00tenso"
2507                       b"r.int.BE.BOM/byteorderPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00"
2508                       b"rq\x19^@\x00\x00\x00@\x00\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
2509                       b"\x00\x00S\x01\x00\x00tensor.int.BE.BOM/data/0PK\x01\x02\x00\x00\x00\x00\x08\x08"
2510                       b"\x00\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00\x19\x00\x00\x00"
2511                       b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x02\x00\x00tensor.int.BE.BOM/vers"
2512                       b"ionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00\x1e\x03-\x00\x00\x00\x00\x00\x00\x00\x00"
2513                       b"\x00\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x1e\x01\x00"
2514                       b"\x00\x00\x00\x00\x00\x92\x02\x00\x00\x00\x00\x00\x00PK\x06\x07\x00\x00\x00\x00"
2515                       b"\xb0\x03\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05\x06\x00\x00\x00\x00\x04\x00"
2516                       b"\x04\x00\x1e\x01\x00\x00\x92\x02\x00\x00\x00\x00")
2517
2518        current_load_endian = get_default_load_endianness()
2519
2520        buf_le_no_bom = io.BytesIO(data_le_no_bom)
2521        buf_le_bom = io.BytesIO(data_le_bom)
2522        buf_be_no_bom = io.BytesIO(data_be_no_bom)
2523        buf_be_bom = io.BytesIO(data_be_bom)
2524
2525        try:
2526            set_default_load_endianness(LoadEndianness.NATIVE)
2527            tensor_le_no_bom = torch.load(buf_le_no_bom)
2528            tensor_be_no_bom = torch.load(buf_be_no_bom)
2529        finally:
2530            set_default_load_endianness(current_load_endian)
2531
2532        tensor_le_bom = torch.load(buf_le_bom)
2533        tensor_be_bom = torch.load(buf_be_bom)
2534
2535        buf_le_no_bom.seek(0)
2536        buf_be_no_bom.seek(0)
2537
2538        try:
2539            set_default_load_endianness(LoadEndianness.LITTLE)
2540            tensor_le_no_bom_little = torch.load(buf_le_no_bom)
2541            tensor_be_no_bom_little = torch.load(buf_be_no_bom)
2542        finally:
2543            set_default_load_endianness(current_load_endian)
2544
2545        buf_le_no_bom.seek(0)
2546        buf_be_no_bom.seek(0)
2547
2548        try:
2549            set_default_load_endianness(LoadEndianness.BIG)
2550            tensor_le_no_bom_big = torch.load(buf_le_no_bom)
2551            tensor_be_no_bom_big = torch.load(buf_be_no_bom)
2552        finally:
2553            set_default_load_endianness(current_load_endian)
2554
2555        self.assertTrue(torch.equal(tensor_le_bom, tensor_be_bom))
2556        self.assertFalse(torch.equal(tensor_le_no_bom, tensor_be_no_bom))
2557        self.assertTrue(torch.equal(tensor_le_no_bom_little, tensor_le_bom))
2558        self.assertFalse(torch.equal(tensor_be_no_bom_little, tensor_be_bom))
2559        self.assertFalse(torch.equal(tensor_le_no_bom_big, tensor_le_bom))
2560        self.assertTrue(torch.equal(tensor_be_no_bom_big, tensor_be_bom))
2561
2562        if (sys.byteorder == 'little'):
2563            self.assertTrue(torch.equal(tensor_le_no_bom, tensor_le_bom))
2564            self.assertTrue(torch.equal(tensor_le_no_bom, tensor_be_bom))
2565            self.assertFalse(torch.equal(tensor_be_no_bom, tensor_le_bom))
2566            self.assertFalse(torch.equal(tensor_be_no_bom, tensor_be_bom))
2567        else:
2568            self.assertFalse(torch.equal(tensor_le_no_bom, tensor_le_bom))
2569            self.assertFalse(torch.equal(tensor_le_no_bom, tensor_be_bom))
2570            self.assertTrue(torch.equal(tensor_be_no_bom, tensor_le_bom))
2571            self.assertTrue(torch.equal(tensor_be_no_bom, tensor_be_bom))
2572
2573    def test_serialization_load_bom_data_int16(self):
2574        # 1. Generated on LE system using following commands:
2575        #
2576        # import torch
2577        #
2578        # x = torch.randint(-32768, 32768, [4, 4], dtype=torch.int16)
2579        #
2580        # torch.save(x, "tensor.int16.LE.pt", _disable_byteorder_record=True)
2581        # torch.save(x, "tensor.int16.LE.BOM.pt")
2582        #
2583        # print(x)
2584        #
2585        # 2. After that it is resaved on BE system with following commands:
2586        #
2587        # import torch
2588        #
2589        # x = torch.load('tensor.int16.LE.BOM.pt')
2590        #
2591        # torch.save(x, 'tensor.int16.BE.pt', _disable_byteorder_record=True)
2592        # torch.save(x, 'tensor.int16.BE.BOM.pt')
2593        #
2594        # print(x)
2595        #
2596        # Following commands and a bit of manual work were used to produce python bytes from resulting files:
2597        #
2598        # file = open('filename', 'rb')
2599        # data = file.read()
2600        # file.close()
2601        # print("\n".join(textwrap.wrap(str(data), 80)))
2602        #
2603        # BOM in this context is used as Byte Order Mark.
2604        #
2605        data_le_no_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2606                          b'\x00\x00\x00\x00\x00\x18\x00\n\x00tensor.int16.LE/data.pklFB\x06\x00ZZZZZZ\x80\x02'
2607                          b'ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorch\n'
2608                          b'ShortStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x10tq\x05Q'
2609                          b'K\x00K\x04K\x04\x86q\x06K\x04K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08)'
2610                          b'Rq\ttq\nRq\x0b.PK\x07\x08\xf6\xc8K\xd8\x9a\x00\x00\x00\x9a\x00\x00\x00PK\x03\x04'
2611                          b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2612                          b'\x00\x00\x16\x00"\x00tensor.int16.LE/data/0FB\x1e\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
2613                          b'ZZZO\xa4\x9bJ_Z-\xa5#\xf1y\xef\xb1@\x061"\xe3\x83\x07;\x83\x80\x08\xf1\x18q\xf6\xfe'
2614                          b'\xf3\xc9,PK\x07\x08\xa0\x98\xd9\xdf \x00\x00\x00 \x00\x00\x00PK\x03\x04\x00\x00'
2615                          b'\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2616                          b'\x17\x00\x1b\x00tensor.int16.LE/versionFB\x17\x00ZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07'
2617                          b'\x08\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08'
2618                          b'\x00\x00\x00\x00\x00\x00\xf6\xc8K\xd8\x9a\x00\x00\x00\x9a\x00\x00\x00\x18\x00'
2619                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00tensor.int16.LE/'
2620                          b'data.pklPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xa0\x98\xd9\xdf'
2621                          b' \x00\x00\x00 \x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2622                          b'\x00\xea\x00\x00\x00tensor.int16.LE/data/0PK\x01\x02\x00\x00\x00\x00\x08\x08\x00'
2623                          b'\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00\x17\x00\x00\x00\x00'
2624                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00p\x01\x00\x00tensor.int16.LE/versionPK\x06'
2625                          b'\x06,\x00\x00\x00\x00\x00\x00\x00\x1e\x03-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03'
2626                          b'\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\xcf\x00\x00\x00\x00'
2627                          b'\x00\x00\x00\xd2\x01\x00\x00\x00\x00\x00\x00PK\x06\x07\x00\x00\x00\x00\xa1\x02'
2628                          b'\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05\x06\x00\x00\x00\x00\x03\x00\x03\x00'
2629                          b'\xcf\x00\x00\x00\xd2\x01\x00\x00\x00\x00')
2630
2631        data_le_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2632                       b'\x00\x00\x00\x00\x00\x1c\x00\x06\x00tensor.int16.LE.BOM/data.pklFB\x02\x00ZZ\x80'
2633                       b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
2634                       b'h\nShortStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x10tq\x05'
2635                       b'QK\x00K\x04K\x04\x86q\x06K\x04K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08'
2636                       b')Rq\ttq\nRq\x0b.PK\x07\x08\xf6\xc8K\xd8\x9a\x00\x00\x00\x9a\x00\x00\x00PK\x03\x04'
2637                       b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2638                       b'\x00\x00\x1d\x00\x1b\x00tensor.int16.LE.BOM/byteorderFB\x17\x00ZZZZZZZZZZZZZZZ'
2639                       b'ZZZZZZZZlittlePK\x07\x08\x85=\xe3\x19\x06\x00\x00\x00\x06\x00\x00\x00PK\x03\x04\x00'
2640                       b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2641                       b'\x00\x1a\x002\x00tensor.int16.LE.BOM/data/0FB.\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
2642                       b'ZZZZZZZZZZZZZZZZZZZO\xa4\x9bJ_Z-\xa5#\xf1y\xef\xb1@\x061"\xe3\x83\x07;\x83\x80\x08'
2643                       b'\xf1\x18q\xf6\xfe\xf3\xc9,PK\x07\x08\xa0\x98\xd9\xdf \x00\x00\x00 \x00\x00\x00'
2644                       b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2645                       b'\x00\x00\x00\x00\x1b\x00\x17\x00tensor.int16.LE.BOM/versionFB\x13\x00ZZZZZZZZZ'
2646                       b'ZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00PK\x01\x02\x00\x00'
2647                       b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xf6\xc8K\xd8\x9a\x00\x00\x00\x9a\x00'
2648                       b'\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2649                       b'tensor.int16.LE.BOM/data.pklPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00'
2650                       b'\x00\x85=\xe3\x19\x06\x00\x00\x00\x06\x00\x00\x00\x1d\x00\x00\x00\x00\x00\x00\x00'
2651                       b'\x00\x00\x00\x00\x00\x00\xea\x00\x00\x00tensor.int16.LE.BOM/byteorderPK\x01\x02'
2652                       b'\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xa0\x98\xd9\xdf \x00\x00\x00 '
2653                       b'\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x01\x00\x00'
2654                       b'tensor.int16.LE.BOM/data/0PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00'
2655                       b'\x00\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00'
2656                       b'\x00\x00\x00\x00\x00\xf0\x01\x00\x00tensor.int16.LE.BOM/versionPK\x06\x06,\x00'
2657                       b'\x00\x00\x00\x00\x00\x00\x1e\x03-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00'
2658                       b'\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00&\x01\x00\x00\x00\x00\x00\x00'
2659                       b'R\x02\x00\x00\x00\x00\x00\x00PK\x06\x07\x00\x00\x00\x00x\x03\x00\x00\x00\x00\x00'
2660                       b'\x00\x01\x00\x00\x00PK\x05\x06\x00\x00\x00\x00\x04\x00\x04\x00&\x01\x00\x00R\x02'
2661                       b'\x00\x00\x00\x00')
2662
2663        data_be_no_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2664                          b'\x00\x00\x00\x00\x00\x18\x00\n\x00tensor.int16.BE/data.pklFB\x06\x00ZZZZZZ\x80\x02'
2665                          b'ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorch\n'
2666                          b'ShortStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x10tq\x05Q'
2667                          b'K\x00K\x04K\x04\x86q\x06K\x04K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08)'
2668                          b'Rq\ttq\nRq\x0b.PK\x07\x08\xf6\xc8K\xd8\x9a\x00\x00\x00\x9a\x00\x00\x00PK\x03\x04'
2669                          b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2670                          b'\x00\x00\x16\x00"\x00tensor.int16.BE/data/0FB\x1e\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
2671                          b'ZZZ\xa4OJ\x9bZ_\xa5-\xf1#\xefy@\xb11\x06\xe3"\x07\x83\x83;\x08\x80\x18\xf1\xf6q\xf3'
2672                          b'\xfe,\xc9PK\x07\x08\x8a\xeb\x9b[ \x00\x00\x00 \x00\x00\x00PK\x03\x04\x00\x00\x08'
2673                          b'\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17'
2674                          b'\x00\x1b\x00tensor.int16.BE/versionFB\x17\x00ZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07'
2675                          b'\x08\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08'
2676                          b'\x00\x00\x00\x00\x00\x00\xf6\xc8K\xd8\x9a\x00\x00\x00\x9a\x00\x00\x00\x18\x00\x00'
2677                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00tensor.int16.BE/dat'
2678                          b'a.pklPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x8a\xeb\x9b[ '
2679                          b'\x00\x00\x00 \x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2680                          b'\xea\x00\x00\x00tensor.int16.BE/data/0PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00'
2681                          b'\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00\x17\x00\x00\x00\x00\x00'
2682                          b'\x00\x00\x00\x00\x00\x00\x00\x00p\x01\x00\x00tensor.int16.BE/versionPK\x06\x06'
2683                          b',\x00\x00\x00\x00\x00\x00\x00\x1e\x03-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00'
2684                          b'\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\xcf\x00\x00\x00\x00\x00'
2685                          b'\x00\x00\xd2\x01\x00\x00\x00\x00\x00\x00PK\x06\x07\x00\x00\x00\x00\xa1\x02\x00'
2686                          b'\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05\x06\x00\x00\x00\x00\x03\x00\x03\x00\xcf'
2687                          b'\x00\x00\x00\xd2\x01\x00\x00\x00\x00')
2688
2689        data_be_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2690                       b'\x00\x00\x00\x00\x00\x1c\x00\x06\x00tensor.int16.BE.BOM/data.pklFB\x02\x00ZZ\x80'
2691                       b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
2692                       b'h\nShortStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x10tq\x05'
2693                       b'QK\x00K\x04K\x04\x86q\x06K\x04K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08'
2694                       b')Rq\ttq\nRq\x0b.PK\x07\x08\xf6\xc8K\xd8\x9a\x00\x00\x00\x9a\x00\x00\x00PK\x03\x04'
2695                       b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2696                       b'\x00\x00\x1d\x00\x1b\x00tensor.int16.BE.BOM/byteorderFB\x17\x00ZZZZZZZZZZZZZZZ'
2697                       b'ZZZZZZZZbigPK\x07\x08I\xe2\xfb\xd3\x03\x00\x00\x00\x03\x00\x00\x00PK\x03\x04\x00'
2698                       b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2699                       b'\x00\x1a\x005\x00tensor.int16.BE.BOM/data/0FB1\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
2700                       b'ZZZZZZZZZZZZZZZZZZZ\xa4OJ\x9bZ_\xa5-\xf1#\xefy@\xb11\x06\xe3"\x07\x83\x83;\x08\x80'
2701                       b'\x18\xf1\xf6q\xf3\xfe,\xc9PK\x07\x08\x8a\xeb\x9b[ \x00\x00\x00 \x00\x00\x00PK\x03'
2702                       b'\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2703                       b'\x00\x00\x00\x1b\x00\x17\x00tensor.int16.BE.BOM/versionFB\x13\x00ZZZZZZZZZZZZ'
2704                       b'ZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00PK\x01\x02\x00\x00'
2705                       b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xf6\xc8K\xd8\x9a\x00\x00\x00\x9a\x00\x00'
2706                       b'\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ten'
2707                       b'sor.int16.BE.BOM/data.pklPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00'
2708                       b'I\xe2\xfb\xd3\x03\x00\x00\x00\x03\x00\x00\x00\x1d\x00\x00\x00\x00\x00\x00\x00'
2709                       b'\x00\x00\x00\x00\x00\x00\xea\x00\x00\x00tensor.int16.BE.BOM/byteorderPK\x01\x02\x00'
2710                       b'\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x8a\xeb\x9b[ \x00\x00\x00 \x00\x00'
2711                       b'\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\x01\x00\x00tenso'
2712                       b'r.int16.BE.BOM/data/0PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1'
2713                       b'\x9egU\x02\x00\x00\x00\x02\x00\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2714                       b'\x00\x00\x00\x00\xf0\x01\x00\x00tensor.int16.BE.BOM/versionPK\x06\x06,\x00\x00\x00'
2715                       b'\x00\x00\x00\x00\x1e\x03-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00'
2716                       b'\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00&\x01\x00\x00\x00\x00\x00\x00R\x02'
2717                       b'\x00\x00\x00\x00\x00\x00PK\x06\x07\x00\x00\x00\x00x\x03\x00\x00\x00\x00\x00\x00'
2718                       b'\x01\x00\x00\x00PK\x05\x06\x00\x00\x00\x00\x04\x00\x04\x00&\x01\x00\x00R\x02\x00'
2719                       b'\x00\x00\x00')
2720
2721        current_load_endian = get_default_load_endianness()
2722
2723        buf_le_no_bom = io.BytesIO(data_le_no_bom)
2724        buf_le_bom = io.BytesIO(data_le_bom)
2725        buf_be_no_bom = io.BytesIO(data_be_no_bom)
2726        buf_be_bom = io.BytesIO(data_be_bom)
2727
2728        try:
2729            set_default_load_endianness(LoadEndianness.NATIVE)
2730            tensor_le_no_bom = torch.load(buf_le_no_bom)
2731            tensor_be_no_bom = torch.load(buf_be_no_bom)
2732        finally:
2733            set_default_load_endianness(current_load_endian)
2734
2735        tensor_le_bom = torch.load(buf_le_bom)
2736        tensor_be_bom = torch.load(buf_be_bom)
2737
2738        buf_le_no_bom.seek(0)
2739        buf_be_no_bom.seek(0)
2740
2741        try:
2742            set_default_load_endianness(LoadEndianness.LITTLE)
2743            tensor_le_no_bom_little = torch.load(buf_le_no_bom)
2744            tensor_be_no_bom_little = torch.load(buf_be_no_bom)
2745        finally:
2746            set_default_load_endianness(current_load_endian)
2747
2748        buf_le_no_bom.seek(0)
2749        buf_be_no_bom.seek(0)
2750
2751        try:
2752            set_default_load_endianness(LoadEndianness.BIG)
2753            tensor_le_no_bom_big = torch.load(buf_le_no_bom)
2754            tensor_be_no_bom_big = torch.load(buf_be_no_bom)
2755        finally:
2756            set_default_load_endianness(current_load_endian)
2757
2758        self.assertTrue(torch.equal(tensor_le_bom, tensor_be_bom))
2759        self.assertFalse(torch.equal(tensor_le_no_bom, tensor_be_no_bom))
2760        self.assertTrue(torch.equal(tensor_le_no_bom_little, tensor_le_bom))
2761        self.assertFalse(torch.equal(tensor_be_no_bom_little, tensor_be_bom))
2762        self.assertFalse(torch.equal(tensor_le_no_bom_big, tensor_le_bom))
2763        self.assertTrue(torch.equal(tensor_be_no_bom_big, tensor_be_bom))
2764
2765        if (sys.byteorder == 'little'):
2766            self.assertTrue(torch.equal(tensor_le_no_bom, tensor_le_bom))
2767            self.assertTrue(torch.equal(tensor_le_no_bom, tensor_be_bom))
2768            self.assertFalse(torch.equal(tensor_be_no_bom, tensor_le_bom))
2769            self.assertFalse(torch.equal(tensor_be_no_bom, tensor_be_bom))
2770        else:
2771            self.assertFalse(torch.equal(tensor_le_no_bom, tensor_le_bom))
2772            self.assertFalse(torch.equal(tensor_le_no_bom, tensor_be_bom))
2773            self.assertTrue(torch.equal(tensor_be_no_bom, tensor_le_bom))
2774            self.assertTrue(torch.equal(tensor_be_no_bom, tensor_be_bom))
2775
2776    def test_serialization_load_bom_data_int8(self):
2777        # 1. Generated on LE system using following commands:
2778        #
2779        # import torch
2780        #
2781        # x = torch.randint(-128, 128, [4, 4], dtype=torch.int8)
2782        #
2783        # torch.save(x, "tensor.int8.LE.pt", _disable_byteorder_record=True)
2784        # torch.save(x, "tensor.int8.LE.BOM.pt")
2785        #
2786        # print(x)
2787        #
2788        # 2. After that it is resaved on BE system with following commands:
2789        #
2790        # import torch
2791        #
2792        # x = torch.load('tensor.int8.LE.BOM.pt')
2793        #
2794        # torch.save(x, 'tensor.int8.BE.pt', _disable_byteorder_record=True)
2795        # torch.save(x, 'tensor.int8.BE.BOM.pt')
2796        #
2797        # print(x)
2798        #
2799        # Following commands and a bit of manual work were used to produce python bytes from resulting files:
2800        #
2801        # file = open('filename', 'rb')
2802        # data = file.read()
2803        # file.close()
2804        # print("\n".join(textwrap.wrap(str(data), 80)))
2805        #
2806        # BOM in this context is used as Byte Order Mark.
2807        #
2808        data_le_no_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2809                          b'\x00\x00\x00\x00\x00\x17\x00\x0b\x00tensor.int8.LE/data.pklFB\x07\x00ZZZZZZZ\x80'
2810                          b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
2811                          b'h\nCharStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x10tq\x05'
2812                          b'QK\x00K\x04K\x04\x86q\x06K\x04K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08'
2813                          b')Rq\ttq\nRq\x0b.PK\x07\x08\xdb6\x08\xe7\x99\x00\x00\x00\x99\x00\x00\x00PK\x03\x04'
2814                          b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2815                          b'\x00\x00\x15\x00$\x00tensor.int8.LE/data/0FB \x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
2816                          b'ZZ\x9d\x1en\xb4\xe0l"s\x15bs\x8aa\xa0\xc6+PK\x07\x08\xe0\xffgs\x10\x00\x00\x00\x10'
2817                          b'\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2818                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x16\x00,\x00tensor.int8.LE/versionFB(\x00ZZZZZZ'
2819                          b'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00\x00\x00\x02\x00'
2820                          b'\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xdb6\x08\xe7'
2821                          b'\x99\x00\x00\x00\x99\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2822                          b'\x00\x00\x00\x00\x00\x00tensor.int8.LE/data.pklPK\x01\x02\x00\x00\x00\x00\x08\x08'
2823                          b'\x00\x00\x00\x00\x00\x00\xe0\xffgs\x10\x00\x00\x00\x10\x00\x00\x00\x15\x00\x00\x00'
2824                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe9\x00\x00\x00tensor.int8.LE/data/0'
2825                          b'PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00'
2826                          b'\x00\x02\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`\x01'
2827                          b'\x00\x00tensor.int8.LE/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00\x1e\x03-\x00'
2828                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00'
2829                          b'\x00\x00\x00\x00\xcc\x00\x00\x00\x00\x00\x00\x00\xd2\x01\x00\x00\x00\x00\x00\x00'
2830                          b'PK\x06\x07\x00\x00\x00\x00\x9e\x02\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05'
2831                          b'\x06\x00\x00\x00\x00\x03\x00\x03\x00\xcc\x00\x00\x00\xd2\x01\x00\x00\x00\x00')
2832
2833        data_le_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2834                       b'\x00\x00\x00\x00\x00\x1b\x00\x07\x00tensor.int8.LE.BOM/data.pklFB\x03\x00ZZZ\x80'
2835                       b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
2836                       b'h\nCharStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x10tq\x05'
2837                       b'QK\x00K\x04K\x04\x86q\x06K\x04K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08'
2838                       b')Rq\ttq\nRq\x0b.PK\x07\x08\xdb6\x08\xe7\x99\x00\x00\x00\x99\x00\x00\x00PK\x03\x04'
2839                       b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2840                       b'\x00\x00\x1c\x00\x1d\x00tensor.int8.LE.BOM/byteorderFB\x19\x00ZZZZZZZZZZZZZZZZZ'
2841                       b'ZZZZZZZZlittlePK\x07\x08\x85=\xe3\x19\x06\x00\x00\x00\x06\x00\x00\x00PK\x03\x04\x00'
2842                       b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2843                       b'\x00\x19\x003\x00tensor.int8.LE.BOM/data/0FB/\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
2844                       b'ZZZZZZZZZZZZZZZZZZZ\x9d\x1en\xb4\xe0l"s\x15bs\x8aa\xa0\xc6+PK\x07\x08\xe0\xffgs\x10'
2845                       b'\x00\x00\x00\x10\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00'
2846                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1a\x00(\x00tensor.int8.LE.BOM'
2847                       b'/versionFB$\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00'
2848                       b'\x00\x00\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00'
2849                       b'\x00\xdb6\x08\xe7\x99\x00\x00\x00\x99\x00\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00'
2850                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00tensor.int8.LE.BOM/data.pklPK\x01\x02\x00'
2851                       b'\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x85=\xe3\x19\x06\x00\x00\x00\x06\x00'
2852                       b'\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe9\x00\x00\x00'
2853                       b'tensor.int8.LE.BOM/byteorderPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00'
2854                       b'\x00\x00\xe0\xffgs\x10\x00\x00\x00\x10\x00\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00'
2855                       b'\x00\x00\x00\x00\x00\x00V\x01\x00\x00tensor.int8.LE.BOM/data/0PK\x01\x02\x00\x00'
2856                       b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00'
2857                       b'\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x01\x00\x00ten'
2858                       b'sor.int8.LE.BOM/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00\x1e\x03-\x00\x00\x00'
2859                       b'\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00'
2860                       b'\x00\x00"\x01\x00\x00\x00\x00\x00\x00R\x02\x00\x00\x00\x00\x00\x00PK\x06\x07\x00'
2861                       b'\x00\x00\x00t\x03\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05\x06\x00\x00\x00'
2862                       b'\x00\x04\x00\x04\x00"\x01\x00\x00R\x02\x00\x00\x00\x00')
2863
2864        data_be_no_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2865                          b'\x00\x00\x00\x00\x00\x17\x00\x0b\x00tensor.int8.BE/data.pklFB\x07\x00ZZZZZZZ\x80'
2866                          b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
2867                          b'h\nCharStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x10tq\x05'
2868                          b'QK\x00K\x04K\x04\x86q\x06K\x04K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08'
2869                          b')Rq\ttq\nRq\x0b.PK\x07\x08\xdb6\x08\xe7\x99\x00\x00\x00\x99\x00\x00\x00PK\x03\x04'
2870                          b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2871                          b'\x00\x00\x15\x00$\x00tensor.int8.BE/data/0FB \x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
2872                          b'ZZ\x9d\x1en\xb4\xe0l"s\x15bs\x8aa\xa0\xc6+PK\x07\x08\xe0\xffgs\x10\x00\x00\x00\x10'
2873                          b'\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2874                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x16\x00,\x00tensor.int8.BE/versionFB(\x00ZZZZZZ'
2875                          b'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00\x00\x00\x02\x00'
2876                          b'\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xdb6\x08\xe7'
2877                          b'\x99\x00\x00\x00\x99\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2878                          b'\x00\x00\x00\x00\x00\x00tensor.int8.BE/data.pklPK\x01\x02\x00\x00\x00\x00\x08\x08'
2879                          b'\x00\x00\x00\x00\x00\x00\xe0\xffgs\x10\x00\x00\x00\x10\x00\x00\x00\x15\x00\x00\x00'
2880                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe9\x00\x00\x00tensor.int8.BE/data/0'
2881                          b'PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00'
2882                          b'\x00\x02\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`\x01'
2883                          b'\x00\x00tensor.int8.BE/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00\x1e\x03-\x00'
2884                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00'
2885                          b'\x00\x00\x00\x00\xcc\x00\x00\x00\x00\x00\x00\x00\xd2\x01\x00\x00\x00\x00\x00\x00'
2886                          b'PK\x06\x07\x00\x00\x00\x00\x9e\x02\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05'
2887                          b'\x06\x00\x00\x00\x00\x03\x00\x03\x00\xcc\x00\x00\x00\xd2\x01\x00\x00\x00\x00')
2888
2889        data_be_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2890                       b'\x00\x00\x00\x00\x00\x1b\x00\x07\x00tensor.int8.BE.BOM/data.pklFB\x03\x00ZZZ\x80'
2891                       b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
2892                       b'h\nCharStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x10tq\x05'
2893                       b'QK\x00K\x04K\x04\x86q\x06K\x04K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08'
2894                       b')Rq\ttq\nRq\x0b.PK\x07\x08\xdb6\x08\xe7\x99\x00\x00\x00\x99\x00\x00\x00PK\x03\x04'
2895                       b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2896                       b'\x00\x00\x1c\x00\x1d\x00tensor.int8.BE.BOM/byteorderFB\x19\x00ZZZZZZZZZZZZZZZZZ'
2897                       b'ZZZZZZZZbigPK\x07\x08I\xe2\xfb\xd3\x03\x00\x00\x00\x03\x00\x00\x00PK\x03\x04\x00'
2898                       b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
2899                       b'\x00\x19\x006\x00tensor.int8.BE.BOM/data/0FB2\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
2900                       b'ZZZZZZZZZZZZZZZZZZZ\x9d\x1en\xb4\xe0l"s\x15bs\x8aa\xa0\xc6+PK\x07\x08\xe0\xffgs\x10'
2901                       b'\x00\x00\x00\x10\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00'
2902                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1a\x00(\x00tensor.int8.BE.BOM'
2903                       b'/versionFB$\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00'
2904                       b'\x00\x00\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00'
2905                       b'\x00\xdb6\x08\xe7\x99\x00\x00\x00\x99\x00\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00'
2906                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00tensor.int8.BE.BOM/data.pklPK\x01\x02\x00'
2907                       b'\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00I\xe2\xfb\xd3\x03\x00\x00\x00\x03\x00'
2908                       b'\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe9\x00\x00\x00'
2909                       b'tensor.int8.BE.BOM/byteorderPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00'
2910                       b'\x00\x00\xe0\xffgs\x10\x00\x00\x00\x10\x00\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00'
2911                       b'\x00\x00\x00\x00\x00\x00S\x01\x00\x00tensor.int8.BE.BOM/data/0PK\x01\x02\x00\x00'
2912                       b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00'
2913                       b'\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x01\x00\x00ten'
2914                       b'sor.int8.BE.BOM/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00\x1e\x03-\x00\x00\x00'
2915                       b'\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00'
2916                       b'\x00\x00"\x01\x00\x00\x00\x00\x00\x00R\x02\x00\x00\x00\x00\x00\x00PK\x06\x07\x00'
2917                       b'\x00\x00\x00t\x03\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05\x06\x00\x00\x00'
2918                       b'\x00\x04\x00\x04\x00"\x01\x00\x00R\x02\x00\x00\x00\x00')
2919
2920        current_load_endian = get_default_load_endianness()
2921
2922        buf_le_no_bom = io.BytesIO(data_le_no_bom)
2923        buf_le_bom = io.BytesIO(data_le_bom)
2924        buf_be_no_bom = io.BytesIO(data_be_no_bom)
2925        buf_be_bom = io.BytesIO(data_be_bom)
2926
2927        try:
2928            set_default_load_endianness(LoadEndianness.NATIVE)
2929            tensor_le_no_bom = torch.load(buf_le_no_bom)
2930            tensor_be_no_bom = torch.load(buf_be_no_bom)
2931        finally:
2932            set_default_load_endianness(current_load_endian)
2933
2934        tensor_le_bom = torch.load(buf_le_bom)
2935        tensor_be_bom = torch.load(buf_be_bom)
2936
2937        buf_le_no_bom.seek(0)
2938        buf_be_no_bom.seek(0)
2939
2940        try:
2941            set_default_load_endianness(LoadEndianness.LITTLE)
2942            tensor_le_no_bom_little = torch.load(buf_le_no_bom)
2943            tensor_be_no_bom_little = torch.load(buf_be_no_bom)
2944        finally:
2945            set_default_load_endianness(current_load_endian)
2946
2947        buf_le_no_bom.seek(0)
2948        buf_be_no_bom.seek(0)
2949
2950        try:
2951            set_default_load_endianness(LoadEndianness.BIG)
2952            tensor_le_no_bom_big = torch.load(buf_le_no_bom)
2953            tensor_be_no_bom_big = torch.load(buf_be_no_bom)
2954        finally:
2955            set_default_load_endianness(current_load_endian)
2956
2957        # 1-byte types are same on BE and LE
2958        self.assertTrue(torch.equal(tensor_le_bom, tensor_be_bom))
2959        self.assertTrue(torch.equal(tensor_le_no_bom, tensor_be_no_bom))
2960        self.assertTrue(torch.equal(tensor_le_no_bom, tensor_le_bom))
2961        self.assertTrue(torch.equal(tensor_le_no_bom, tensor_be_bom))
2962        self.assertTrue(torch.equal(tensor_be_no_bom, tensor_le_bom))
2963        self.assertTrue(torch.equal(tensor_be_no_bom, tensor_be_bom))
2964        self.assertTrue(torch.equal(tensor_le_no_bom_little, tensor_le_bom))
2965        self.assertTrue(torch.equal(tensor_be_no_bom_little, tensor_be_bom))
2966        self.assertTrue(torch.equal(tensor_le_no_bom_big, tensor_le_bom))
2967        self.assertTrue(torch.equal(tensor_be_no_bom_big, tensor_be_bom))
2968
2969    def test_serialization_load_bom_data_uint8(self):
2970        # 1. Generated on LE system using following commands:
2971        #
2972        # import torch
2973        #
2974        # x = torch.randint(0, 256, [4, 4], dtype=torch.uint8)
2975        #
2976        # torch.save(x, "tensor.uint8.LE.pt", _disable_byteorder_record=True)
2977        # torch.save(x, "tensor.uint8.LE.BOM.pt")
2978        #
2979        # print(x)
2980        #
2981        # 2. After that it is resaved on BE system with following commands:
2982        #
2983        # import torch
2984        #
2985        # x = torch.load('tensor.uint8.LE.BOM.pt')
2986        #
2987        # torch.save(x, 'tensor.uint8.BE.pt', _disable_byteorder_record=True)
2988        # torch.save(x, 'tensor.uint8.BE.BOM.pt')
2989        #
2990        # print(x)
2991        #
2992        # Following commands and a bit of manual work were used to produce python bytes from resulting files:
2993        #
2994        # file = open('filename', 'rb')
2995        # data = file.read()
2996        # file.close()
2997        # print("\n".join(textwrap.wrap(str(data), 80)))
2998        #
2999        # BOM in this context is used as Byte Order Mark.
3000        #
3001        data_le_no_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3002                          b'\x00\x00\x00\x00\x00\x18\x00\n\x00tensor.uint8.LE/data.pklFB\x06\x00ZZZZZZ\x80\x02'
3003                          b'ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorch\n'
3004                          b'ByteStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x10tq\x05QK'
3005                          b'\x00K\x04K\x04\x86q\x06K\x04K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08)R'
3006                          b'q\ttq\nRq\x0b.PK\x07\x08\xff\xb9!\x97\x99\x00\x00\x00\x99\x00\x00\x00PK\x03\x04\x00'
3007                          b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3008                          b'\x00\x16\x00#\x00tensor.uint8.LE/data/0FB\x1f\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
3009                          b'ZZZ\xf7\xf20\x04\t\x8a!\xbev\xf4\xbe\x0e";\xbb\tPK\x07\x08\xa8\x94#\x08\x10\x00\x00'
3010                          b'\x00\x10\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00'
3011                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\x00+\x00tensor.uint8.LE/versionFB\''
3012                          b'\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00\x00\x00'
3013                          b'\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xff'
3014                          b'\xb9!\x97\x99\x00\x00\x00\x99\x00\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3015                          b'\x00\x00\x00\x00\x00\x00\x00\x00tensor.uint8.LE/data.pklPK\x01\x02\x00\x00\x00'
3016                          b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\xa8\x94#\x08\x10\x00\x00\x00\x10\x00\x00\x00'
3017                          b'\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe9\x00\x00\x00tensor.'
3018                          b'uint8.LE/data/0PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9e'
3019                          b'gU\x02\x00\x00\x00\x02\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3020                          b'\x00\x00`\x01\x00\x00tensor.uint8.LE/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00'
3021                          b'\x00\x1e\x03-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00'
3022                          b'\x03\x00\x00\x00\x00\x00\x00\x00\xcf\x00\x00\x00\x00\x00\x00\x00\xd2\x01\x00\x00'
3023                          b'\x00\x00\x00\x00PK\x06\x07\x00\x00\x00\x00\xa1\x02\x00\x00\x00\x00\x00\x00\x01'
3024                          b'\x00\x00\x00PK\x05\x06\x00\x00\x00\x00\x03\x00\x03\x00\xcf\x00\x00\x00\xd2\x01\x00'
3025                          b'\x00\x00\x00')
3026
3027        data_le_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3028                       b'\x00\x00\x00\x00\x00\x1c\x00\x06\x00tensor.uint8.LE.BOM/data.pklFB\x02\x00ZZ\x80'
3029                       b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
3030                       b'h\nByteStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x10tq\x05'
3031                       b'QK\x00K\x04K\x04\x86q\x06K\x04K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08'
3032                       b')Rq\ttq\nRq\x0b.PK\x07\x08\xff\xb9!\x97\x99\x00\x00\x00\x99\x00\x00\x00PK\x03\x04'
3033                       b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3034                       b'\x00\x00\x1d\x00\x1c\x00tensor.uint8.LE.BOM/byteorderFB\x18\x00ZZZZZZZZZZZZZZZZ'
3035                       b'ZZZZZZZZlittlePK\x07\x08\x85=\xe3\x19\x06\x00\x00\x00\x06\x00\x00\x00PK\x03\x04\x00'
3036                       b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3037                       b'\x00\x1a\x002\x00tensor.uint8.LE.BOM/data/0FB.\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
3038                       b'ZZZZZZZZZZZZZZZZZZZ\xf7\xf20\x04\t\x8a!\xbev\xf4\xbe\x0e";\xbb\tPK\x07\x08\xa8\x94'
3039                       b'#\x08\x10\x00\x00\x00\x10\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00'
3040                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\x00\'\x00tensor.ui'
3041                       b'nt8.LE.BOM/versionFB#\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9e'
3042                       b'gU\x02\x00\x00\x00\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00'
3043                       b'\x00\x00\x00\xff\xb9!\x97\x99\x00\x00\x00\x99\x00\x00\x00\x1c\x00\x00\x00\x00\x00'
3044                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00tensor.uint8.LE.BOM/data.pklPK'
3045                       b'\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x85=\xe3\x19\x06\x00\x00'
3046                       b'\x00\x06\x00\x00\x00\x1d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe9'
3047                       b'\x00\x00\x00tensor.uint8.LE.BOM/byteorderPK\x01\x02\x00\x00\x00\x00\x08\x08\x00'
3048                       b'\x00\x00\x00\x00\x00\xa8\x94#\x08\x10\x00\x00\x00\x10\x00\x00\x00\x1a\x00\x00\x00'
3049                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x01\x00\x00tensor.uint8.LE.BOM/data/0'
3050                       b'PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00'
3051                       b'\x00\x02\x00\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0'
3052                       b'\x01\x00\x00tensor.uint8.LE.BOM/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00\x1e'
3053                       b'\x03-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00'
3054                       b'\x00\x00\x00\x00\x00\x00&\x01\x00\x00\x00\x00\x00\x00R\x02\x00\x00\x00\x00\x00'
3055                       b'\x00PK\x06\x07\x00\x00\x00\x00x\x03\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05'
3056                       b'\x06\x00\x00\x00\x00\x04\x00\x04\x00&\x01\x00\x00R\x02\x00\x00\x00\x00')
3057
3058        data_be_no_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3059                          b'\x00\x00\x00\x00\x00\x18\x00\n\x00tensor.uint8.BE/data.pklFB\x06\x00ZZZZZZ\x80\x02'
3060                          b'ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorch\n'
3061                          b'ByteStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x10tq\x05QK'
3062                          b'\x00K\x04K\x04\x86q\x06K\x04K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08)R'
3063                          b'q\ttq\nRq\x0b.PK\x07\x08\xff\xb9!\x97\x99\x00\x00\x00\x99\x00\x00\x00PK\x03\x04\x00'
3064                          b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3065                          b'\x00\x16\x00#\x00tensor.uint8.BE/data/0FB\x1f\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
3066                          b'ZZZ\xf7\xf20\x04\t\x8a!\xbev\xf4\xbe\x0e";\xbb\tPK\x07\x08\xa8\x94#\x08\x10\x00\x00'
3067                          b'\x00\x10\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00'
3068                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\x00+\x00tensor.uint8.BE/versionFB\''
3069                          b'\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00\x00\x00'
3070                          b'\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xff'
3071                          b'\xb9!\x97\x99\x00\x00\x00\x99\x00\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3072                          b'\x00\x00\x00\x00\x00\x00\x00\x00tensor.uint8.BE/data.pklPK\x01\x02\x00\x00\x00'
3073                          b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\xa8\x94#\x08\x10\x00\x00\x00\x10\x00\x00\x00'
3074                          b'\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe9\x00\x00\x00tensor.'
3075                          b'uint8.BE/data/0PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9e'
3076                          b'gU\x02\x00\x00\x00\x02\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3077                          b'\x00\x00`\x01\x00\x00tensor.uint8.BE/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00'
3078                          b'\x00\x1e\x03-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00'
3079                          b'\x03\x00\x00\x00\x00\x00\x00\x00\xcf\x00\x00\x00\x00\x00\x00\x00\xd2\x01\x00\x00'
3080                          b'\x00\x00\x00\x00PK\x06\x07\x00\x00\x00\x00\xa1\x02\x00\x00\x00\x00\x00\x00\x01'
3081                          b'\x00\x00\x00PK\x05\x06\x00\x00\x00\x00\x03\x00\x03\x00\xcf\x00\x00\x00\xd2\x01\x00'
3082                          b'\x00\x00\x00')
3083
3084        data_be_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3085                       b'\x00\x00\x00\x00\x00\x1c\x00\x06\x00tensor.uint8.BE.BOM/data.pklFB\x02\x00ZZ\x80'
3086                       b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
3087                       b'h\nByteStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x10tq\x05'
3088                       b'QK\x00K\x04K\x04\x86q\x06K\x04K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08'
3089                       b')Rq\ttq\nRq\x0b.PK\x07\x08\xff\xb9!\x97\x99\x00\x00\x00\x99\x00\x00\x00PK\x03\x04'
3090                       b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3091                       b'\x00\x00\x1d\x00\x1c\x00tensor.uint8.BE.BOM/byteorderFB\x18\x00ZZZZZZZZZZZZZZZZ'
3092                       b'ZZZZZZZZbigPK\x07\x08I\xe2\xfb\xd3\x03\x00\x00\x00\x03\x00\x00\x00PK\x03\x04\x00'
3093                       b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3094                       b'\x00\x1a\x005\x00tensor.uint8.BE.BOM/data/0FB1\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
3095                       b'ZZZZZZZZZZZZZZZZZZZ\xf7\xf20\x04\t\x8a!\xbev\xf4\xbe\x0e";\xbb\tPK\x07\x08\xa8\x94'
3096                       b'#\x08\x10\x00\x00\x00\x10\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00'
3097                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\x00\'\x00tensor.ui'
3098                       b'nt8.BE.BOM/versionFB#\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9e'
3099                       b'gU\x02\x00\x00\x00\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00'
3100                       b'\x00\x00\x00\xff\xb9!\x97\x99\x00\x00\x00\x99\x00\x00\x00\x1c\x00\x00\x00\x00\x00'
3101                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00tensor.uint8.BE.BOM/data.pklPK'
3102                       b'\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00I\xe2\xfb\xd3\x03\x00\x00'
3103                       b'\x00\x03\x00\x00\x00\x1d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe9'
3104                       b'\x00\x00\x00tensor.uint8.BE.BOM/byteorderPK\x01\x02\x00\x00\x00\x00\x08\x08\x00'
3105                       b'\x00\x00\x00\x00\x00\xa8\x94#\x08\x10\x00\x00\x00\x10\x00\x00\x00\x1a\x00\x00\x00'
3106                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\x01\x00\x00tensor.uint8.BE.BOM/data/0'
3107                       b'PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00'
3108                       b'\x00\x02\x00\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0'
3109                       b'\x01\x00\x00tensor.uint8.BE.BOM/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00\x1e'
3110                       b'\x03-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00'
3111                       b'\x00\x00\x00\x00\x00\x00&\x01\x00\x00\x00\x00\x00\x00R\x02\x00\x00\x00\x00\x00'
3112                       b'\x00PK\x06\x07\x00\x00\x00\x00x\x03\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05'
3113                       b'\x06\x00\x00\x00\x00\x04\x00\x04\x00&\x01\x00\x00R\x02\x00\x00\x00\x00')
3114
3115        current_load_endian = get_default_load_endianness()
3116
3117        buf_le_no_bom = io.BytesIO(data_le_no_bom)
3118        buf_le_bom = io.BytesIO(data_le_bom)
3119        buf_be_no_bom = io.BytesIO(data_be_no_bom)
3120        buf_be_bom = io.BytesIO(data_be_bom)
3121
3122        try:
3123            set_default_load_endianness(LoadEndianness.NATIVE)
3124            tensor_le_no_bom = torch.load(buf_le_no_bom)
3125            tensor_be_no_bom = torch.load(buf_be_no_bom)
3126        finally:
3127            set_default_load_endianness(current_load_endian)
3128
3129        tensor_le_bom = torch.load(buf_le_bom)
3130        tensor_be_bom = torch.load(buf_be_bom)
3131
3132        buf_le_no_bom.seek(0)
3133        buf_be_no_bom.seek(0)
3134
3135        try:
3136            set_default_load_endianness(LoadEndianness.LITTLE)
3137            tensor_le_no_bom_little = torch.load(buf_le_no_bom)
3138            tensor_be_no_bom_little = torch.load(buf_be_no_bom)
3139        finally:
3140            set_default_load_endianness(current_load_endian)
3141
3142        buf_le_no_bom.seek(0)
3143        buf_be_no_bom.seek(0)
3144
3145        try:
3146            set_default_load_endianness(LoadEndianness.BIG)
3147            tensor_le_no_bom_big = torch.load(buf_le_no_bom)
3148            tensor_be_no_bom_big = torch.load(buf_be_no_bom)
3149        finally:
3150            set_default_load_endianness(current_load_endian)
3151
3152        # 1-byte types are same on BE and LE
3153        self.assertTrue(torch.equal(tensor_le_bom, tensor_be_bom))
3154        self.assertTrue(torch.equal(tensor_le_no_bom, tensor_be_no_bom))
3155        self.assertTrue(torch.equal(tensor_le_no_bom, tensor_le_bom))
3156        self.assertTrue(torch.equal(tensor_le_no_bom, tensor_be_bom))
3157        self.assertTrue(torch.equal(tensor_be_no_bom, tensor_le_bom))
3158        self.assertTrue(torch.equal(tensor_be_no_bom, tensor_be_bom))
3159        self.assertTrue(torch.equal(tensor_le_no_bom_little, tensor_le_bom))
3160        self.assertTrue(torch.equal(tensor_be_no_bom_little, tensor_be_bom))
3161        self.assertTrue(torch.equal(tensor_le_no_bom_big, tensor_le_bom))
3162        self.assertTrue(torch.equal(tensor_be_no_bom_big, tensor_be_bom))
3163
3164    def test_serialization_load_bom_data_bool(self):
3165        # 1. Generated on LE system using following commands:
3166        #
3167        # import torch
3168        #
3169        # x = torch.randint(0, 2, [4, 4], dtype=torch.bool)
3170        #
3171        # torch.save(x, "tensor.bool.LE.pt", _disable_byteorder_record=True)
3172        # torch.save(x, "tensor.bool.LE.BOM.pt")
3173        #
3174        # print(x)
3175        #
3176        # 2. After that it is resaved on BE system with following commands:
3177        #
3178        # import torch
3179        #
3180        # x = torch.load('tensor.bool.LE.BOM.pt')
3181        #
3182        # torch.save(x, 'tensor.bool.BE.pt', _disable_byteorder_record=True)
3183        # torch.save(x, 'tensor.bool.BE.BOM.pt')
3184        #
3185        # print(x)
3186        #
3187        # Following commands and a bit of manual work were used to produce python bytes from resulting files:
3188        #
3189        # file = open('filename', 'rb')
3190        # data = file.read()
3191        # file.close()
3192        # print("\n".join(textwrap.wrap(str(data), 80)))
3193        #
3194        # BOM in this context is used as Byte Order Mark.
3195        #
3196        data_le_no_bom = (b"PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
3197                          b"\x00\x00\x00\x00\x00\x17\x00\x0b\x00tensor.bool.LE/data.pklFB\x07\x00ZZZZZZZ\x80"
3198                          b"\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc"
3199                          b"h\nBoolStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x10tq\x05"
3200                          b"QK\x00K\x04K\x04\x86q\x06K\x04K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08"
3201                          b")Rq\ttq\nRq\x0b.PK\x07\x08\x9a\xab='\x99\x00\x00\x00\x99\x00\x00\x00PK\x03\x04\x00"
3202                          b"\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
3203                          b"\x00\x15\x00$\x00tensor.bool.LE/data/0FB \x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ\x01"
3204                          b"\x00\x00\x01\x00\x01\x00\x00\x00\x00\x01\x00\x01\x00\x01\x00PK\x07\x08\x00Y04"
3205                          b"\x10\x00\x00\x00\x10\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00"
3206                          b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16\x00,\x00tensor.bool.LE/ve"
3207                          b"rsionFB(\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00"
3208                          b"\x00\x00\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00"
3209                          b"\x00\x9a\xab='\x99\x00\x00\x00\x99\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x00"
3210                          b"\x00\x00\x00\x00\x00\x00\x00\x00\x00tensor.bool.LE/data.pklPK\x01\x02\x00\x00"
3211                          b"\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00Y04\x10\x00\x00\x00\x10\x00\x00\x00\x15"
3212                          b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe9\x00\x00\x00tensor.bo"
3213                          b"ol.LE/data/0PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU"
3214                          b"\x02\x00\x00\x00\x02\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
3215                          b"\x00\x00`\x01\x00\x00tensor.bool.LE/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00"
3216                          b"\x1e\x03-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x03"
3217                          b"\x00\x00\x00\x00\x00\x00\x00\xcc\x00\x00\x00\x00\x00\x00\x00\xd2\x01\x00\x00\x00"
3218                          b"\x00\x00\x00PK\x06\x07\x00\x00\x00\x00\x9e\x02\x00\x00\x00\x00\x00\x00\x01\x00"
3219                          b"\x00\x00PK\x05\x06\x00\x00\x00\x00\x03\x00\x03\x00\xcc\x00\x00\x00\xd2\x01\x00\x00"
3220                          b"\x00\x00")
3221
3222        data_le_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3223                       b'\x00\x00\x00\x00\x00\x1b\x00\x07\x00tensor.bool.LE.BOM/data.pklFB\x03\x00ZZZ\x80'
3224                       b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
3225                       b'h\nBoolStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x10tq\x05'
3226                       b'QK\x00K\x04K\x04\x86q\x06K\x04K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08'
3227                       b')Rq\ttq\nRq\x0b.PK\x07\x08\x9a\xab=\'\x99\x00\x00\x00\x99\x00\x00\x00PK\x03\x04\x00'
3228                       b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3229                       b'\x00\x1c\x00\x1d\x00tensor.bool.LE.BOM/byteorderFB\x19\x00ZZZZZZZZZZZZZZZZZZZ'
3230                       b'ZZZZZZlittlePK\x07\x08\x85=\xe3\x19\x06\x00\x00\x00\x06\x00\x00\x00PK\x03\x04\x00'
3231                       b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3232                       b'\x00\x19\x003\x00tensor.bool.LE.BOM/data/0FB/\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
3233                       b'ZZZZZZZZZZZZZZZZZ\x01\x00\x00\x01\x00\x01\x00\x00\x00\x00\x01\x00\x01\x00\x01\x00'
3234                       b'PK\x07\x08\x00Y04\x10\x00\x00\x00\x10\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00'
3235                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1a\x00(\x00'
3236                       b'tensor.bool.LE.BOM/versionFB$\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08'
3237                       b'\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00'
3238                       b'\x00\x00\x00\x00\x00\x9a\xab=\'\x99\x00\x00\x00\x99\x00\x00\x00\x1b\x00\x00\x00'
3239                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00tensor.bool.LE.BOM/dat'
3240                       b'a.pklPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x85=\xe3\x19\x06'
3241                       b'\x00\x00\x00\x06\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3242                       b'\x00\xe9\x00\x00\x00tensor.bool.LE.BOM/byteorderPK\x01\x02\x00\x00\x00\x00\x08\x08'
3243                       b'\x00\x00\x00\x00\x00\x00\x00Y04\x10\x00\x00\x00\x10\x00\x00\x00\x19\x00\x00\x00'
3244                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x01\x00\x00tensor.bool.LE.BOM/data/0P'
3245                       b'K\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00\x00'
3246                       b'\x02\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x01'
3247                       b'\x00\x00tensor.bool.LE.BOM/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00\x1e'
3248                       b'\x03-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00'
3249                       b'\x00\x00\x00\x00\x00\x00"\x01\x00\x00\x00\x00\x00\x00R\x02\x00\x00\x00\x00\x00\x00'
3250                       b'PK\x06\x07\x00\x00\x00\x00t\x03\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05'
3251                       b'\x06\x00\x00\x00\x00\x04\x00\x04\x00"\x01\x00\x00R\x02\x00\x00\x00\x00')
3252
3253        data_be_no_bom = (b"PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
3254                          b"\x00\x00\x00\x00\x00\x17\x00\x0b\x00tensor.bool.BE/data.pklFB\x07\x00ZZZZZZZ\x80"
3255                          b"\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc"
3256                          b"h\nBoolStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x10tq\x05"
3257                          b"QK\x00K\x04K\x04\x86q\x06K\x04K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08"
3258                          b")Rq\ttq\nRq\x0b.PK\x07\x08\x9a\xab='\x99\x00\x00\x00\x99\x00\x00\x00PK\x03\x04\x00"
3259                          b"\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
3260                          b"\x00\x15\x00$\x00tensor.bool.BE/data/0FB \x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ\x01"
3261                          b"\x00\x00\x01\x00\x01\x00\x00\x00\x00\x01\x00\x01\x00\x01\x00PK\x07\x08\x00Y04"
3262                          b"\x10\x00\x00\x00\x10\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00"
3263                          b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16\x00,\x00tensor.bool.BE/ve"
3264                          b"rsionFB(\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00"
3265                          b"\x00\x00\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00"
3266                          b"\x00\x9a\xab='\x99\x00\x00\x00\x99\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x00"
3267                          b"\x00\x00\x00\x00\x00\x00\x00\x00\x00tensor.bool.BE/data.pklPK\x01\x02\x00\x00"
3268                          b"\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00Y04\x10\x00\x00\x00\x10\x00\x00\x00\x15"
3269                          b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe9\x00\x00\x00tensor.bo"
3270                          b"ol.BE/data/0PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU"
3271                          b"\x02\x00\x00\x00\x02\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
3272                          b"\x00\x00`\x01\x00\x00tensor.bool.BE/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00"
3273                          b"\x1e\x03-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x03"
3274                          b"\x00\x00\x00\x00\x00\x00\x00\xcc\x00\x00\x00\x00\x00\x00\x00\xd2\x01\x00\x00\x00"
3275                          b"\x00\x00\x00PK\x06\x07\x00\x00\x00\x00\x9e\x02\x00\x00\x00\x00\x00\x00\x01\x00"
3276                          b"\x00\x00PK\x05\x06\x00\x00\x00\x00\x03\x00\x03\x00\xcc\x00\x00\x00\xd2\x01\x00\x00"
3277                          b"\x00\x00")
3278
3279        data_be_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3280                       b'\x00\x00\x00\x00\x00\x1b\x00\x07\x00tensor.bool.BE.BOM/data.pklFB\x03\x00ZZZ\x80'
3281                       b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
3282                       b'h\nBoolStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x10tq\x05'
3283                       b'QK\x00K\x04K\x04\x86q\x06K\x04K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08'
3284                       b')Rq\ttq\nRq\x0b.PK\x07\x08\x9a\xab=\'\x99\x00\x00\x00\x99\x00\x00\x00PK\x03\x04\x00'
3285                       b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3286                       b'\x00\x1c\x00\x1d\x00tensor.bool.BE.BOM/byteorderFB\x19\x00ZZZZZZZZZZZZZZZZZZZ'
3287                       b'ZZZZZZbigPK\x07\x08I\xe2\xfb\xd3\x03\x00\x00\x00\x03\x00\x00\x00PK\x03\x04\x00\x00'
3288                       b'\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3289                       b'\x19\x006\x00tensor.bool.BE.BOM/data/0FB2\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
3290                       b'ZZZZZZZZZZZZZZZZZ\x01\x00\x00\x01\x00\x01\x00\x00\x00\x00\x01\x00\x01\x00\x01\x00'
3291                       b'PK\x07\x08\x00Y04\x10\x00\x00\x00\x10\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00'
3292                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1a\x00(\x00'
3293                       b'tensor.bool.BE.BOM/versionFB$\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08'
3294                       b'\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00'
3295                       b'\x00\x00\x00\x00\x00\x9a\xab=\'\x99\x00\x00\x00\x99\x00\x00\x00\x1b\x00\x00\x00'
3296                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00tensor.bool.BE.BOM/dat'
3297                       b'a.pklPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00I\xe2\xfb\xd3\x03'
3298                       b'\x00\x00\x00\x03\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3299                       b'\x00\xe9\x00\x00\x00tensor.bool.BE.BOM/byteorderPK\x01\x02\x00\x00\x00\x00\x08\x08'
3300                       b'\x00\x00\x00\x00\x00\x00\x00Y04\x10\x00\x00\x00\x10\x00\x00\x00\x19\x00\x00\x00'
3301                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\x01\x00\x00tensor.bool.BE.BOM/data/0P'
3302                       b'K\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00\x00'
3303                       b'\x02\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x01'
3304                       b'\x00\x00tensor.bool.BE.BOM/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00\x1e'
3305                       b'\x03-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00'
3306                       b'\x00\x00\x00\x00\x00\x00"\x01\x00\x00\x00\x00\x00\x00R\x02\x00\x00\x00\x00\x00\x00'
3307                       b'PK\x06\x07\x00\x00\x00\x00t\x03\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05'
3308                       b'\x06\x00\x00\x00\x00\x04\x00\x04\x00"\x01\x00\x00R\x02\x00\x00\x00\x00')
3309
3310        current_load_endian = get_default_load_endianness()
3311
3312        buf_le_no_bom = io.BytesIO(data_le_no_bom)
3313        buf_le_bom = io.BytesIO(data_le_bom)
3314        buf_be_no_bom = io.BytesIO(data_be_no_bom)
3315        buf_be_bom = io.BytesIO(data_be_bom)
3316
3317        try:
3318            set_default_load_endianness(LoadEndianness.NATIVE)
3319            tensor_le_no_bom = torch.load(buf_le_no_bom)
3320            tensor_be_no_bom = torch.load(buf_be_no_bom)
3321        finally:
3322            set_default_load_endianness(current_load_endian)
3323
3324        tensor_le_bom = torch.load(buf_le_bom)
3325        tensor_be_bom = torch.load(buf_be_bom)
3326
3327        buf_le_no_bom.seek(0)
3328        buf_be_no_bom.seek(0)
3329
3330        try:
3331            set_default_load_endianness(LoadEndianness.LITTLE)
3332            tensor_le_no_bom_little = torch.load(buf_le_no_bom)
3333            tensor_be_no_bom_little = torch.load(buf_be_no_bom)
3334        finally:
3335            set_default_load_endianness(current_load_endian)
3336
3337        buf_le_no_bom.seek(0)
3338        buf_be_no_bom.seek(0)
3339
3340        try:
3341            set_default_load_endianness(LoadEndianness.BIG)
3342            tensor_le_no_bom_big = torch.load(buf_le_no_bom)
3343            tensor_be_no_bom_big = torch.load(buf_be_no_bom)
3344        finally:
3345            set_default_load_endianness(current_load_endian)
3346
3347        # 1-byte types are same on BE and LE
3348        self.assertTrue(torch.equal(tensor_le_bom, tensor_be_bom))
3349        self.assertTrue(torch.equal(tensor_le_no_bom, tensor_be_no_bom))
3350        self.assertTrue(torch.equal(tensor_le_no_bom, tensor_le_bom))
3351        self.assertTrue(torch.equal(tensor_le_no_bom, tensor_be_bom))
3352        self.assertTrue(torch.equal(tensor_be_no_bom, tensor_le_bom))
3353        self.assertTrue(torch.equal(tensor_be_no_bom, tensor_be_bom))
3354        self.assertTrue(torch.equal(tensor_le_no_bom_little, tensor_le_bom))
3355        self.assertTrue(torch.equal(tensor_be_no_bom_little, tensor_be_bom))
3356        self.assertTrue(torch.equal(tensor_le_no_bom_big, tensor_le_bom))
3357        self.assertTrue(torch.equal(tensor_be_no_bom_big, tensor_be_bom))
3358
3359    def test_serialization_load_bom_data_bfloat16(self):
3360        # 1. Generated on LE system using following commands:
3361        #
3362        # import torch
3363        #
3364        # x = torch.randn(2,2, dtype=torch.bfloat16)
3365        #
3366        # torch.save(x, "tensor.bfloat16.LE.pt", _disable_byteorder_record=True)
3367        # torch.save(x, "tensor.bfloat16.LE.BOM.pt")
3368        #
3369        # print(x)
3370        #
3371        # 2. After that it is resaved on BE system with following commands:
3372        #
3373        # import torch
3374        #
3375        # x = torch.load('tensor.bfloat16.LE.BOM.pt')
3376        #
3377        # torch.save(x, 'tensor.bfloat16.BE.pt', _disable_byteorder_record=True)
3378        # torch.save(x, 'tensor.bfloat16.BE.BOM.pt')
3379        #
3380        # print(x)
3381        #
3382        # Following commands and a bit of manual work were used to produce python bytes from resulting files:
3383        #
3384        # file = open('filename', 'rb')
3385        # data = file.read()
3386        # file.close()
3387        # print("\n".join(textwrap.wrap(str(data), 80)))
3388        #
3389        # BOM in this context is used as Byte Order Mark.
3390        #
3391        data_le_no_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3392                          b'\x00\x00\x00\x00\x00\x1b\x00\x07\x00tensor.bfloat16.LE/data.pklFB\x03\x00ZZZ\x80'
3393                          b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
3394                          b'h\nBFloat16Storage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x04tq'
3395                          b'\x05QK\x00K\x02K\x02\x86q\x06K\x02K\x01\x86q\x07\x89ccollections\nOrderedDict\nq'
3396                          b'\x08)Rq\ttq\nRq\x0b.PK\x07\x08\x1f>\xd9\x7f\x9d\x00\x00\x00\x9d\x00\x00\x00PK\x03'
3397                          b'\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3398                          b'\x00\x00\x00\x19\x00\x1c\x00tensor.bfloat16.LE/data/0FB\x18\x00ZZZZZZZZZZZZZZZZ'
3399                          b'ZZZZZZZZ\r@i\xber?\xbc\xbfPK\x07\x085\xd2\x8f\xc7\x08\x00\x00\x00\x08\x00\x00\x00'
3400                          b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3401                          b'\x00\x00\x00\x00\x1a\x000\x00tensor.bfloat16.LE/versionFB,\x00ZZZZZZZZZZZZZZZ'
3402                          b'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00'
3403                          b'\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x1f>\xd9\x7f\x9d\x00'
3404                          b'\x00\x00\x9d\x00\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3405                          b'\x00\x00\x00\x00tensor.bfloat16.LE/data.pklPK\x01\x02\x00\x00\x00\x00\x08\x08'
3406                          b'\x00\x00\x00\x00\x00\x005\xd2\x8f\xc7\x08\x00\x00\x00\x08\x00\x00\x00\x19\x00\x00'
3407                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xed\x00\x00\x00tensor.bfloat16.LE/'
3408                          b'data/0PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00'
3409                          b'\x00\x00\x02\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3410                          b'X\x01\x00\x00tensor.bfloat16.LE/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00'
3411                          b'\x1e\x03-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x03'
3412                          b'\x00\x00\x00\x00\x00\x00\x00\xd8\x00\x00\x00\x00\x00\x00\x00\xd2\x01\x00\x00\x00'
3413                          b'\x00\x00\x00PK\x06\x07\x00\x00\x00\x00\xaa\x02\x00\x00\x00\x00\x00\x00\x01\x00\x00'
3414                          b'\x00PK\x05\x06\x00\x00\x00\x00\x03\x00\x03\x00\xd8\x00\x00\x00\xd2\x01\x00\x00'
3415                          b'\x00\x00')
3416
3417        data_le_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3418                       b'\x00\x00\x00\x00\x00\x1f\x00C\x00tensor.bfloat16.LE.BOM/data.pklFB?\x00ZZZZZZZZZ'
3419                       b'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ\x80\x02ctorch._utils\n_re'
3420                       b'build_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorch\nBFloat16Storage\nq\x02'
3421                       b'X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x04tq\x05QK\x00K\x02K\x02\x86'
3422                       b'q\x06K\x02K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08)Rq\ttq\nRq\x0b.PK'
3423                       b'\x07\x08\x1f>\xd9\x7f\x9d\x00\x00\x00\x9d\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00'
3424                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x15'
3425                       b'\x00tensor.bfloat16.LE.BOM/byteorderFB\x11\x00ZZZZZZZZZZZZZZZZZlittlePK\x07\x08\x85'
3426                       b'=\xe3\x19\x06\x00\x00\x00\x06\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00'
3427                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00/\x00tenso'
3428                       b'r.bfloat16.LE.BOM/data/0FB+\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ\r@i\xbe'
3429                       b'r?\xbc\xbfPK\x07\x085\xd2\x8f\xc7\x08\x00\x00\x00\x08\x00\x00\x00PK\x03\x04\x00'
3430                       b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3431                       b'\x00\x1e\x00,\x00tensor.bfloat16.LE.BOM/versionFB(\x00ZZZZZZZZZZZZZZZZZZZZZZZZZ'
3432                       b'ZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00PK\x01\x02'
3433                       b'\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x1f>\xd9\x7f\x9d\x00\x00\x00\x9d'
3434                       b'\x00\x00\x00\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3435                       b'\x00tensor.bfloat16.LE.BOM/data.pklPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00'
3436                       b'\x00\x00\x00\x85=\xe3\x19\x06\x00\x00\x00\x06\x00\x00\x00 \x00\x00\x00\x00\x00'
3437                       b'\x00\x00\x00\x00\x00\x00\x00\x00-\x01\x00\x00tensor.bfloat16.LE.BOM/byteorderPK\x01'
3438                       b'\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x005\xd2\x8f\xc7\x08\x00\x00'
3439                       b'\x00\x08\x00\x00\x00\x1d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96'
3440                       b'\x01\x00\x00tensor.bfloat16.LE.BOM/data/0PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00'
3441                       b'\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00\x1e\x00\x00\x00\x00'
3442                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x02\x00\x00tensor.bfloat16.LE.BOM/vers'
3443                       b'ionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00\x1e\x03-\x00\x00\x00\x00\x00\x00\x00\x00'
3444                       b'\x00\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x002\x01\x00'
3445                       b'\x00\x00\x00\x00\x00\x92\x02\x00\x00\x00\x00\x00\x00PK\x06\x07\x00\x00\x00\x00\xc4'
3446                       b'\x03\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05\x06\x00\x00\x00\x00\x04\x00'
3447                       b'\x04\x002\x01\x00\x00\x92\x02\x00\x00\x00\x00')
3448
3449        data_be_no_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3450                          b'\x00\x00\x00\x00\x00\x1b\x00\x07\x00tensor.bfloat16.BE/data.pklFB\x03\x00ZZZ\x80'
3451                          b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
3452                          b'h\nBFloat16Storage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x04tq'
3453                          b'\x05QK\x00K\x02K\x02\x86q\x06K\x02K\x01\x86q\x07\x89ccollections\nOrderedDict\nq'
3454                          b'\x08)Rq\ttq\nRq\x0b.PK\x07\x08\x1f>\xd9\x7f\x9d\x00\x00\x00\x9d\x00\x00\x00PK\x03'
3455                          b'\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3456                          b'\x00\x00\x00\x19\x00\x1c\x00tensor.bfloat16.BE/data/0FB\x18\x00ZZZZZZZZZZZZZZZZ'
3457                          b'ZZZZZZZZ@\r\xbei?r\xbf\xbcPK\x07\x08d\x02=\xc7\x08\x00\x00\x00\x08\x00\x00\x00PK'
3458                          b'\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3459                          b'\x00\x00\x00\x00\x1a\x000\x00tensor.bfloat16.BE/versionFB,\x00ZZZZZZZZZZZZZZZZZZ'
3460                          b'ZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00'
3461                          b'PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x1f>\xd9\x7f\x9d\x00'
3462                          b'\x00\x00\x9d\x00\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3463                          b'\x00\x00\x00\x00tensor.bfloat16.BE/data.pklPK\x01\x02\x00\x00\x00\x00\x08\x08\x00'
3464                          b'\x00\x00\x00\x00\x00d\x02=\xc7\x08\x00\x00\x00\x08\x00\x00\x00\x19\x00\x00\x00\x00'
3465                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\xed\x00\x00\x00tensor.bfloat16.BE/data/0'
3466                          b'PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00'
3467                          b'\x00\x02\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\x01'
3468                          b'\x00\x00tensor.bfloat16.BE/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00\x1e\x03'
3469                          b'-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00'
3470                          b'\x00\x00\x00\x00\x00\xd8\x00\x00\x00\x00\x00\x00\x00\xd2\x01\x00\x00\x00\x00\x00'
3471                          b'\x00PK\x06\x07\x00\x00\x00\x00\xaa\x02\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00'
3472                          b'PK\x05\x06\x00\x00\x00\x00\x03\x00\x03\x00\xd8\x00\x00\x00\xd2\x01\x00\x00\x00\x00')
3473
3474        data_be_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3475                       b'\x00\x00\x00\x00\x00\x1f\x00C\x00tensor.bfloat16.BE.BOM/data.pklFB?\x00ZZZZZZZZZ'
3476                       b'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ\x80\x02ctorch._utils\n_re'
3477                       b'build_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorch\nBFloat16Storage\nq\x02'
3478                       b'X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x04tq\x05QK\x00K\x02K\x02\x86'
3479                       b'q\x06K\x02K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08)Rq\ttq\nRq\x0b.PK'
3480                       b'\x07\x08\x1f>\xd9\x7f\x9d\x00\x00\x00\x9d\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00'
3481                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x15'
3482                       b'\x00tensor.bfloat16.BE.BOM/byteorderFB\x11\x00ZZZZZZZZZZZZZZZZZbigPK\x07\x08I\xe2'
3483                       b'\xfb\xd3\x03\x00\x00\x00\x03\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00'
3484                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x002\x00tensor.b'
3485                       b'float16.BE.BOM/data/0FB.\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ@\r\xbe'
3486                       b'i?r\xbf\xbcPK\x07\x08d\x02=\xc7\x08\x00\x00\x00\x08\x00\x00\x00PK\x03\x04\x00\x00'
3487                       b'\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3488                       b'\x1e\x00,\x00tensor.bfloat16.BE.BOM/versionFB(\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
3489                       b'ZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00PK\x01\x02\x00'
3490                       b'\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x1f>\xd9\x7f\x9d\x00\x00\x00\x9d\x00'
3491                       b'\x00\x00\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3492                       b'tensor.bfloat16.BE.BOM/data.pklPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00'
3493                       b'\x00\x00I\xe2\xfb\xd3\x03\x00\x00\x00\x03\x00\x00\x00 \x00\x00\x00\x00\x00\x00'
3494                       b'\x00\x00\x00\x00\x00\x00\x00-\x01\x00\x00tensor.bfloat16.BE.BOM/byteorderPK\x01'
3495                       b'\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00d\x02=\xc7\x08\x00\x00\x00\x08'
3496                       b'\x00\x00\x00\x1d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x93\x01\x00'
3497                       b'\x00tensor.bfloat16.BE.BOM/data/0PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00'
3498                       b'\x00\x00\x00\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x00'
3499                       b'\x00\x00\x00\x00\x00\x00\x00\x18\x02\x00\x00tensor.bfloat16.BE.BOM/versionPK\x06'
3500                       b'\x06,\x00\x00\x00\x00\x00\x00\x00\x1e\x03-\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3501                       b'\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x002\x01\x00\x00\x00'
3502                       b'\x00\x00\x00\x92\x02\x00\x00\x00\x00\x00\x00PK\x06\x07\x00\x00\x00\x00\xc4\x03'
3503                       b'\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05\x06\x00\x00\x00\x00\x04\x00\x04\x00'
3504                       b'2\x01\x00\x00\x92\x02\x00\x00\x00\x00')
3505
3506        current_load_endian = get_default_load_endianness()
3507
3508        buf_le_no_bom = io.BytesIO(data_le_no_bom)
3509        buf_le_bom = io.BytesIO(data_le_bom)
3510        buf_be_no_bom = io.BytesIO(data_be_no_bom)
3511        buf_be_bom = io.BytesIO(data_be_bom)
3512
3513        try:
3514            set_default_load_endianness(LoadEndianness.NATIVE)
3515            tensor_le_no_bom = torch.load(buf_le_no_bom)
3516            tensor_be_no_bom = torch.load(buf_be_no_bom)
3517        finally:
3518            set_default_load_endianness(current_load_endian)
3519
3520        tensor_le_bom = torch.load(buf_le_bom)
3521        tensor_be_bom = torch.load(buf_be_bom)
3522
3523        buf_le_no_bom.seek(0)
3524        buf_be_no_bom.seek(0)
3525
3526        try:
3527            set_default_load_endianness(LoadEndianness.LITTLE)
3528            tensor_le_no_bom_little = torch.load(buf_le_no_bom)
3529            tensor_be_no_bom_little = torch.load(buf_be_no_bom)
3530        finally:
3531            set_default_load_endianness(current_load_endian)
3532
3533        buf_le_no_bom.seek(0)
3534        buf_be_no_bom.seek(0)
3535
3536        try:
3537            set_default_load_endianness(LoadEndianness.BIG)
3538            tensor_le_no_bom_big = torch.load(buf_le_no_bom)
3539            tensor_be_no_bom_big = torch.load(buf_be_no_bom)
3540        finally:
3541            set_default_load_endianness(current_load_endian)
3542
3543        self.assertTrue(torch.equal(tensor_le_bom, tensor_be_bom))
3544        self.assertFalse(torch.equal(tensor_le_no_bom, tensor_be_no_bom))
3545        self.assertTrue(torch.equal(tensor_le_no_bom_little, tensor_le_bom))
3546        self.assertFalse(torch.equal(tensor_be_no_bom_little, tensor_be_bom))
3547        self.assertFalse(torch.equal(tensor_le_no_bom_big, tensor_le_bom))
3548        self.assertTrue(torch.equal(tensor_be_no_bom_big, tensor_be_bom))
3549
3550        if (sys.byteorder == 'little'):
3551            self.assertTrue(torch.equal(tensor_le_no_bom, tensor_le_bom))
3552            self.assertTrue(torch.equal(tensor_le_no_bom, tensor_be_bom))
3553            self.assertFalse(torch.equal(tensor_be_no_bom, tensor_le_bom))
3554            self.assertFalse(torch.equal(tensor_be_no_bom, tensor_be_bom))
3555        else:
3556            self.assertFalse(torch.equal(tensor_le_no_bom, tensor_le_bom))
3557            self.assertFalse(torch.equal(tensor_le_no_bom, tensor_be_bom))
3558            self.assertTrue(torch.equal(tensor_be_no_bom, tensor_le_bom))
3559            self.assertTrue(torch.equal(tensor_be_no_bom, tensor_be_bom))
3560
3561    def test_serialization_load_bom_data_cdouble(self):
3562        # 1. Generated on LE system using following commands:
3563        #
3564        # import torch
3565        #
3566        # x = torch.randn(2,2, dtype=torch.cdouble)
3567        #
3568        # torch.save(x, "tensor.cdouble.LE.pt", _disable_byteorder_record=True)
3569        # torch.save(x, "tensor.cdouble.LE.BOM.pt")
3570        #
3571        # print(x)
3572        #
3573        # 2. After that it is resaved on BE system with following commands:
3574        #
3575        # import torch
3576        #
3577        # x = torch.load('tensor.cdouble.LE.BOM.pt')
3578        #
3579        # torch.save(x, 'tensor.cdouble.BE.pt', _disable_byteorder_record=True)
3580        # torch.save(x, 'tensor.cdouble.BE.BOM.pt')
3581        #
3582        # print(x)
3583        #
3584        # Following commands and a bit of manual work were used to produce python bytes from resulting files:
3585        #
3586        # file = open('filename', 'rb')
3587        # data = file.read()
3588        # file.close()
3589        # print("\n".join(textwrap.wrap(str(data), 80)))
3590        #
3591        # BOM in this context is used as Byte Order Mark.
3592        #
3593        data_le_no_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3594                          b'\x00\x00\x00\x00\x00\x1a\x00\x08\x00tensor.cdouble.LE/data.pklFB\x04\x00ZZZZ\x80'
3595                          b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
3596                          b'h\nComplexDoubleStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x04'
3597                          b'tq\x05QK\x00K\x02K\x02\x86q\x06K\x02K\x01\x86q\x07\x89ccollections\nOrderedDi'
3598                          b'ct\nq\x08)Rq\ttq\nRq\x0b.PK\x07\x08(W{\xca\xa2\x00\x00\x00\xa2\x00\x00\x00PK\x03'
3599                          b'\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3600                          b'\x00\x00\x00\x18\x00\x18\x00tensor.cdouble.LE/data/0FB\x14\x00ZZZZZZZZZZZZZZZZZZ'
3601                          b'ZZ\xd1/\x84\xd8,\x00\xcd\xbf|L\xcf\xd0O\xee\xd7\xbfb\xb6<\xb4\xe2_\xec?v+\x86\xd9'
3602                          b'\xca\x0e\xf8?i#\xbb\xfcU\x1b\xe0\xbf\x984\xcd\x02q\x8a\xe9?\xc1_\xd7R\xe3\xfb\xe3'
3603                          b'\xbf\xcf\xce>\xcd\xa2\x9f\xe8?PK\x07\x08\x1d\xed\xed\xa0@\x00\x00\x00@\x00\x00'
3604                          b'\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3605                          b'\x00\x00\x00\x00\x00\x19\x009\x00tensor.cdouble.LE/versionFB5\x00ZZZZZZZZZZZZZ'
3606                          b'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00\x00\x00\x02'
3607                          b'\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00(W{\xca'
3608                          b'\xa2\x00\x00\x00\xa2\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3609                          b'\x00\x00\x00\x00\x00\x00tensor.cdouble.LE/data.pklPK\x01\x02\x00\x00\x00\x00\x08'
3610                          b'\x08\x00\x00\x00\x00\x00\x00\x1d\xed\xed\xa0@\x00\x00\x00@\x00\x00\x00\x18\x00\x00'
3611                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf2\x00\x00\x00tensor.cdouble.LE/'
3612                          b'data/0PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00'
3613                          b'\x00\x00\x02\x00\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3614                          b'\x90\x01\x00\x00tensor.cdouble.LE/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00'
3615                          b'\x1e\x03-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x03'
3616                          b'\x00\x00\x00\x00\x00\x00\x00\xd5\x00\x00\x00\x00\x00\x00\x00\x12\x02\x00\x00\x00'
3617                          b'\x00\x00\x00PK\x06\x07\x00\x00\x00\x00\xe7\x02\x00\x00\x00\x00\x00\x00\x01\x00'
3618                          b'\x00\x00PK\x05\x06\x00\x00\x00\x00\x03\x00\x03\x00\xd5\x00\x00\x00\x12\x02\x00\x00'
3619                          b'\x00\x00')
3620
3621        data_le_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3622                       b'\x00\x00\x00\x00\x00\x1e\x00\x04\x00tensor.cdouble.LE.BOM/data.pklFB\x00\x00\x80'
3623                       b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
3624                       b'h\nComplexDoubleStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x04'
3625                       b'tq\x05QK\x00K\x02K\x02\x86q\x06K\x02K\x01\x86q\x07\x89ccollections\nOrderedDi'
3626                       b'ct\nq\x08)Rq\ttq\nRq\x0b.PK\x07\x08(W{\xca\xa2\x00\x00\x00\xa2\x00\x00\x00PK\x03'
3627                       b'\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3628                       b'\x00\x00\x00\x1f\x00\x11\x00tensor.cdouble.LE.BOM/byteorderFB\r\x00ZZZZZZZZZZZZZ'
3629                       b'littlePK\x07\x08\x85=\xe3\x19\x06\x00\x00\x00\x06\x00\x00\x00PK\x03\x04\x00\x00\x08'
3630                       b'\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c'
3631                       b'\x000\x00tensor.cdouble.LE.BOM/data/0FB,\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
3632                       b'ZZZZZZZZZZZ\xd1/\x84\xd8,\x00\xcd\xbf|L\xcf\xd0O\xee\xd7\xbfb\xb6<\xb4\xe2_\xec?'
3633                       b'v+\x86\xd9\xca\x0e\xf8?i#\xbb\xfcU\x1b\xe0\xbf\x984\xcd\x02q\x8a\xe9?\xc1_\xd7R\xe3'
3634                       b'\xfb\xe3\xbf\xcf\xce>\xcd\xa2\x9f\xe8?PK\x07\x08\x1d\xed\xed\xa0@\x00\x00\x00'
3635                       b'@\x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3636                       b'\x00\x00\x00\x00\x00\x00\x00\x1d\x005\x00tensor.cdouble.LE.BOM/versionFB1\x00'
3637                       b'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00'
3638                       b'\x00\x00\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00'
3639                       b'(W{\xca\xa2\x00\x00\x00\xa2\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3640                       b'\x00\x00\x00\x00\x00\x00\x00\x00tensor.cdouble.LE.BOM/data.pklPK\x01\x02\x00\x00'
3641                       b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x85=\xe3\x19\x06\x00\x00\x00\x06\x00\x00'
3642                       b'\x00\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf2\x00\x00\x00te'
3643                       b'nsor.cdouble.LE.BOM/byteorderPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00'
3644                       b'\x00\x1d\xed\xed\xa0@\x00\x00\x00@\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00'
3645                       b'\x00\x00\x00\x00\x00\x00V\x01\x00\x00tensor.cdouble.LE.BOM/data/0PK\x01\x02\x00'
3646                       b'\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00'
3647                       b'\x00\x1d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x02\x00\x00te'
3648                       b'nsor.cdouble.LE.BOM/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00\x1e\x03-\x00\x00'
3649                       b'\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00'
3650                       b'\x00\x00\x00.\x01\x00\x00\x00\x00\x00\x00\x92\x02\x00\x00\x00\x00\x00\x00PK\x06'
3651                       b'\x07\x00\x00\x00\x00\xc0\x03\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05\x06'
3652                       b'\x00\x00\x00\x00\x04\x00\x04\x00.\x01\x00\x00\x92\x02\x00\x00\x00\x00')
3653
3654        data_be_no_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3655                          b'\x00\x00\x00\x00\x00\x1a\x00\x08\x00tensor.cdouble.BE/data.pklFB\x04\x00ZZZZ\x80'
3656                          b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
3657                          b'h\nComplexDoubleStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x04'
3658                          b'tq\x05QK\x00K\x02K\x02\x86q\x06K\x02K\x01\x86q\x07\x89ccollections\nOrderedDi'
3659                          b'ct\nq\x08)Rq\ttq\nRq\x0b.PK\x07\x08(W{\xca\xa2\x00\x00\x00\xa2\x00\x00\x00PK\x03'
3660                          b'\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3661                          b'\x00\x00\x00\x18\x00\x18\x00tensor.cdouble.BE/data/0FB\x14\x00ZZZZZZZZZZZZZZZZZZ'
3662                          b'ZZ\xbf\xcd\x00,\xd8\x84/\xd1\xbf\xd7\xeeO\xd0\xcfL|?\xec_\xe2\xb4<\xb6b?\xf8\x0e'
3663                          b'\xca\xd9\x86+v\xbf\xe0\x1bU\xfc\xbb#i?\xe9\x8aq\x02\xcd4\x98\xbf\xe3\xfb\xe3R\xd7'
3664                          b'_\xc1?\xe8\x9f\xa2\xcd>\xce\xcfPK\x07\x08\x91\xbey\x14@\x00\x00\x00@\x00\x00\x00'
3665                          b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3666                          b'\x00\x00\x00\x00\x19\x009\x00tensor.cdouble.BE/versionFB5\x00ZZZZZZZZZZZZZZZZ'
3667                          b'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00\x00\x00\x02'
3668                          b'\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00(W{\xca\xa2'
3669                          b'\x00\x00\x00\xa2\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3670                          b'\x00\x00\x00\x00\x00tensor.cdouble.BE/data.pklPK\x01\x02\x00\x00\x00\x00\x08\x08'
3671                          b'\x00\x00\x00\x00\x00\x00\x91\xbey\x14@\x00\x00\x00@\x00\x00\x00\x18\x00\x00\x00'
3672                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf2\x00\x00\x00tensor.cdouble.BE/data/0'
3673                          b'PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00'
3674                          b'\x00\x02\x00\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90'
3675                          b'\x01\x00\x00tensor.cdouble.BE/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00\x1e'
3676                          b'\x03-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x03\x00'
3677                          b'\x00\x00\x00\x00\x00\x00\xd5\x00\x00\x00\x00\x00\x00\x00\x12\x02\x00\x00\x00\x00'
3678                          b'\x00\x00PK\x06\x07\x00\x00\x00\x00\xe7\x02\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00'
3679                          b'PK\x05\x06\x00\x00\x00\x00\x03\x00\x03\x00\xd5\x00\x00\x00\x12\x02\x00\x00\x00'
3680                          b'\x00')
3681
3682        data_be_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3683                       b'\x00\x00\x00\x00\x00\x1e\x00\x04\x00tensor.cdouble.BE.BOM/data.pklFB\x00\x00\x80'
3684                       b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
3685                       b'h\nComplexDoubleStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x04'
3686                       b'tq\x05QK\x00K\x02K\x02\x86q\x06K\x02K\x01\x86q\x07\x89ccollections\nOrderedDi'
3687                       b'ct\nq\x08)Rq\ttq\nRq\x0b.PK\x07\x08(W{\xca\xa2\x00\x00\x00\xa2\x00\x00\x00PK\x03'
3688                       b'\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3689                       b'\x00\x00\x00\x1f\x00\x11\x00tensor.cdouble.BE.BOM/byteorderFB\r\x00ZZZZZZZZZZZZZ'
3690                       b'bigPK\x07\x08I\xe2\xfb\xd3\x03\x00\x00\x00\x03\x00\x00\x00PK\x03\x04\x00\x00\x08'
3691                       b'\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c'
3692                       b'\x003\x00tensor.cdouble.BE.BOM/data/0FB/\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
3693                       b'ZZZZZZZZZZZ\xbf\xcd\x00,\xd8\x84/\xd1\xbf\xd7\xeeO\xd0\xcfL|?\xec_\xe2\xb4<\xb6b'
3694                       b'?\xf8\x0e\xca\xd9\x86+v\xbf\xe0\x1bU\xfc\xbb#i?\xe9\x8aq\x02\xcd4\x98\xbf\xe3\xfb'
3695                       b'\xe3R\xd7_\xc1?\xe8\x9f\xa2\xcd>\xce\xcfPK\x07\x08\x91\xbey\x14@\x00\x00\x00@\x00'
3696                       b'\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3697                       b'\x00\x00\x00\x00\x00\x00\x00\x1d\x005\x00tensor.cdouble.BE.BOM/versionFB1\x00ZZZ'
3698                       b'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02\x00\x00'
3699                       b'\x00\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00('
3700                       b'W{\xca\xa2\x00\x00\x00\xa2\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3701                       b'\x00\x00\x00\x00\x00\x00\x00tensor.cdouble.BE.BOM/data.pklPK\x01\x02\x00\x00\x00'
3702                       b'\x00\x08\x08\x00\x00\x00\x00\x00\x00I\xe2\xfb\xd3\x03\x00\x00\x00\x03\x00\x00\x00'
3703                       b'\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf2\x00\x00\x00tenso'
3704                       b'r.cdouble.BE.BOM/byteorderPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00'
3705                       b'\x00\x91\xbey\x14@\x00\x00\x00@\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3706                       b'\x00\x00\x00\x00S\x01\x00\x00tensor.cdouble.BE.BOM/data/0PK\x01\x02\x00\x00\x00'
3707                       b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00'
3708                       b'\x1d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x02\x00\x00tensor.c'
3709                       b'double.BE.BOM/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00\x1e\x03-\x00\x00\x00'
3710                       b'\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00'
3711                       b'\x00\x00.\x01\x00\x00\x00\x00\x00\x00\x92\x02\x00\x00\x00\x00\x00\x00PK\x06\x07'
3712                       b'\x00\x00\x00\x00\xc0\x03\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05\x06\x00\x00'
3713                       b'\x00\x00\x04\x00\x04\x00.\x01\x00\x00\x92\x02\x00\x00\x00\x00')
3714
3715        current_load_endian = get_default_load_endianness()
3716
3717        buf_le_no_bom = io.BytesIO(data_le_no_bom)
3718        buf_le_bom = io.BytesIO(data_le_bom)
3719        buf_be_no_bom = io.BytesIO(data_be_no_bom)
3720        buf_be_bom = io.BytesIO(data_be_bom)
3721
3722        try:
3723            set_default_load_endianness(LoadEndianness.NATIVE)
3724            tensor_le_no_bom = torch.load(buf_le_no_bom)
3725            tensor_be_no_bom = torch.load(buf_be_no_bom)
3726        finally:
3727            set_default_load_endianness(current_load_endian)
3728
3729        tensor_le_bom = torch.load(buf_le_bom)
3730        tensor_be_bom = torch.load(buf_be_bom)
3731
3732        buf_le_no_bom.seek(0)
3733        buf_be_no_bom.seek(0)
3734
3735        try:
3736            set_default_load_endianness(LoadEndianness.LITTLE)
3737            tensor_le_no_bom_little = torch.load(buf_le_no_bom)
3738            tensor_be_no_bom_little = torch.load(buf_be_no_bom)
3739        finally:
3740            set_default_load_endianness(current_load_endian)
3741
3742        buf_le_no_bom.seek(0)
3743        buf_be_no_bom.seek(0)
3744
3745        try:
3746            set_default_load_endianness(LoadEndianness.BIG)
3747            tensor_le_no_bom_big = torch.load(buf_le_no_bom)
3748            tensor_be_no_bom_big = torch.load(buf_be_no_bom)
3749        finally:
3750            set_default_load_endianness(current_load_endian)
3751
3752        self.assertTrue(torch.equal(tensor_le_bom, tensor_be_bom))
3753        self.assertFalse(torch.equal(tensor_le_no_bom, tensor_be_no_bom))
3754        self.assertTrue(torch.equal(tensor_le_no_bom_little, tensor_le_bom))
3755        self.assertFalse(torch.equal(tensor_be_no_bom_little, tensor_be_bom))
3756        self.assertFalse(torch.equal(tensor_le_no_bom_big, tensor_le_bom))
3757        self.assertTrue(torch.equal(tensor_be_no_bom_big, tensor_be_bom))
3758
3759        if (sys.byteorder == 'little'):
3760            self.assertTrue(torch.equal(tensor_le_no_bom, tensor_le_bom))
3761            self.assertTrue(torch.equal(tensor_le_no_bom, tensor_be_bom))
3762            self.assertFalse(torch.equal(tensor_be_no_bom, tensor_le_bom))
3763            self.assertFalse(torch.equal(tensor_be_no_bom, tensor_be_bom))
3764        else:
3765            self.assertFalse(torch.equal(tensor_le_no_bom, tensor_le_bom))
3766            self.assertFalse(torch.equal(tensor_le_no_bom, tensor_be_bom))
3767            self.assertTrue(torch.equal(tensor_be_no_bom, tensor_le_bom))
3768            self.assertTrue(torch.equal(tensor_be_no_bom, tensor_be_bom))
3769
3770    def test_serialization_load_bom_data_cfloat(self):
3771        # 1. Generated on LE system using following commands:
3772        #
3773        # import torch
3774        #
3775        # x = torch.randn(2,2, dtype=torch.cfloat)
3776        #
3777        # torch.save(x, "tensor.cfloat.LE.pt", _disable_byteorder_record=True)
3778        # torch.save(x, "tensor.cfloat.LE.BOM.pt")
3779        #
3780        # print(x)
3781        #
3782        # 2. After that it is resaved on BE system with following commands:
3783        #
3784        # import torch
3785        #
3786        # x = torch.load('tensor.cfloat.LE.BOM.pt')
3787        #
3788        # torch.save(x, 'tensor.cfloat.BE.pt', _disable_byteorder_record=True)
3789        # torch.save(x, 'tensor.cfloat.BE.BOM.pt')
3790        #
3791        # print(x)
3792        #
3793        # Following commands and a bit of manual work were used to produce python bytes from resulting files:
3794        #
3795        # file = open('filename', 'rb')
3796        # data = file.read()
3797        # file.close()
3798        # print("\n".join(textwrap.wrap(str(data), 80)))
3799        #
3800        # BOM in this context is used as Byte Order Mark.
3801        #
3802        data_le_no_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3803                          b'\x00\x00\x00\x00\x00\x12\x00\x10\x00tensor.le/data.pklFB\x0c\x00ZZZZZZZZZZZZ\x80'
3804                          b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
3805                          b'h\nComplexFloatStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x04'
3806                          b'tq\x05QK\x00K\x02K\x02\x86q\x06K\x02K\x01\x86q\x07\x89ccollections\nOrderedDic'
3807                          b't\nq\x08)Rq\ttq\nRq\x0b.PK\x07\x08\xe4\x04T\xec\xa1\x00\x00\x00\xa1\x00\x00\x00P'
3808                          b'K\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3809                          b'\x00\x00\x00\x00\x10\x00!\x00tensor.le/data/0FB\x1d\x00ZZZZZZZZZZZZZZZZZZZZZZZZ'
3810                          b'ZZZZZ\x9e<5\xbe\x96\xd1\xf1=Q\xeaj\xbfiX\x02\xbfW`\xfe?+\xfd\x0c>;a\\\xbe.b\xe2>'
3811                          b'PK\x07\x08\xaa\x05\x14\x12 \x00\x00\x00 \x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00'
3812                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00!\x00'
3813                          b'tensor.le/versionFB\x1d\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9e'
3814                          b'gU\x02\x00\x00\x00\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00'
3815                          b'\x00\x00\x00\xe4\x04T\xec\xa1\x00\x00\x00\xa1\x00\x00\x00\x12\x00\x00\x00\x00\x00'
3816                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00tensor.le/data.pklPK\x01\x02\x00'
3817                          b'\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xaa\x05\x14\x12 \x00\x00\x00 \x00\x00'
3818                          b'\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x00\x00\x00t'
3819                          b'ensor.le/data/0PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9e'
3820                          b'gU\x02\x00\x00\x00\x02\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3821                          b'\x00\x00p\x01\x00\x00tensor.le/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00'
3822                          b'\x1e\x03-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x03'
3823                          b'\x00\x00\x00\x00\x00\x00\x00\xbd\x00\x00\x00\x00\x00\x00\x00\xd2\x01\x00\x00\x00'
3824                          b'\x00\x00\x00PK\x06\x07\x00\x00\x00\x00\x8f\x02\x00\x00\x00\x00\x00\x00\x01\x00\x00'
3825                          b'\x00PK\x05\x06\x00\x00\x00\x00\x03\x00\x03\x00\xbd\x00\x00\x00\xd2\x01\x00\x00'
3826                          b'\x00\x00')
3827
3828        data_le_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3829                       b'\x00\x00\x00\x00\x00\x12\x00\x10\x00tensor.le/data.pklFB\x0c\x00ZZZZZZZZZZZZ\x80'
3830                       b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
3831                       b'h\nComplexFloatStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x04'
3832                       b'tq\x05QK\x00K\x02K\x02\x86q\x06K\x02K\x01\x86q\x07\x89ccollections\nOrderedDic'
3833                       b't\nq\x08)Rq\ttq\nRq\x0b.PK\x07\x08\xe4\x04T\xec\xa1\x00\x00\x00\xa1\x00\x00\x00P'
3834                       b'K\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3835                       b'\x00\x00\x00\x00\x13\x00\x1e\x00tensor.le/byteorderFB\x1a\x00ZZZZZZZZZZZZZZZZZZ'
3836                       b'ZZZZZZZZlittlePK\x07\x08\x85=\xe3\x19\x06\x00\x00\x00\x06\x00\x00\x00PK\x03\x04\x00'
3837                       b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3838                       b'\x00\x10\x00<\x00tensor.le/data/0FB8\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
3839                       b'ZZZZZZZZZZZZZZZZZZZ\x9e<5\xbe\x96\xd1\xf1=Q\xeaj\xbfiX\x02\xbfW`\xfe?+\xfd\x0c>;'
3840                       b'a\\\xbe.b\xe2>PK\x07\x08\xaa\x05\x14\x12 \x00\x00\x00 \x00\x00\x00PK\x03\x04\x00'
3841                       b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3842                       b'\x00\x11\x00!\x00tensor.le/versionFB\x1d\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07'
3843                       b'\x08\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08'
3844                       b'\x00\x00\x00\x00\x00\x00\xe4\x04T\xec\xa1\x00\x00\x00\xa1\x00\x00\x00\x12\x00\x00'
3845                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00tensor.le/data.pk'
3846                       b'lPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x85=\xe3\x19\x06\x00'
3847                       b'\x00\x00\x06\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3848                       b'\xf1\x00\x00\x00tensor.le/byteorderPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00'
3849                       b'\x00\x00\x00\xaa\x05\x14\x12 \x00\x00\x00 \x00\x00\x00\x10\x00\x00\x00\x00\x00\x00'
3850                       b'\x00\x00\x00\x00\x00\x00\x00V\x01\x00\x00tensor.le/data/0PK\x01\x02\x00\x00\x00'
3851                       b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00'
3852                       b'\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x01\x00\x00tensor.l'
3853                       b'e/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00\x1e\x03-\x00\x00\x00\x00\x00\x00'
3854                       b'\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\xfe'
3855                       b'\x00\x00\x00\x00\x00\x00\x00R\x02\x00\x00\x00\x00\x00\x00PK\x06\x07\x00\x00\x00'
3856                       b'\x00P\x03\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05\x06\x00\x00\x00\x00\x04\x00'
3857                       b'\x04\x00\xfe\x00\x00\x00R\x02\x00\x00\x00\x00')
3858
3859        data_be_no_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3860                          b'\x00\x00\x00\x00\x00\x12\x00\x10\x00tensor.be/data.pklFB\x0c\x00ZZZZZZZZZZZZ\x80'
3861                          b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
3862                          b'h\nComplexFloatStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x04'
3863                          b'tq\x05QK\x00K\x02K\x02\x86q\x06K\x02K\x01\x86q\x07\x89ccollections\nOrderedDic'
3864                          b't\nq\x08)Rq\ttq\nRq\x0b.PK\x07\x08\xe4\x04T\xec\xa1\x00\x00\x00\xa1\x00\x00\x00P'
3865                          b'K\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3866                          b'\x00\x00\x00\x00\x10\x00!\x00tensor.be/data/0FB\x1d\x00ZZZZZZZZZZZZZZZZZZZZZZZZ'
3867                          b'ZZZZZ\xbe5<\x9e=\xf1\xd1\x96\xbfj\xeaQ\xbf\x02Xi?\xfe`W>\x0c\xfd+\xbe\\a;>\xe2b.'
3868                          b'PK\x07\x08\xe0\x07\xaa8 \x00\x00\x00 \x00\x00\x00PK\x03\x04\x00\x00\x08\x08\x00\x00'
3869                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00!\x00'
3870                          b'tensor.be/versionFB\x1d\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08\xd1\x9egU\x02'
3871                          b'\x00\x00\x00\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00'
3872                          b'\x00\x00\xe4\x04T\xec\xa1\x00\x00\x00\xa1\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00'
3873                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00tensor.be/data.pklPK\x01\x02\x00\x00'
3874                          b'\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xe0\x07\xaa8 \x00\x00\x00 \x00\x00\x00'
3875                          b'\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x00\x00\x00tensor.'
3876                          b'be/data/0PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU\x02'
3877                          b'\x00\x00\x00\x02\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3878                          b'\x00p\x01\x00\x00tensor.be/versionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00\x1e\x03'
3879                          b'-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00'
3880                          b'\x00\x00\x00\x00\x00\xbd\x00\x00\x00\x00\x00\x00\x00\xd2\x01\x00\x00\x00\x00\x00'
3881                          b'\x00PK\x06\x07\x00\x00\x00\x00\x8f\x02\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00'
3882                          b'PK\x05\x06\x00\x00\x00\x00\x03\x00\x03\x00\xbd\x00\x00\x00\xd2\x01\x00\x00\x00\x00')
3883
3884        data_be_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3885                       b'\x00\x00\x00\x00\x00\x12\x00\x10\x00tensor.be/data.pklFB\x0c\x00ZZZZZZZZZZZZ\x80'
3886                       b'\x02ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorc'
3887                       b'h\nComplexFloatStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x04'
3888                       b'tq\x05QK\x00K\x02K\x02\x86q\x06K\x02K\x01\x86q\x07\x89ccollections\nOrderedDic'
3889                       b't\nq\x08)Rq\ttq\nRq\x0b.PK\x07\x08\xe4\x04T\xec\xa1\x00\x00\x00\xa1\x00\x00\x00P'
3890                       b'K\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3891                       b'\x00\x00\x00\x00\x13\x00\x1e\x00tensor.be/byteorderFB\x1a\x00ZZZZZZZZZZZZZZZZZZ'
3892                       b'ZZZZZZZZbigPK\x07\x08I\xe2\xfb\xd3\x03\x00\x00\x00\x03\x00\x00\x00PK\x03\x04\x00'
3893                       b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3894                       b'\x00\x10\x00?\x00tensor.be/data/0FB;\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
3895                       b'ZZZZZZZZZZZZZZZZZZZ\xbe5<\x9e=\xf1\xd1\x96\xbfj\xeaQ\xbf\x02Xi?\xfe`W>\x0c\xfd+\xbe'
3896                       b'\\a;>\xe2b.PK\x07\x08\xe0\x07\xaa8 \x00\x00\x00 \x00\x00\x00PK\x03\x04\x00\x00'
3897                       b'\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3898                       b'\x11\x00!\x00tensor.be/versionFB\x1d\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07\x08'
3899                       b'\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08\x00'
3900                       b'\x00\x00\x00\x00\x00\xe4\x04T\xec\xa1\x00\x00\x00\xa1\x00\x00\x00\x12\x00\x00'
3901                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00tensor.be/data.pklPK'
3902                       b'\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00I\xe2\xfb\xd3\x03\x00\x00'
3903                       b'\x00\x03\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1'
3904                       b'\x00\x00\x00tensor.be/byteorderPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00'
3905                       b'\x00\x00\xe0\x07\xaa8 \x00\x00\x00 \x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00'
3906                       b'\x00\x00\x00\x00\x00\x00S\x01\x00\x00tensor.be/data/0PK\x01\x02\x00\x00\x00\x00'
3907                       b'\x08\x08\x00\x00\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00\x11\x00'
3908                       b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x01\x00\x00tensor.be/vers'
3909                       b'ionPK\x06\x06,\x00\x00\x00\x00\x00\x00\x00\x1e\x03-\x00\x00\x00\x00\x00\x00\x00\x00'
3910                       b'\x00\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\xfe\x00\x00'
3911                       b'\x00\x00\x00\x00\x00R\x02\x00\x00\x00\x00\x00\x00PK\x06\x07\x00\x00\x00\x00P\x03'
3912                       b'\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05\x06\x00\x00\x00\x00\x04\x00\x04'
3913                       b'\x00\xfe\x00\x00\x00R\x02\x00\x00\x00\x00')
3914
3915        current_load_endian = get_default_load_endianness()
3916
3917        buf_le_no_bom = io.BytesIO(data_le_no_bom)
3918        buf_le_bom = io.BytesIO(data_le_bom)
3919        buf_be_no_bom = io.BytesIO(data_be_no_bom)
3920        buf_be_bom = io.BytesIO(data_be_bom)
3921
3922        try:
3923            set_default_load_endianness(LoadEndianness.NATIVE)
3924            tensor_le_no_bom = torch.load(buf_le_no_bom)
3925            tensor_be_no_bom = torch.load(buf_be_no_bom)
3926        finally:
3927            set_default_load_endianness(current_load_endian)
3928
3929        tensor_le_bom = torch.load(buf_le_bom)
3930        tensor_be_bom = torch.load(buf_be_bom)
3931
3932        buf_le_no_bom.seek(0)
3933        buf_be_no_bom.seek(0)
3934
3935        try:
3936            set_default_load_endianness(LoadEndianness.LITTLE)
3937            tensor_le_no_bom_little = torch.load(buf_le_no_bom)
3938            tensor_be_no_bom_little = torch.load(buf_be_no_bom)
3939        finally:
3940            set_default_load_endianness(current_load_endian)
3941
3942        buf_le_no_bom.seek(0)
3943        buf_be_no_bom.seek(0)
3944
3945        try:
3946            set_default_load_endianness(LoadEndianness.BIG)
3947            tensor_le_no_bom_big = torch.load(buf_le_no_bom)
3948            tensor_be_no_bom_big = torch.load(buf_be_no_bom)
3949        finally:
3950            set_default_load_endianness(current_load_endian)
3951
3952        self.assertTrue(torch.equal(tensor_le_bom, tensor_be_bom))
3953        self.assertFalse(torch.equal(tensor_le_no_bom, tensor_be_no_bom))
3954        self.assertTrue(torch.equal(tensor_le_no_bom_little, tensor_le_bom))
3955        self.assertFalse(torch.equal(tensor_be_no_bom_little, tensor_be_bom))
3956        self.assertFalse(torch.equal(tensor_le_no_bom_big, tensor_le_bom))
3957        self.assertTrue(torch.equal(tensor_be_no_bom_big, tensor_be_bom))
3958
3959        if (sys.byteorder == 'little'):
3960            self.assertTrue(torch.equal(tensor_le_no_bom, tensor_le_bom))
3961            self.assertTrue(torch.equal(tensor_le_no_bom, tensor_be_bom))
3962            self.assertFalse(torch.equal(tensor_be_no_bom, tensor_le_bom))
3963            self.assertFalse(torch.equal(tensor_be_no_bom, tensor_be_bom))
3964        else:
3965            self.assertFalse(torch.equal(tensor_le_no_bom, tensor_le_bom))
3966            self.assertFalse(torch.equal(tensor_le_no_bom, tensor_be_bom))
3967            self.assertTrue(torch.equal(tensor_be_no_bom, tensor_le_bom))
3968            self.assertTrue(torch.equal(tensor_be_no_bom, tensor_be_bom))
3969
3970    @unittest.skipIf(platform.machine() != 's390x', "s390x-specific test")
3971    def test_serialization_warning_s390x(self):
3972        data_be_no_bom = (b'PK\x03\x04\x00\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3973                          b'\x00\x00\x00\x00\x00\x19\x00\t\x00tensor.double.BE/data.pklFB\x05\x00ZZZZZ\x80\x02'
3974                          b'ctorch._utils\n_rebuild_tensor_v2\nq\x00((X\x07\x00\x00\x00storageq\x01ctorch\n'
3975                          b'DoubleStorage\nq\x02X\x01\x00\x00\x000q\x03X\x03\x00\x00\x00cpuq\x04K\x04tq\x05'
3976                          b'QK\x00K\x02K\x02\x86q\x06K\x02K\x01\x86q\x07\x89ccollections\nOrderedDict\nq\x08'
3977                          b')Rq\ttq\nRq\x0b.PK\x07\x08S\xd3\xba&\x9b\x00\x00\x00\x9b\x00\x00\x00PK\x03\x04\x00'
3978                          b'\x00\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3979                          b'\x00\x17\x00 \x00tensor.double.BE/data/0FB\x1c\x00ZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
3980                          b'?\xc9^|\xff\xa4v\x97\xbf\xe9\xb0\x8dP\x8c\xbc\xce\xbf\xd3\xdb\xb7[\xef\x0e\xdc?\xde'
3981                          b'\x00\xf9Q\x08\xb14PK\x07\x083@\x82/ \x00\x00\x00 \x00\x00\x00PK\x03\x04\x00\x00'
3982                          b'\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3983                          b'\x18\x00\x1a\x00tensor.double.BE/versionFB\x16\x00ZZZZZZZZZZZZZZZZZZZZZZ3\nPK\x07'
3984                          b'\x08\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00PK\x01\x02\x00\x00\x00\x00\x08\x08'
3985                          b'\x00\x00\x00\x00\x00\x00S\xd3\xba&\x9b\x00\x00\x00\x9b\x00\x00\x00\x19\x00\x00'
3986                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00tensor.double.BE/da'
3987                          b'ta.pklPK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00\x00\x00\x00\x003@\x82/ '
3988                          b'\x00\x00\x00 \x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
3989                          b'\xeb\x00\x00\x00tensor.double.BE/data/0PK\x01\x02\x00\x00\x00\x00\x08\x08\x00\x00'
3990                          b'\x00\x00\x00\x00\xd1\x9egU\x02\x00\x00\x00\x02\x00\x00\x00\x18\x00\x00\x00\x00'
3991                          b'\x00\x00\x00\x00\x00\x00\x00\x00\x00p\x01\x00\x00tensor.double.BE/versionPK\x06\x06'
3992                          b',\x00\x00\x00\x00\x00\x00\x00\x1e\x03-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03'
3993                          b'\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\xd2\x00\x00\x00\x00'
3994                          b'\x00\x00\x00\xd2\x01\x00\x00\x00\x00\x00\x00PK\x06\x07\x00\x00\x00\x00\xa4\x02\x00'
3995                          b'\x00\x00\x00\x00\x00\x01\x00\x00\x00PK\x05\x06\x00\x00\x00\x00\x03\x00\x03\x00'
3996                          b'\xd2\x00\x00\x00\xd2\x01\x00\x00\x00\x00')
3997
3998        current_load_endian = get_default_load_endianness()
3999
4000        buf_be_no_bom = io.BytesIO(data_be_no_bom)
4001
4002        try:
4003            set_default_load_endianness(None)
4004            with self.assertWarnsRegex(UserWarning, "The default load endianness for checkpoints "
4005                                       "without a byteorder mark on big endian machines "
4006                                       "was changed from 'native' to 'little' endian"):
4007                tensor_be_no_bom = torch.load(buf_be_no_bom)
4008        finally:
4009            set_default_load_endianness(current_load_endian)
4010
4011    @parametrize('path_type', (str, pathlib.Path))
4012    @parametrize('weights_only', (True, False))
4013    @unittest.skipIf(IS_WINDOWS, "NamedTemporaryFile on windows")
4014    def test_serialization_mmap_loading(self, weights_only, path_type):
4015        class DummyModel(torch.nn.Module):
4016            def __init__(self):
4017                super().__init__()
4018                self.fc1 = torch.nn.Linear(3, 1024)
4019                self.fc2 = torch.nn.Linear(1024, 5)
4020
4021            def forward(self, input):
4022                return self.fc2(self.fc1(input))
4023
4024        with TemporaryFileName() as f:
4025            f = path_type(f)
4026            state_dict = DummyModel().state_dict()
4027            torch.save(state_dict, f)
4028            result = torch.load(f, mmap=True, weights_only=weights_only)
4029            result_non_mmap = torch.load(f, mmap=False, weights_only=weights_only)
4030
4031        model_mmap_state_dict = DummyModel()
4032        model_mmap_state_dict.load_state_dict(result)
4033        model_non_mmap_state_dict = DummyModel()
4034        model_non_mmap_state_dict.load_state_dict(result_non_mmap)
4035        input = torch.randn(4, 3)
4036        self.assertEqual(model_mmap_state_dict(input), model_non_mmap_state_dict(input.clone()))
4037
4038    @unittest.skipIf(not torch.cuda.is_available() or IS_WINDOWS,
4039                     "CUDA is unavailable or NamedTemporaryFile on Windows")
4040    def test_serialization_mmap_loading_with_map_location(self):
4041        class DummyModel(torch.nn.Module):
4042            def __init__(self):
4043                super().__init__()
4044                self.fc1 = torch.nn.Linear(3, 1024)
4045                self.fc2 = torch.nn.Linear(1024, 5)
4046
4047            def forward(self, input):
4048                return self.fc2(self.fc1(input))
4049
4050        # make sure mmap where tensors' location tags are not CPU does not crash
4051        # zipfile will first be mmap-ed on CPU and storages are extracted using
4052        # overall_storage[start_offset:end_offset] before running
4053        # _{device}_deserialize, which moves the storage to device
4054        with TemporaryFileName() as f:
4055            with torch.device('cuda'):
4056                m = DummyModel()
4057            state_dict = m.state_dict()
4058            torch.save(state_dict, f)
4059            result = torch.load(f, mmap=True)
4060            for v in result.values():
4061                self.assertTrue(v.is_cuda)
4062
4063    def test_serialization_mmap_loading_options(self):
4064        if IS_WINDOWS:
4065            with self.assertRaisesRegex(RuntimeError, "Changing the default mmap options is currently not supported"):
4066                torch.serialization.set_default_mmap_options(2)
4067            return
4068        m = torch.nn.Linear(3, 5)
4069        sd = m.state_dict()
4070        with tempfile.NamedTemporaryFile() as f:
4071            torch.save(sd, f)
4072            # with MmapVisibility.MAP_PRIVATE, should not be able to modify file
4073            sd_loaded = torch.load(f.name, mmap=True)
4074            sd_loaded['weight'][0][0] = 0
4075            sd_loaded2 = torch.load(f.name, mmap=True)
4076            self.assertEqual(sd_loaded2['weight'], sd['weight'])
4077            # with MmapVisibility.MAP_SHARED, should be able to modify file
4078            torch.serialization.set_default_mmap_options(MAP_SHARED)
4079            try:
4080                sd_loaded = torch.load(f.name, mmap=True)
4081                sd_loaded['weight'][0][0] = 0
4082                sd_loaded2 = torch.load(f.name, mmap=True)
4083                self.assertNotEqual(sd_loaded2['weight'], sd['weight'])
4084                self.assertEqual(sd_loaded2['weight'][0][0].item(), 0)
4085                self.assertEqual(sd_loaded2['weight'], sd_loaded['weight'])
4086            finally:
4087                torch.serialization.set_default_mmap_options(MAP_PRIVATE)
4088
4089    @parametrize('dtype', (torch.float8_e5m2, torch.float8_e4m3fn, torch.complex32))
4090    @parametrize('weights_only', (True, False))
4091    def test_serialization_dtype(self, dtype, weights_only):
4092        """ Tests that newer dtypes can be serialized using `_rebuild_tensor_v3` """
4093        with tempfile.NamedTemporaryFile() as f:
4094            x = torch.arange(0.0, 100.0).to(dtype=dtype)
4095            torch.save({'x': x, 'even': x[0::2], 'odd': x[1::2]}, f)
4096            f.seek(0)
4097            y = torch.load(f, weights_only=weights_only)
4098            self.assertEqual(y['x'], x)
4099            # Check that views are actually views
4100            y['odd'][0] = torch.tensor(0.25, dtype=dtype)
4101            y['even'][0] = torch.tensor(-0.25, dtype=dtype)
4102            self.assertEqual(y['x'][:2].to(dtype=torch.float32), torch.tensor([-0.25, 0.25]))
4103
4104    @parametrize('filename', (True, False))
4105    @unittest.skipIf(IS_WINDOWS, "NamedTemporaryFile on windows")
4106    @unittest.skipIf(IS_FBCODE, "miniz version differs between fbcode and oss")
4107    def test_filewriter_metadata_writing(self, filename):
4108        sd = torch.nn.Linear(3, 5).state_dict()
4109        weight_nbytes = sd['weight'].untyped_storage().nbytes()
4110        bias_nbytes = sd['bias'].untyped_storage().nbytes()
4111        # TemporaryFileName will give a string
4112        # NamedTemporaryFile will be treated as a buffer
4113        file_creation_func = TemporaryFileName if filename else tempfile.NamedTemporaryFile
4114
4115        with file_creation_func() as f, file_creation_func() as g:
4116            # save state_dict in f
4117            torch.save(sd, f)
4118            if not filename:
4119                f.seek(0)
4120            # extract 'data.pkl' for use in our fake checkpoint
4121            with torch.serialization._open_file_like(f, 'rb') as opened_file:
4122                with torch.serialization._open_zipfile_reader(opened_file) as zip_file:
4123                    data_file = io.BytesIO(zip_file.get_record('data.pkl'))
4124                    data_0_offset = zip_file.get_record_offset('data/0')
4125                    data_1_offset = zip_file.get_record_offset('data/1')
4126
4127            # write nulls for 'data/0' and 'data/1'
4128            with open(f if filename else f.name, 'rb+') as opened_f:
4129                opened_f.seek(data_0_offset)
4130                opened_f.write(b'0' * weight_nbytes)
4131                opened_f.seek(data_1_offset)
4132                opened_f.write(b'0' * bias_nbytes)
4133
4134            with torch.serialization._open_zipfile_writer(g) as zip_file:
4135                data_value = data_file.getvalue()
4136                zip_file.write_record('data.pkl', data_value, len(data_value))
4137                zip_file.write_record('byteorder', sys.byteorder, len(sys.byteorder))
4138                # Only write metadata for storages
4139                zip_file.write_record_metadata('data/0', weight_nbytes)
4140                zip_file.write_record_metadata('data/1', bias_nbytes)
4141
4142            if not filename:
4143                f.seek(0)
4144                g.seek(0)
4145            sd_loaded = torch.load(g)
4146            sd_loaded_ref = torch.load(f)
4147            self.assertEqual(sd_loaded, sd_loaded_ref)
4148
4149    def run(self, *args, **kwargs):
4150        with serialization_method(use_zip=True):
4151            return super().run(*args, **kwargs)
4152
4153class TestWrapperSubclass(torch.Tensor):
4154    elem: torch.Tensor
4155    __slots__ = ['elem', 'other']
4156
4157    @staticmethod
4158    def __new__(cls, elem, *args, **kwargs):
4159        # The wrapping tensor (TestSubclass) is just a meta tensor, so it
4160        # doesn't hold any memory (meta tensor is generally the preferred type
4161        # of tensor you want to make a subclass from)...
4162        r = torch.Tensor._make_subclass(cls, elem.to('meta'), elem.requires_grad)
4163        # ...the real tensor is held as an element on the tensor.
4164        r.elem = elem
4165        return r
4166
4167    def clone(self):
4168        return type(self)(self.elem.clone())
4169
4170
4171class TestGetStateSubclass(torch.Tensor):
4172    elem: torch.Tensor
4173    __slots__ = ['elem']
4174
4175    @staticmethod
4176    def __new__(cls, elem, *args, **kwargs):
4177        # The wrapping tensor (TestSubclass) is just a meta tensor, so it
4178        # doesn't hold any memory (meta tensor is generally the preferred type
4179        # of tensor you want to make a subclass from)...
4180        r = torch.Tensor._make_subclass(cls, elem.to('meta'), elem.requires_grad)
4181        # ...the real tensor is held as an element on the tensor.
4182        r.elem = elem
4183        return r
4184
4185    def __getstate__(self):
4186        return ("foo", getattr(self, "elem", None), self.__dict__)
4187
4188    def __setstate__(self, state):
4189        marker, self.elem, self.__dict__ = state
4190        if not marker == "foo":
4191            raise RuntimeError("Invalid state for TestGetStateSubclass")
4192        self.reloaded = True
4193
4194
4195class TestEmptySubclass(torch.Tensor):
4196    ...
4197
4198
4199class TestSubclassSerialization(TestCase):
4200    def test_tensor_subclass_wrapper_serialization(self):
4201        wrapped_tensor = torch.rand(2)
4202        my_tensor = TestWrapperSubclass(wrapped_tensor)
4203
4204        foo_val = "bar"
4205        my_tensor.foo = foo_val
4206        self.assertEqual(my_tensor.foo, foo_val)
4207
4208        with BytesIOContext() as f:
4209            torch.save(my_tensor, f)
4210            f.seek(0)
4211            new_tensor = torch.load(f)
4212
4213        self.assertIsInstance(new_tensor, TestWrapperSubclass)
4214        self.assertEqual(new_tensor.elem, my_tensor.elem)
4215        self.assertEqual(new_tensor.foo, foo_val)
4216
4217    def test_tensor_subclass_getstate_overwrite(self):
4218        wrapped_tensor = torch.rand(2)
4219        my_tensor = TestGetStateSubclass(wrapped_tensor)
4220
4221        foo_val = "bar"
4222        my_tensor.foo = foo_val
4223        self.assertEqual(my_tensor.foo, foo_val)
4224
4225        with BytesIOContext() as f:
4226            torch.save(my_tensor, f)
4227            f.seek(0)
4228            new_tensor = torch.load(f)
4229
4230        self.assertIsInstance(new_tensor, TestGetStateSubclass)
4231        self.assertEqual(new_tensor.elem, my_tensor.elem)
4232        self.assertEqual(new_tensor.foo, foo_val)
4233        self.assertTrue(new_tensor.reloaded)
4234
4235    def test_tensor_subclass_deepcopy(self):
4236        wrapped_tensor = torch.rand(2)
4237        my_tensor = TestWrapperSubclass(wrapped_tensor)
4238
4239        foo_val = "bar"
4240        my_tensor.foo = foo_val
4241        self.assertEqual(my_tensor.foo, foo_val)
4242
4243        new_tensor = deepcopy(my_tensor)
4244
4245        self.assertIsInstance(new_tensor, TestWrapperSubclass)
4246        self.assertEqual(new_tensor.elem, my_tensor.elem)
4247        self.assertEqual(new_tensor.foo, foo_val)
4248
4249    @parametrize('requires_grad', (True, False))
4250    def test_cloned_deepcopy(self, requires_grad):
4251        my_tensor = torch.rand(2, requires_grad=requires_grad, device='meta')
4252
4253        new_tensor = deepcopy(my_tensor)
4254
4255        self.assertEqual(new_tensor.requires_grad, my_tensor.requires_grad)
4256
4257    def test_empty_class_serialization(self):
4258        tensor = TestEmptySubclass([1.])
4259        # Ensures it runs fine
4260        tensor2 = copy.copy(tensor)
4261
4262        with BytesIOContext() as f:
4263            torch.save(tensor, f)
4264            f.seek(0)
4265            tensor2 = torch.load(f)
4266
4267        tensor = TestEmptySubclass()
4268        # Ensures it runs fine
4269        # Note that tensor.data_ptr() == 0 here
4270        tensor2 = copy.copy(tensor)
4271
4272        with BytesIOContext() as f:
4273            torch.save(tensor, f)
4274            f.seek(0)
4275            tensor2 = torch.load(f)
4276
4277    @skipIfTorchDynamo("name 'SYNTHETIC_LOCAL' is not defined")
4278    def test_safe_globals_for_weights_only(self):
4279        '''
4280        Tests import semantic for tensor subclass and the {add/get/clear}_safe_globals APIs
4281        '''
4282        t = TwoTensor(torch.randn(2, 3), torch.randn(2, 3))
4283        p = torch.nn.Parameter(t)
4284        sd = OrderedDict([('t', t), ('p', p)])
4285
4286        with tempfile.NamedTemporaryFile() as f:
4287            torch.save(sd, f)
4288
4289            # Loading tensor subclass with weights_only=True should fail
4290            # since tensor subclass is not in safe_globals
4291            with self.assertRaisesRegex(pickle.UnpicklingError,
4292                                        "Unsupported global: GLOBAL torch.testing._internal.two_tensor.TwoTensor"):
4293                f.seek(0)
4294                sd = torch.load(f, weights_only=True)
4295
4296            # Loading tensor subclass should work if the class is marked safe
4297            f.seek(0)
4298            try:
4299                torch.serialization.add_safe_globals([TwoTensor])
4300                self.assertTrue(torch.serialization.get_safe_globals() == [TwoTensor])
4301                sd = torch.load(f, weights_only=True)
4302                self.assertEqual(sd['t'], t)
4303                self.assertEqual(sd['p'], p)
4304
4305                # Should fail again when safe globals are cleared
4306                torch.serialization.clear_safe_globals()
4307                f.seek(0)
4308                with self.assertRaisesRegex(pickle.UnpicklingError,
4309                                            "Unsupported global: GLOBAL torch.testing._internal.two_tensor.TwoTensor"):
4310                    torch.load(f, weights_only=True)
4311            finally:
4312                torch.serialization.clear_safe_globals()
4313
4314    @unittest.skipIf(not torch.cuda.is_available(), "map_location loads to cuda")
4315    def test_tensor_subclass_map_location(self):
4316        t = TwoTensor(torch.randn(2, 3), torch.randn(2, 3))
4317        sd = {'t': t}
4318
4319        with TemporaryFileName() as f:
4320            torch.save(sd, f)
4321            sd_loaded = torch.load(f, map_location=torch.device('cuda:0'))
4322            self.assertTrue(sd_loaded['t'].device == torch.device('cuda:0'))
4323            self.assertTrue(sd_loaded['t'].a.device == torch.device('cuda:0'))
4324            self.assertTrue(sd_loaded['t'].b.device == torch.device('cuda:0'))
4325            # make sure map_location is not propagated over multiple torch.load calls
4326            sd_loaded = torch.load(f)
4327            self.assertTrue(sd_loaded['t'].device == torch.device('cpu'))
4328            self.assertTrue(sd_loaded['t'].a.device == torch.device('cpu'))
4329            self.assertTrue(sd_loaded['t'].b.device == torch.device('cpu'))
4330
4331
4332instantiate_device_type_tests(TestBothSerialization, globals())
4333instantiate_parametrized_tests(TestSubclassSerialization)
4334instantiate_parametrized_tests(TestOldSerialization)
4335instantiate_parametrized_tests(TestSerialization)
4336
4337if __name__ == '__main__':
4338    run_tests()
4339