nvmath-python 0.5.0__cp313-cp313-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nvmath/__init__.pxd +0 -0
- nvmath/__init__.py +37 -0
- nvmath/_internal/__init__.py +0 -0
- nvmath/_internal/layout.py +58 -0
- nvmath/_utils.py +363 -0
- nvmath/bindings/__init__.pxd +0 -0
- nvmath/bindings/__init__.py +44 -0
- nvmath/bindings/_internal/__init__.pxd +0 -0
- nvmath/bindings/_internal/__init__.py +0 -0
- nvmath/bindings/_internal/cublas.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cublas.pxd +518 -0
- nvmath/bindings/_internal/cublasLt.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cublasLt.pxd +54 -0
- nvmath/bindings/_internal/cudss.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cudss.pxd +44 -0
- nvmath/bindings/_internal/cufft.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cufft.pxd +69 -0
- nvmath/bindings/_internal/cufftMp.pxd +77 -0
- nvmath/bindings/_internal/curand.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/curand.pxd +42 -0
- nvmath/bindings/_internal/cusolver.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cusolver.pxd +15 -0
- nvmath/bindings/_internal/cusolverDn.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cusolverDn.pxd +386 -0
- nvmath/bindings/_internal/cusparse.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cusparse.pxd +270 -0
- nvmath/bindings/_internal/mathdx.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/mathdx.pxd +79 -0
- nvmath/bindings/_internal/nvshmem.pxd +29 -0
- nvmath/bindings/_internal/utils.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/utils.pxd +186 -0
- nvmath/bindings/cublas.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cublas.pxd +545 -0
- nvmath/bindings/cublas.pyi +18 -0
- nvmath/bindings/cublasLt.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cublasLt.pxd +99 -0
- nvmath/bindings/cudss.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cudss.pxd +83 -0
- nvmath/bindings/cudss.pyi +249 -0
- nvmath/bindings/cufft.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cufft.pxd +114 -0
- nvmath/bindings/cufftMp.pxd +124 -0
- nvmath/bindings/curand.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/curand.pxd +71 -0
- nvmath/bindings/cusolver.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cusolver.pxd +60 -0
- nvmath/bindings/cusolverDn.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cusolverDn.pxd +410 -0
- nvmath/bindings/cusparse.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cusparse.pxd +329 -0
- nvmath/bindings/cycublas.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cycublas.pxd +657 -0
- nvmath/bindings/cycublasLt.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cycublasLt.pxd +1010 -0
- nvmath/bindings/cycudss.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cycudss.pxd +191 -0
- nvmath/bindings/cycufft.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cycufft.pxd +320 -0
- nvmath/bindings/cycufftMp.pxd +333 -0
- nvmath/bindings/cycurand.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cycurand.pxd +146 -0
- nvmath/bindings/cycusolver.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cycusolver.pxd +143 -0
- nvmath/bindings/cycusolverDn.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cycusolverDn.pxd +414 -0
- nvmath/bindings/cycusparse.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cycusparse.pxd +476 -0
- nvmath/bindings/cymathdx.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cymathdx.pxd +363 -0
- nvmath/bindings/cynvshmem.pxd +126 -0
- nvmath/bindings/mathdx.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/mathdx.pxd +131 -0
- nvmath/bindings/mathdx.pyi +686 -0
- nvmath/bindings/nvpl/__init__.pxd +0 -0
- nvmath/bindings/nvpl/__init__.py +11 -0
- nvmath/bindings/nvpl/_internal/__init__.pxd +0 -0
- nvmath/bindings/nvpl/_internal/__init__.py +0 -0
- nvmath/bindings/nvpl/_internal/fft.pxd +36 -0
- nvmath/bindings/nvpl/cyfft.pxd +87 -0
- nvmath/bindings/nvpl/fft.pxd +100 -0
- nvmath/bindings/nvshmem.pxd +54 -0
- nvmath/device/__init__.py +23 -0
- nvmath/device/_deprecated.py +33 -0
- nvmath/device/caching.py +51 -0
- nvmath/device/common.py +131 -0
- nvmath/device/common_backend.py +125 -0
- nvmath/device/common_cuda.py +156 -0
- nvmath/device/common_mathdx.py +97 -0
- nvmath/device/common_numba.py +159 -0
- nvmath/device/common_opaque_tensor.py +128 -0
- nvmath/device/cublasdx.py +1085 -0
- nvmath/device/cublasdx_backend.py +552 -0
- nvmath/device/cublasdx_numba.py +528 -0
- nvmath/device/cufftdx.py +551 -0
- nvmath/device/cufftdx_backend.py +194 -0
- nvmath/device/cufftdx_numba.py +123 -0
- nvmath/device/curand_kernel.py +9147 -0
- nvmath/device/nvrtc.py +95 -0
- nvmath/device/patch.py +35 -0
- nvmath/device/random.py +417 -0
- nvmath/device/random_helpers.py +23 -0
- nvmath/device/random_states.py +189 -0
- nvmath/device/types.py +11 -0
- nvmath/device/vector_types_numba.py +203 -0
- nvmath/distributed/__init__.py +117 -0
- nvmath/distributed/_internal/__init__.py +0 -0
- nvmath/distributed/_internal/nvshmem.py +243 -0
- nvmath/distributed/_internal/tensor_ifc_cupy.py +111 -0
- nvmath/distributed/_internal/tensor_ifc_numpy.py +53 -0
- nvmath/distributed/_internal/tensor_ifc_torch.py +108 -0
- nvmath/distributed/_internal/tensor_wrapper.py +59 -0
- nvmath/distributed/_utils.py +152 -0
- nvmath/distributed/fft/__init__.py +6 -0
- nvmath/distributed/fft/_configuration.py +86 -0
- nvmath/distributed/fft/fft.py +1737 -0
- nvmath/distributed/reshape/__init__.py +6 -0
- nvmath/distributed/reshape/_configuration.py +39 -0
- nvmath/distributed/reshape/reshape.py +1249 -0
- nvmath/fft/__init__.py +7 -0
- nvmath/fft/_configuration.py +208 -0
- nvmath/fft/_exec_utils.py +116 -0
- nvmath/fft/_helpers.py +260 -0
- nvmath/fft/fft.py +2346 -0
- nvmath/internal/__init__.py +5 -0
- nvmath/internal/enum_utils.py +142 -0
- nvmath/internal/formatters.py +87 -0
- nvmath/internal/mem_limit.py +51 -0
- nvmath/internal/package_ifc.py +119 -0
- nvmath/internal/package_ifc_cuda.py +43 -0
- nvmath/internal/package_ifc_cupy.py +49 -0
- nvmath/internal/package_ifc_torch.py +31 -0
- nvmath/internal/package_wrapper.py +14 -0
- nvmath/internal/tensor_ifc.py +143 -0
- nvmath/internal/tensor_ifc_cupy.py +185 -0
- nvmath/internal/tensor_ifc_numpy.py +157 -0
- nvmath/internal/tensor_ifc_torch.py +115 -0
- nvmath/internal/tensor_wrapper.py +160 -0
- nvmath/internal/typemaps.py +154 -0
- nvmath/internal/utils.py +634 -0
- nvmath/linalg/__init__.py +11 -0
- nvmath/linalg/_internal/__init__.py +3 -0
- nvmath/linalg/_internal/algo_cap_ifc.py +86 -0
- nvmath/linalg/_internal/algo_config_ifc.py +87 -0
- nvmath/linalg/_internal/enum_to_tuples.py +64 -0
- nvmath/linalg/_internal/epilog_protocol.py +738 -0
- nvmath/linalg/_internal/matmul_desc_ifc.py +72 -0
- nvmath/linalg/_internal/matmul_pref_ifc.py +65 -0
- nvmath/linalg/_internal/matrix_layout_ifc.py +59 -0
- nvmath/linalg/_internal/typemaps.py +135 -0
- nvmath/linalg/_internal/utils.py +96 -0
- nvmath/linalg/advanced/__init__.py +8 -0
- nvmath/linalg/advanced/_algorithmmod.py +142 -0
- nvmath/linalg/advanced/_configuration.py +320 -0
- nvmath/linalg/advanced/helpers/__init__.py +5 -0
- nvmath/linalg/advanced/helpers/matmul.py +173 -0
- nvmath/linalg/advanced/matmulmod.py +2855 -0
- nvmath/memory.py +266 -0
- nvmath/sparse/__init__.py +18 -0
- nvmath/sparse/_internal/__init__.py +21 -0
- nvmath/sparse/_internal/common_utils.py +81 -0
- nvmath/sparse/_internal/cudss_config_ifc.py +584 -0
- nvmath/sparse/_internal/cudss_data_ifc.py +291 -0
- nvmath/sparse/_internal/cudss_utils.py +398 -0
- nvmath/sparse/_internal/sparse_csr_ifc.py +154 -0
- nvmath/sparse/_internal/sparse_format_helpers.py +88 -0
- nvmath/sparse/_internal/sparse_tensor_ifc.py +80 -0
- nvmath/sparse/advanced/__init__.py +7 -0
- nvmath/sparse/advanced/_configuration.py +150 -0
- nvmath/sparse/advanced/direct_solver.py +1705 -0
- nvmath_python-0.5.0.dist-info/METADATA +122 -0
- nvmath_python-0.5.0.dist-info/RECORD +174 -0
- nvmath_python-0.5.0.dist-info/WHEEL +5 -0
- nvmath_python-0.5.0.dist-info/licenses/LICENSE +177 -0
- nvmath_python-0.5.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
__all__ = ["allocate_symmetric_memory", "free_symmetric_memory"]
|
|
8
|
+
|
|
9
|
+
from logging import Logger
|
|
10
|
+
from collections.abc import Iterable, Sequence
|
|
11
|
+
from types import ModuleType
|
|
12
|
+
from typing import Literal
|
|
13
|
+
|
|
14
|
+
from typing import TYPE_CHECKING
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
import torch
|
|
18
|
+
|
|
19
|
+
import numpy as np
|
|
20
|
+
from numpy.typing import DTypeLike
|
|
21
|
+
|
|
22
|
+
import nvmath.distributed
|
|
23
|
+
from nvmath.internal.utils import device_ctx
|
|
24
|
+
from nvmath.distributed._internal import tensor_wrapper
|
|
25
|
+
|
|
26
|
+
from ._internal.nvshmem import free as nvshmem_free_wrapper
|
|
27
|
+
|
|
28
|
+
# Supported packages for tensors backed by symmetric memory.
|
|
29
|
+
_SUPPORTED_PACKAGES = ("cupy", "torch")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# TODO: do a general refactor of this function in nvmath
|
|
33
|
+
def calculate_strides(shape: Sequence[int], axis_order: Iterable[int]):
|
|
34
|
+
"""
|
|
35
|
+
Calculate the strides for the provided shape and axis order.
|
|
36
|
+
"""
|
|
37
|
+
strides = [0] * len(shape)
|
|
38
|
+
|
|
39
|
+
stride = 1
|
|
40
|
+
for axis in axis_order:
|
|
41
|
+
strides[axis] = stride
|
|
42
|
+
stride *= shape[axis]
|
|
43
|
+
|
|
44
|
+
return strides
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def allocate_symmetric_memory(
|
|
48
|
+
shape: int | Sequence[int],
|
|
49
|
+
package: ModuleType,
|
|
50
|
+
*,
|
|
51
|
+
dtype: DTypeLike | torch.dtype | None = None,
|
|
52
|
+
axis_order: Literal["C", "F"] | Sequence[int] | None = None,
|
|
53
|
+
make_symmetric: bool = False,
|
|
54
|
+
logger: Logger | None = None,
|
|
55
|
+
):
|
|
56
|
+
"""Return uninitialized tensor of given shape and type, allocated from the symmetric
|
|
57
|
+
heap, on the device on which nvmath.distributed was initialized. The tensor type is
|
|
58
|
+
determined by the provided package (e.g. cupy, torch).
|
|
59
|
+
**This is a collective operation and must be called by all processes**.
|
|
60
|
+
Note that the buffer size must be the same on all processes, or you can
|
|
61
|
+
use ``make_symmetric=True`` to pad all buffers to the same max size.
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
shape: Shape of the tensor to allocate.
|
|
65
|
+
|
|
66
|
+
package: Python package determining the tensor type (e.g. cupy, torch).
|
|
67
|
+
|
|
68
|
+
dtype: Tensor dtype.
|
|
69
|
+
|
|
70
|
+
axis_order: Axis order.
|
|
71
|
+
|
|
72
|
+
make_symmetric: If buffer sizes do not match across processes, will allocate
|
|
73
|
+
the maximum size on every process to ensure the allocation is symmetric.
|
|
74
|
+
|
|
75
|
+
logger (logging.Logger): Python Logger object. The root logger will be used if a
|
|
76
|
+
logger object is not provided.
|
|
77
|
+
"""
|
|
78
|
+
|
|
79
|
+
if package.__name__ not in _SUPPORTED_PACKAGES:
|
|
80
|
+
raise ValueError(f"The package must be one of {_SUPPORTED_PACKAGES}. Got {package}.")
|
|
81
|
+
|
|
82
|
+
distributed_ctx = nvmath.distributed.get_context()
|
|
83
|
+
if distributed_ctx is None:
|
|
84
|
+
raise RuntimeError("nvmath.distributed has not been initialized")
|
|
85
|
+
|
|
86
|
+
device_id = distributed_ctx.device_id
|
|
87
|
+
|
|
88
|
+
if isinstance(shape, int):
|
|
89
|
+
shape = (shape,)
|
|
90
|
+
|
|
91
|
+
strides = None
|
|
92
|
+
if axis_order is not None:
|
|
93
|
+
if axis_order == "C":
|
|
94
|
+
strides = calculate_strides(shape, reversed(range(len(shape))))
|
|
95
|
+
elif axis_order == "F":
|
|
96
|
+
strides = calculate_strides(shape, range(len(shape)))
|
|
97
|
+
else:
|
|
98
|
+
strides = calculate_strides(shape, axis_order)
|
|
99
|
+
|
|
100
|
+
if package.__name__ == "cupy":
|
|
101
|
+
from ._internal.tensor_ifc_cupy import CupyDistributedTensor
|
|
102
|
+
|
|
103
|
+
if dtype is None:
|
|
104
|
+
# This mimics numpy and cupy
|
|
105
|
+
dtype = np.float64
|
|
106
|
+
|
|
107
|
+
dtype = np.dtype(dtype).name # type: ignore
|
|
108
|
+
return CupyDistributedTensor.empty(
|
|
109
|
+
shape, dtype=dtype, device_id=device_id, strides=strides, make_symmetric=make_symmetric, logger=logger
|
|
110
|
+
).tensor
|
|
111
|
+
elif package.__name__ == "torch":
|
|
112
|
+
from ._internal.tensor_ifc_torch import TorchDistributedTensor
|
|
113
|
+
|
|
114
|
+
if dtype is None:
|
|
115
|
+
import torch
|
|
116
|
+
|
|
117
|
+
dtype = torch.get_default_dtype()
|
|
118
|
+
|
|
119
|
+
dtype = str(dtype).split(".")[1]
|
|
120
|
+
return TorchDistributedTensor.empty(
|
|
121
|
+
shape, dtype=dtype, device_id=device_id, strides=strides, make_symmetric=make_symmetric, logger=logger
|
|
122
|
+
).tensor
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def free_symmetric_memory(*tensors) -> None:
|
|
126
|
+
"""Frees tensors' data buffer where the buffer was allocated on the symmetric heap.
|
|
127
|
+
Note that this is only meant to be called on tensors returned by
|
|
128
|
+
``allocate_symmetric_memory()``.
|
|
129
|
+
|
|
130
|
+
**This is a collective operation and must be called by all processes, with tensors
|
|
131
|
+
in the same order**."""
|
|
132
|
+
for tensor in tensors:
|
|
133
|
+
package = _get_tensor_package(tensor)
|
|
134
|
+
if package not in _SUPPORTED_PACKAGES:
|
|
135
|
+
raise ValueError(
|
|
136
|
+
f"The tensor package must be one of {_SUPPORTED_PACKAGES}. Got {type(tensor)} from package {package}."
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
for tensor in tensors:
|
|
140
|
+
wrapped_tensor = tensor_wrapper.wrap_operand(tensor)
|
|
141
|
+
if not isinstance(wrapped_tensor.device_id, int):
|
|
142
|
+
raise ValueError("Tensor must be on GPU symmetric memory")
|
|
143
|
+
with device_ctx(wrapped_tensor.device_id):
|
|
144
|
+
nvshmem_free_wrapper(wrapped_tensor.data_ptr)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def _get_tensor_package(tensor):
|
|
148
|
+
if issubclass(tensor.__class__, np.ndarray):
|
|
149
|
+
return "numpy"
|
|
150
|
+
module = tensor.__class__.__module__
|
|
151
|
+
package = module.split(".")[0]
|
|
152
|
+
return package
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
__all__ = ["FFTDirection", "FFTOptions", "Slab"]
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
from enum import IntEnum
|
|
9
|
+
from logging import Logger
|
|
10
|
+
from typing import Literal
|
|
11
|
+
from nvmath.bindings import cufftMp # type: ignore
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass
|
|
15
|
+
class FFTOptions:
|
|
16
|
+
"""
|
|
17
|
+
A data class for providing options to the :class:`FFT` object and the family of wrapper
|
|
18
|
+
functions :func:`fft` and :func:`ifft`.
|
|
19
|
+
|
|
20
|
+
Attributes:
|
|
21
|
+
fft_type: The type of FFT to perform, available options include ``'C2C'``.
|
|
22
|
+
|
|
23
|
+
reshape: Reshape the output distribution to the same slab distribution used by the
|
|
24
|
+
input. This only applies when using a Slab distribution. The default is `True`.
|
|
25
|
+
|
|
26
|
+
logger (logging.Logger): Python Logger object. The root logger will be used if a
|
|
27
|
+
logger object is not provided.
|
|
28
|
+
|
|
29
|
+
blocking: A flag specifying the behavior of the execution functions and methods,
|
|
30
|
+
such as :func:`fft` and :meth:`FFT.execute`. When ``blocking`` is `True`, the
|
|
31
|
+
execution methods do not return until the operation is complete. When
|
|
32
|
+
``blocking`` is ``"auto"``, the methods return immediately when the input tensor
|
|
33
|
+
is on the GPU. The execution methods always block when the input tensor is on
|
|
34
|
+
the CPU, to ensure that the user doesn't inadvertently use the result before it
|
|
35
|
+
becomes available. The default is ``"auto"``.
|
|
36
|
+
|
|
37
|
+
See Also:
|
|
38
|
+
:class:`FFT`, :func:`fft` and :func:`ifft`.
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
fft_type: Literal["C2C"] | None = None
|
|
42
|
+
reshape: bool = True
|
|
43
|
+
logger: Logger | None = None
|
|
44
|
+
blocking: Literal[True, "auto"] = "auto"
|
|
45
|
+
|
|
46
|
+
def __post_init__(self):
|
|
47
|
+
valid_fft_types = [None, "C2C"]
|
|
48
|
+
if self.fft_type not in valid_fft_types:
|
|
49
|
+
raise ValueError(f"The value specified for 'fft_type' must be one of {valid_fft_types}.")
|
|
50
|
+
|
|
51
|
+
if not isinstance(self.reshape, bool):
|
|
52
|
+
raise ValueError("The value specified for 'reshape' must be of type bool (True or False).")
|
|
53
|
+
|
|
54
|
+
if self.blocking not in (True, "auto"):
|
|
55
|
+
raise ValueError("The value specified for 'blocking' must be either True or 'auto'.")
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class FFTDirection(IntEnum):
|
|
59
|
+
"""An IntEnum class specifying the direction of the transform.
|
|
60
|
+
|
|
61
|
+
See Also:
|
|
62
|
+
:meth:`FFT.execute`, :func:`fft`
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
FORWARD = -1
|
|
66
|
+
INVERSE = 1
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class Slab(IntEnum):
|
|
70
|
+
"""An IntEnum class to specify a cuFFTMp Slab distribution.
|
|
71
|
+
|
|
72
|
+
Given an array of size X * Y * Z distributed over n GPUs, there are two possible slab
|
|
73
|
+
distributions depending on whether the data is partitioned on the X or Y axis:
|
|
74
|
+
|
|
75
|
+
* X axis partitioning: the first X % n GPUs each own (X/n+1) * Y * Z elements and
|
|
76
|
+
the remaining GPUs each own (X/n) * Y * Z elements.
|
|
77
|
+
|
|
78
|
+
* Y axis partitioning: the first Y % n GPUs each own X * (Y/n+1) * Z elements and
|
|
79
|
+
the remaining GPUs each own X * (Y/n) * Z elements.
|
|
80
|
+
|
|
81
|
+
See Also:
|
|
82
|
+
:class:`FFT`, :func:`fft`
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
X = cufftMp.XtSubFormat.FORMAT_INPLACE
|
|
86
|
+
Y = cufftMp.XtSubFormat.FORMAT_INPLACE_SHUFFLED
|