Jason Lowe-Power has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/67472?usp=email )

Change subject: stdlib: Add progress bars for long functions
......................................................................

stdlib: Add progress bars for long functions

This adds a progress bar for downloading large files and computing
md5sums on large files.

Change-Id: Iddc9faf61e861837cc1e2e3b3dbdbeebd6ccf529
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/67472
Tested-by: kokoro <noreply+kok...@google.com>
Reviewed-by: Melissa Jost <melissakj...@gmail.com>
Maintainer: Jason Lowe-Power <power...@gmail.com>
---
A optional-requirements.txt
M src/python/SConscript
M src/python/gem5/resources/downloader.py
M src/python/gem5/resources/md5_utils.py
A src/python/gem5/utils/progress_bar.py
5 files changed, 132 insertions(+), 6 deletions(-)

Approvals:
  kokoro: Regressions pass
  Melissa Jost: Looks good to me, approved
  Jason Lowe-Power: Looks good to me, approved




diff --git a/optional-requirements.txt b/optional-requirements.txt
new file mode 100644
index 0000000..f88787d
--- /dev/null
+++ b/optional-requirements.txt
@@ -0,0 +1 @@
+tqdm==4.64.1
diff --git a/src/python/SConscript b/src/python/SConscript
index 900723b..b0f11dd 100644
--- a/src/python/SConscript
+++ b/src/python/SConscript
@@ -267,6 +267,7 @@
 PySource('gem5.utils', 'gem5/utils/__init__.py')
 PySource('gem5.utils', 'gem5/utils/filelock.py')
 PySource('gem5.utils', 'gem5/utils/override.py')
+PySource('gem5.utils', 'gem5/utils/progress_bar.py')
 PySource('gem5.utils', 'gem5/utils/requires.py')
 PySource('gem5.utils.multiprocessing',
     'gem5/utils/multiprocessing/__init__.py')
diff --git a/src/python/gem5/resources/downloader.py b/src/python/gem5/resources/downloader.py
index 4a2ed5d..24b8970 100644
--- a/src/python/gem5/resources/downloader.py
+++ b/src/python/gem5/resources/downloader.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2021 The Regents of the University of California
+# Copyright (c) 2021-2023 The Regents of the University of California
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -42,6 +42,7 @@
 from typing import List, Dict, Set, Optional

 from .md5_utils import md5_file, md5_dir
+from ..utils.progress_bar import tqdm, progress_hook

 from ..utils.filelock import FileLock

@@ -286,10 +287,26 @@
                 # get the file as a bytes blob
                 request = urllib.request.Request(url)
                 with urllib.request.urlopen(request, context=ctx) as fr:
-                    with open(download_to, "wb") as fw:
-                        fw.write(fr.read())
+                    with tqdm.wrapattr(
+                        open(download_to, "wb"),
+                        "write",
+                        miniters=1,
+                        desc="Downloading {download_to}",
+                        total=getattr(fr, "length", None),
+                    ) as fw:
+                        for chunk in fr:
+                            fw.write(chunk)
             else:
-                urllib.request.urlretrieve(url, download_to)
+                with tqdm(
+                    unit="B",
+                    unit_scale=True,
+                    unit_divisor=1024,
+                    miniters=1,
+                    desc=f"Downloading {download_to}",
+                ) as t:
+                    urllib.request.urlretrieve(
+                        url, download_to, reporthook=progress_hook(t)
+                    )
             return
         except HTTPError as e:
             # If the error code retrieved is retryable, we retry using a
diff --git a/src/python/gem5/resources/md5_utils.py b/src/python/gem5/resources/md5_utils.py
index d7212ab..f4a1a87 100644
--- a/src/python/gem5/resources/md5_utils.py
+++ b/src/python/gem5/resources/md5_utils.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2022 The Regents of the University of California
+# Copyright (c) 2022-2023 The Regents of the University of California
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,22 @@

 def _md5_update_from_file(filename: Path, hash: Hash) -> Hash:
     assert filename.is_file()
-    with open(str(filename), "rb") as f:
+
+    if filename.stat().st_size < 1024 * 1024 * 100:
+        from ..utils.progress_bar import FakeTQDM
+
+        # if the file is less than 100MB, no need to show a progress bar.
+        tqdm = FakeTQDM()
+    else:
+        from ..utils.progress_bar import tqdm
+
+    with tqdm.wrapattr(
+        open(str(filename), "rb"),
+        "read",
+        miniters=1,
+        desc=f"Computing md5sum on {filename}",
+        total=filename.stat().st_size,
+    ) as f:
         for chunk in iter(lambda: f.read(4096), b""):
             hash.update(chunk)
     return hash
diff --git a/src/python/gem5/utils/progress_bar.py b/src/python/gem5/utils/progress_bar.py
new file mode 100644
index 0000000..0ac1320
--- /dev/null
+++ b/src/python/gem5/utils/progress_bar.py
@@ -0,0 +1,76 @@
+# Copyright (c) 2023 The Regents of the University of California
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+class FakeTQDM:
+    """This is a fake wrapper so that the tqdm calls work whether or not it
+    has been installed.
+    """
+
+    def __call__(*args, **kwargs):
+        if args:
+            return args[0]
+        return kwargs.get("iterable", None)
+
+    def wrapattr(self, *args, **kwargs):
+        if args:
+            return args[0]
+        return kwargs.get("iterable", None)
+
+    def __enter__(self):
+        pass
+
+    def __exit__(self, exc_type, exc_val, exc_tb):
+        pass
+
+
+try:
+    from tqdm.auto import tqdm
+
+    _have_tqdm = True
+except ImportError:
+    tqdm = FakeTQDM()
+    _have_tqdm = False
+
+# Hook for the progress bar
+def progress_hook(t):
+    if not _have_tqdm:
+        # Takes 3 arguments
+        return lambda a, b, c: None
+
+    last_b = [0]
+
+    def update_to(b=1, bsize=1, tsize=None):
+        if tsize not in (None, -1):
+            t.total = tsize
+        displayed = t.update((b - last_b[0]) * bsize)
+        last_b[0] = b
+        return displayed
+
+    return update_to
+
+
+__all__ = [tqdm, progress_hook, FakeTQDM]

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/67472?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: Iddc9faf61e861837cc1e2e3b3dbdbeebd6ccf529
Gerrit-Change-Number: 67472
Gerrit-PatchSet: 9
Gerrit-Owner: Jason Lowe-Power <power...@gmail.com>
Gerrit-Reviewer: Bobby Bruce <bbr...@ucdavis.edu>
Gerrit-Reviewer: Jason Lowe-Power <power...@gmail.com>
Gerrit-Reviewer: Melissa Jost <melissakj...@gmail.com>
Gerrit-Reviewer: Melissa Jost <mkj...@ucdavis.edu>
Gerrit-Reviewer: kokoro <noreply+kok...@google.com>
Gerrit-MessageType: merged
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org

Reply via email to