ManimCommunity/manim

Polygon tries to allocate 8.7 PiB of memory when rounding corners

Open

#3052 opened on Nov 30, 2022

View on GitHub
 (1 comment) (1 reaction) (0 assignees)Python (17,820 stars) (1,378 forks)batch import
good first issueissue:bug

Description

Description of bug / unexpected behavior

Drawing a Polygon of three points that lie on a line tries to allocate 8.70 PiB of memory.

Expected behavior

I expected manim to maybe throw an error or draw a straight line (but not try to allocate 8.70 PiB of memory).

How to reproduce the issue

from manim import *

class PolygonTestScene(Scene):
    def construct(self):
        # letting all points be on a line and then rounding corners
        # tries to allocate 8.70 PiB of memory
        points = [
            [-1, 0, 0],
            [0, 0, 0],
            [1, 0, 0],
        ]

        p = Polygon(*points)
        p.round_corners(0.15)  # here it happens
        self.play(Create(p))

Logs

Manim Community v0.16.0.post0

╭──────────────────────────── Traceback (most recent call last) ────────────────────────────╮
│ /Users/mxmerz/Library/Caches/pypoetry/virtualenvs/boolean-functions-nRWsek1T-py3.10/lib/p │
│ ython3.10/site-packages/manim/cli/render/commands.py:121 in render                        │
│                                                                                           │
│   118 │   │   │   try:                                                                    │
│   119 │   │   │   │   with tempconfig(config):                                            │
│   120 │   │   │   │   │   scene = SceneClass()                                            │
│ ❱ 121 │   │   │   │   │   scene.render()                                                  │
│   122 │   │   │   except Exception:                                                       │
│   123 │   │   │   │   error_console.print_exception()                                     │
│   124 │   │   │   │   sys.exit(1)                                                         │
│                                                                                           │
│ /Users/mxmerz/Library/Caches/pypoetry/virtualenvs/boolean-functions-nRWsek1T-py3.10/lib/p │
│ ython3.10/site-packages/manim/scene/scene.py:222 in render                                │
│                                                                                           │
│    219 │   │   """                                                                        │
│    220 │   │   self.setup()                                                               │
│    221 │   │   try:                                                                       │
│ ❱  222 │   │   │   self.construct()                                                       │
│    223 │   │   except EndSceneEarlyException:                                             │
│    224 │   │   │   pass                                                                   │
│    225 │   │   except RerunSceneException as e:                                           │
│                                                                                           │
│ /Users/mxmerz/Work/src/research/hypercube-graphs/contrib/draw_test.py:15 in construct     │
│                                                                                           │
│   12 │   │   ]                                                                            │
│   13 │   │                                                                                │
│   14 │   │   p = Polygon(*points)                                                         │
│ ❱ 15 │   │   p.round_corners(0.15)  # here it happens                                     │
│   16 │   │   self.play(Create(p))                                                         │
│   17                                                                                      │
│                                                                                           │
│ /Users/mxmerz/Library/Caches/pypoetry/virtualenvs/boolean-functions-nRWsek1T-py3.10/lib/p │
│ ython3.10/site-packages/manim/mobject/geometry/polygram.py:207 in round_corners           │
│                                                                                           │
│   204 │   │   │   │   # Make sure anchors are evenly distributed                          │
│   205 │   │   │   │   len_ratio = line.get_length() / arc1.get_arc_length()               │
│   206 │   │   │   │                                                                       │
│ ❱ 207 │   │   │   │   line.insert_n_curves(int(arc1.get_num_curves() * len_ratio))        │
│   208 │   │   │   │                                                                       │
│   209 │   │   │   │   new_points.extend(line.points)                                      │
│   210                                                                                     │
│                                                                                           │
│ /Users/mxmerz/Library/Caches/pypoetry/virtualenvs/boolean-functions-nRWsek1T-py3.10/lib/p │
│ ython3.10/site-packages/manim/mobject/types/vectorized_mobject.py:1475 in insert_n_curves │
│                                                                                           │
│   1472 │   │   if self.has_new_path_started():                                            │
│   1473 │   │   │   new_path_point = self.get_last_point()                                 │
│   1474 │   │                                                                              │
│ ❱ 1475 │   │   new_points = self.insert_n_curves_to_point_list(n, self.points)            │
│   1476 │   │   self.set_points(new_points)                                                │
│   1477 │   │                                                                              │
│   1478 │   │   if new_path_point is not None:                                             │
│                                                                                           │
│ /Users/mxmerz/Library/Caches/pypoetry/virtualenvs/boolean-functions-nRWsek1T-py3.10/lib/p │
│ ython3.10/site-packages/manim/mobject/types/vectorized_mobject.py:1509 in                 │
│ insert_n_curves_to_point_list                                                             │
│                                                                                           │
│   1506 │   │   # it's total length is target_num.  For example,                           │
│   1507 │   │   # with curr_num = 10, target_num = 15, this would                          │
│   1508 │   │   # be [0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9]                         │
│ ❱ 1509 │   │   repeat_indices = (np.arange(target_num, dtype="i") * curr_num) // target_n │
│   1510 │   │                                                                              │
│   1511 │   │   # If the nth term of this list is k, it means                              │
│   1512 │   │   # that the nth curve of our path should be split                           │
╰───────────────────────────────────────────────────────────────────────────────────────────╯
MemoryError: Unable to allocate 8.70 PiB for an array with shape (2449685902979305,) and data
type int32

System specifications

  • OS: macOS Ventura 13.0.1 (22A400)
  • RAM: 16GB (<8.70 PiB)
  • Python version: 3.10.8

Additional comments

  • This also works with just two points.
  • I assume this is because in these cases, arc1.get_arc_length() is very small, which leads to len_ratio = line.get_length() / arc1.get_arc_length() being very large.

Contributor guide