From 67c0cd86b3a3247cb4411170b78723e6deddc772 Mon Sep 17 00:00:00 2001 From: Yi Xu Date: Wed, 30 Nov 2022 11:15:48 +0800 Subject: [PATCH] [Doc] [lang] Cherrypick commits related to packed mode (#6765) ### Brief Summary Cherrypicks #6755 and #6753 into v1.3.0 release branch. Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- docs/lang/articles/basic/layout.md | 26 ++++++-------------------- python/taichi/lang/misc.py | 11 +++++++++++ taichi/ir/snode.cpp | 8 +++----- tests/python/test_deprecation.py | 18 ++++++++++++++++++ 4 files changed, 38 insertions(+), 25 deletions(-) diff --git a/docs/lang/articles/basic/layout.md b/docs/lang/articles/basic/layout.md index db46b10ddbdad..327bf178676ff 100644 --- a/docs/lang/articles/basic/layout.md +++ b/docs/lang/articles/basic/layout.md @@ -323,6 +323,12 @@ ti.root.dense(ti.ij, (M // 8, N // 8)).dense(ti.ij, (8, 8)).place(val) where `M` and `N` are multiples of 8. We encourage you to try this out! The performance difference can be significant! +:::note + +We highly recommend that you use power-of-two block size so that accelerated indexing with bitwise arithmetic and better memory address alignment can be enabled. + +::: + ## Manage memory occupancy ### Manual field allocation and destruction @@ -358,23 +364,3 @@ fb2_snode_tree.destroy() # Destruction ``` Actually, the above demonstrated `ti.root` statements are implemented with `FieldsBuilder`, despite that `ti.root` has the capability to automatically manage memory allocations and recycling. - -### Packed mode - -By default, Taichi implicitly fits a field in a larger buffer with power-of-two dimensions. We take the power-of-two padding convention because it is widely adopted in computer graphics. The design enables fast indexing with bitwise arithmetic and better memory address alignment, while trading off memory occupations. - -For example, a `(18, 65)` field is materialized with a `(32, 128)` buffer, which is acceptable. As field size grows, the padding strategy can be exaggeratedly unbearable: `(129, 6553600)` will be expanded to `(256, 6335600)`, which allocates considerable unused blank memory. Therefore, Taichi provides the optional packed mode to allocate buffer that tightly fits the requested field shape. It is especially useful when memory usage is a major concern. - -To leverage the packed mode, specify `packed` in `ti.init()` argument: - -```python -ti.init() # default: packed=False -a = ti.field(ti.i32, shape=(18, 65)) # padded to (32, 128) -``` - -```python -ti.init(packed=True) -a = ti.field(ti.i32, shape=(18, 65)) # no padding -``` - -You might observe mild performance regression with the packed mode due to more complex addressing and memory alignment. Therefore, the packed mode should be specified only when memory capacity is a major concern. diff --git a/python/taichi/lang/misc.py b/python/taichi/lang/misc.py index 90e2bb270b5bb..0ff541f659e58 100644 --- a/python/taichi/lang/misc.py +++ b/python/taichi/lang/misc.py @@ -356,6 +356,17 @@ def init(arch=None, if require_version is not None: check_require_version(require_version) + if "packed" in kwargs: + if kwargs["packed"] is True: + warnings.warn( + "Currently packed=True is the default setting and the switch will be removed in v1.4.0.", + DeprecationWarning) + else: + warnings.warn( + "The automatic padding mode (packed=False) will no longer exist in v1.4.0. The switch will " + "also be removed then. Make sure your code doesn't rely on it.", + DeprecationWarning) + if "default_up" in kwargs: raise KeyError( "'default_up' is always the unsigned type of 'default_ip'. Please set 'default_ip' instead." diff --git a/taichi/ir/snode.cpp b/taichi/ir/snode.cpp index 1f5195a160ee5..5d44cc06d6b42 100644 --- a/taichi/ir/snode.cpp +++ b/taichi/ir/snode.cpp @@ -64,11 +64,9 @@ SNode &SNode::create_node(std::vector axes, } else { TI_WARN_IF( packed && !bit::is_power_of_two(sizes[i]), - "Non-first division of an axis on a SNodeTree path should be a power " - "of two to achieve best performance:\n{} We plan to turn this " - "warning into an error at v1.4.0. If you do have a use case that " - "needs to violate this rule, please submit an issue to notify us.", - tb); + "Shape {} is detected on non-first division of axis {}:\n{} For " + "best performance, we recommend that you set it to a power of two.", + sizes[i], char('i' + ind), tb); } new_node.extractors[ind].activate( bit::log2int(bit::least_pot_bound(sizes[i]))); diff --git a/tests/python/test_deprecation.py b/tests/python/test_deprecation.py index 3aaaf477d6813..2c56b02277670 100644 --- a/tests/python/test_deprecation.py +++ b/tests/python/test_deprecation.py @@ -92,3 +92,21 @@ def test_deprecate_metal_sparse(): "Dynamic SNode on metal backend is deprecated and removed in this release." ): ti.root.dynamic(ti.i, 10) + + +def test_deprecated_packed_true(): + with pytest.warns( + DeprecationWarning, + match= + "Currently packed=True is the default setting and the switch will be removed in v1.4.0." + ): + ti.init(packed=True) + + +def test_deprecated_packed_false(): + with pytest.warns( + DeprecationWarning, + match= + r"The automatic padding mode \(packed=False\) will no longer exist in v1.4.0. The switch will " + "also be removed then. Make sure your code doesn't rely on it."): + ti.init(packed=False)