GithubHelp home page GithubHelp logo

nschloe / stressberry Goto Github PK

View Code? Open in Web Editor NEW
310.0 12.0 26.0 7.89 MB

Stress tests for the Raspberry Pi :sweat_smile:

License: GNU General Public License v3.0

Makefile 6.60% Python 93.40%
raspberry-pi stress-test temperature pypi python python3

stressberry's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

stressberry's Issues

Issues with stressberry-plot

Hi,

luckily I found your stresstest script, looks amazing! Well, first run is done after setting it up according to your guide.

But when it comes to creating the plot with "stressberry-plot out.dat -o out.png", I get:

pi@raspberry:~$ stressberry-plot out.dat -o out.png
Unable to init server: Could not connect: Connection refused
Unable to init server: Verbindung ist gescheitert:Connection refused

(stressberry-plot:12857): Gdk-CRITICAL **: gdk_cursor_new_for_display: assertion 'GDK_IS_DISPLAY (display)' failed
Traceback (most recent call last):
  File "/usr/local/bin/stressberry-plot", line 7, in <module>
    import matplotlib.pyplot as plt
  File "/usr/local/lib/python2.7/dist-packages/matplotlib/pyplot.py", line 115, in <module>
    _backend_mod, new_figure_manager, draw_if_interactive, _show = pylab_setup()
  File "/usr/local/lib/python2.7/dist-packages/matplotlib/backends/__init__.py", line 62, in pylab_setup
    [backend_name], 0)
  File "/usr/local/lib/python2.7/dist-packages/matplotlib/backends/backend_gtk3agg.py", line 9, in <module>
    from . import backend_agg, backend_gtk3
  File "/usr/local/lib/python2.7/dist-packages/matplotlib/backends/backend_gtk3.py", line 32, in <module>
    cursors.MOVE          : Gdk.Cursor.new(Gdk.CursorType.FLEUR),
TypeError: constructor returned NULL

Do you have any idea on where to start?

Plot delta-t broken in 0.2.3

Noticed that the latest version has broken the --delta-t option to plot ambient temperatures. Suspect this is caused when removing use of numpy in #66 which intended to lighten dependencies, even though numpy is used by matplot so is already an inherited dependency for the project.
I'll investigate and see if there is a fix which doesn't require numpy.

Traceback (most recent call last):
  File "/home/pi/.local/bin/stressberry-plot", line 10, in <module>
    sys.exit(plot())
  File "/home/pi/.local/lib/python3.7/site-packages/stressberry/cli/plot.py", line 26, in plot
    temperature_data = [t - data[k]["ambient"] for t in data[k]["temperature"]]
  File "/home/pi/.local/lib/python3.7/site-packages/stressberry/cli/plot.py", line 26, in <listcomp>
    temperature_data = [t - data[k]["ambient"] for t in data[k]["temperature"]]
TypeError: unsupported operand type(s) for -: 'float' and 'list'

need clarifications

Hi,
I'm trying to get stressberry run on a Pi4 with a fresh Raspbian OS install.
I'm sure we need more details in the readme file

sudo apt install stress => OK
pip install stressberry => OK, no error to report

pi@raspberrypi:~ $ stressberry-run out.dat
-bash: stressberry-run: command not found

added /home/pi/.local/bin to PATH

export PATH=$PATH:/home/pi/.local/bin
echo $PATH
/home/pi/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games:/home/pi/.local/bin

pi@raspberrypi:~ $ stressberry-run out.dat
Traceback (most recent call last):
File "/home/pi/.local/bin/stressberry-run", line 6, in
from stressberry.cli import run
File "/home/pi/.local/lib/python2.7/site-packages/stressberry/init.py", line 15, in
from . import cli
File "/home/pi/.local/lib/python2.7/site-packages/stressberry/cli.py", line 8, in
import matplotlib.pyplot as plt
File "/home/pi/.local/lib/python2.7/site-packages/matplotlib/init.py", line 133, in
from matplotlib.rcsetup import defaultParams, validate_backend, cycler
File "/home/pi/.local/lib/python2.7/site-packages/matplotlib/rcsetup.py", line 31, in
from matplotlib.fontconfig_pattern import parse_fontconfig_pattern
File "/home/pi/.local/lib/python2.7/site-packages/matplotlib/fontconfig_pattern.py", line 28, in
from backports.functools_lru_cache import lru_cache
ImportError: No module named functools_lru_cache

pi@raspberrypi:~/.local/bin $ MPLBACKEND=Agg stressberry-run out.dat
Traceback (most recent call last):
File "/home/pi/.local/bin/stressberry-run", line 6, in
from stressberry.cli import run
File "/home/pi/.local/lib/python2.7/site-packages/stressberry/init.py", line 15, in
from . import cli
File "/home/pi/.local/lib/python2.7/site-packages/stressberry/cli.py", line 8, in
import matplotlib.pyplot as plt
File "/home/pi/.local/lib/python2.7/site-packages/matplotlib/init.py", line 133, in
from matplotlib.rcsetup import defaultParams, validate_backend, cycler
File "/home/pi/.local/lib/python2.7/site-packages/matplotlib/rcsetup.py", line 31, in
from matplotlib.fontconfig_pattern import parse_fontconfig_pattern
File "/home/pi/.local/lib/python2.7/site-packages/matplotlib/fontconfig_pattern.py", line 28, in
from backports.functools_lru_cache import lru_cache
ImportError: No module named functools_lru_cache

tried to follow many posts from this github like install libatlas-base-dev

pip3 install stressberry

stressberry-run out.dat
Awaiting stable baseline temperature...
Current temperature: 51.1°C - Previous temperature: 52.1°C

Seems to work...

If pip3 is the one to use, should be added to readme instead of pip
not sure about path, dependencies to install as well...

That would be great to have clear steps to follow starting from a fresh official install.

AttributeError: 'NoneType' object has no attribute 'plot'

pi@raspberrypi:~ $ MPLBACKEND=Agg stressberry-plot out.dat 
Traceback (most recent call last):
  File "/home/pi/.local/bin/stressberry-plot", line 10, in <module>
    sys.exit(plot())
  File "/home/pi/.local/lib/python3.7/site-packages/stressberry/cli.py", line 152, in plot
    ax1.plot(
AttributeError: 'NoneType' object has no attribute 'plot'

I have limited knowledge of linux and I'm not sure how to fix this error, I already have a plot file with the out data which i got from the first command . Thanks for all your help this is a great little project.

Increase Max Speed

Hi, Is it possible to modify stressberry to increase maximum speed from 1500Mhz to 2147Mhz
I have overclocked my raspberry pi 4 and have good cooling, i would be interested to see what temps
i get when running at 2147Mhz.

MANOUII Raspberry PI passiv Case 1500 vs 2147 MHz

IMG_20200406_205110
Im using the Pi 4 4GB with no overvolting or overclocking in this case. I'm not using any active cooling, it is purely passively cooled. The case cools the power management chip, the USB controller and the SoC itself. It is delivered with a small bag of thermal paste, which I'm using for all 3 of those chips.

These are the results of the stock run:
out

Just for fun I also tried overclocking to 2147 MHz CPU and 750 MHz GPU using over_voltage=6
These are the results:
out

Here are the log files for both runs:
StressBerryResults.zip

venv / virtualenv notes

I followed the instructions... sorta ;-) I created a virtualenv and then followed instructions. This did not go well for me. I saw all the errors described in issue #42. I believe this is due to me using:

pip3 install stressberry --user

I also needed some packages to be installed and https://www.instructables.com/id/Stress-Testing-the-Raspberry-Pi/ was a good resource for me.

Once I removed the --user flag (in a new virtualenv) all was good. Not sure if this will help everyone but jotting down what I found.

Raspberry Pi 4 - Cooling Tests

After figuring out how to get the 0.3.1 stressberry version working on my Pi (hint: "pip3 install stressberry"), I've got my tests done and here they are.

The case is made of acrylic with openings that help the air flows through. The heatsinks are common but the main chip heatsink is flat.
image
image

And the tests...
image
image

FYI: I choose the Case+Heatsinks+Fan(Push-in) system for daily use.

Problem with plotting

Hi there,
I have used Stressberry for testing heatsinks on raspberry pi 4, but I have run in some trouble while trying to plot data. To be specific I had trouble removing data labels.
I don't know if this problem is standard or I have done something wrong but I fixed my problem by changing some code in plot.py file from code.
Please let me know if this problem is specific to me or is this some fault in code.
I can send a changed code if you want.

Test results: Minimalist aluminium heatsinks + 8cm fan (5v) as cover for OKdo plastic case

Test conditions

  • Raspberry Pi 4 8G was fitted with a set of 4 minimalistic aluminium heatskins (1).
  • Fan: recycled (from old desktop case) 8 cm model running at 5V using an external Multi Voltage Power Adapter (2).
  • Case: OKdo ABS plastic with top cover removed (3).
  • Room temperature while running the test was: 16º Celsius.
  • Raspberry Pi was overclocked at 2000MHZ with overvoltage of 3.

(1) https://mauser.pt/catalog/product_info.php?cPath=1667_2620_2621&products_id=012-0181
(2) Globe Fan Sleeve Bearing S 011388 12M DC12V 0.17A 80×80×30 mm
(3) https://www.okdo.com/p/okdo-raspberry-pi-4-case-black/

Test results
2000mhz_v3

Set-up
Set-up

Sidenote 1: Fan is pulling the air out.
Sidenote 2: Ugly green foam under case serves to dampen/reduce the noise/vibrations from the fan.
Sidenote 3: Flash enhanced dust courtesy of 6 months of use.

*.dat file
2000mhz_v3.dat.zip

Broken?!

I've installed both but I just get an error. So it's more then just install two things apperently.

This is what I got:

~ $ MPLBACKEND=Agg stressberry-plot out.dat -o out.png


Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/numpy/core/__init__.py", line 16,
 in <module>
    from . import multiarray
ImportError: libf77blas.so.3: cannot open shared object file: No such file or di
rectory

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/bin/stressberry-plot", line 7, in <module>
    from stressberry.cli import plot
  File "/usr/local/lib/python3.5/dist-packages/stressberry/__init__.py", line 15
, in <module>
    from . import cli
  File "/usr/local/lib/python3.5/dist-packages/stressberry/cli.py", line 8, in <
module>
    import matplotlib.pyplot as plt
  File "/usr/local/lib/python3.5/dist-packages/matplotlib/__init__.py", line 126
, in <module>
    from . import cbook
  File "/usr/local/lib/python3.5/dist-packages/matplotlib/cbook/__init__.py", li
ne 34, in <module>
    import numpy as np
  File "/usr/local/lib/python3.5/dist-packages/numpy/__init__.py", line 142, in
<module>
    from . import add_newdocs
  File "/usr/local/lib/python3.5/dist-packages/numpy/add_newdocs.py", line 13, i
n <module>
    from numpy.lib import add_newdoc
  File "/usr/local/lib/python3.5/dist-packages/numpy/lib/__init__.py", line 8, i
n <module>
    from .type_check import *
  File "/usr/local/lib/python3.5/dist-packages/numpy/lib/type_check.py", line 11
, in <module>
    import numpy.core.numeric as _nx
  File "/usr/local/lib/python3.5/dist-packages/numpy/core/__init__.py", line 26,
 in <module>
    raise ImportError(msg)
ImportError:
Importing the multiarray numpy extension module failed.  Most
likely you are trying to import a failed build of numpy.
If you're working with a numpy git repo, try `git clean -xdf` (removes all
files not under version control).  Otherwise reinstall numpy.

Original error was: libf77blas.so.3: cannot open shared object file: No such fil
e or directory

ERROR: stressberry-plot: error: unrecognized arguments: --hide-legend --line-width 2

Getting this Error stressberry-plot: error: unrecognized arguments: --hide-legend --line-width 2

When running command
MPLBACKEND=Agg /home/pi/.local/bin/stressberry-plot mytest.out -f -d 300 -f -l 400 1600 -t 30 90 -o mytest.png --hide-legend --not-transparent --line-width 2

Works when remove —hide-legend and —line-width command but the graph is not clear

output .png file and got error

Hi, I trying to output the png file, and show error message like below, what should I do?
Thanks!

pi@raspberrypi:~/Desktop $ MPLBACKEND=Agg stressberry-plot out.dat -o out.png
Traceback (most recent call last):
File "/home/pi/.local/bin/stressberry-plot", line 8, in
sys.exit(plot())
File "/home/pi/.local/lib/python3.7/site-packages/stressberry/cli.py", line 152, in plot
ax1.plot(
AttributeError: 'NoneType' object has no attribute 'plot'

Unable to install

pi@RetroPie:~ $ sudo -H pip3 install stressberry
Collecting stressberry
Exception:
Traceback (most recent call last):
  File "/usr/share/python-wheels/urllib3-1.19.1-py2.py3-none-any.whl/urllib3/connection.py", line 138, in _new_conn
    (self.host, self.port), self.timeout, **extra_kw)
  File "/usr/share/python-wheels/urllib3-1.19.1-py2.py3-none-any.whl/urllib3/util/connection.py", line 75, in create_connection
    for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):
  File "/usr/lib/python3.5/socket.py", line 733, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno -3] Temporary failure in name resolution

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/share/python-wheels/urllib3-1.19.1-py2.py3-none-any.whl/urllib3/connectionpool.py", line 594, in urlopen
    chunked=chunked)
  File "/usr/share/python-wheels/urllib3-1.19.1-py2.py3-none-any.whl/urllib3/connectionpool.py", line 350, in _make_request
    self._validate_conn(conn)
  File "/usr/share/python-wheels/urllib3-1.19.1-py2.py3-none-any.whl/urllib3/connectionpool.py", line 837, in _validate_conn
    conn.connect()
  File "/usr/share/python-wheels/urllib3-1.19.1-py2.py3-none-any.whl/urllib3/connection.py", line 281, in connect
    conn = self._new_conn()
  File "/usr/share/python-wheels/urllib3-1.19.1-py2.py3-none-any.whl/urllib3/connection.py", line 147, in _new_conn
    self, "Failed to establish a new connection: %s" % e)
requests.packages.urllib3.exceptions.NewConnectionError: <requests.packages.urllib3.connection.VerifiedHTTPSConnection object at 0x75d6cd10>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/pip/basecommand.py", line 215, in main
    status = self.run(options, args)
  File "/usr/lib/python3/dist-packages/pip/commands/install.py", line 353, in run
    wb.build(autobuilding=True)
  File "/usr/lib/python3/dist-packages/pip/wheel.py", line 749, in build
    self.requirement_set.prepare_files(self.finder)
  File "/usr/lib/python3/dist-packages/pip/req/req_set.py", line 380, in prepare_files
    ignore_dependencies=self.ignore_dependencies))
  File "/usr/lib/python3/dist-packages/pip/req/req_set.py", line 554, in _prepare_file
    require_hashes
  File "/usr/lib/python3/dist-packages/pip/req/req_install.py", line 278, in populate_link
    self.link = finder.find_requirement(self, upgrade)
  File "/usr/lib/python3/dist-packages/pip/index.py", line 465, in find_requirement
    all_candidates = self.find_all_candidates(req.name)
  File "/usr/lib/python3/dist-packages/pip/index.py", line 423, in find_all_candidates
    for page in self._get_pages(url_locations, project_name):
  File "/usr/lib/python3/dist-packages/pip/index.py", line 568, in _get_pages
    page = self._get_page(location)
  File "/usr/lib/python3/dist-packages/pip/index.py", line 683, in _get_page
    return HTMLPage.get_page(link, session=self.session)
  File "/usr/lib/python3/dist-packages/pip/index.py", line 792, in get_page
    "Cache-Control": "max-age=600",
  File "/usr/share/python-wheels/requests-2.12.4-py2.py3-none-any.whl/requests/sessions.py", line 501, in get
    return self.request('GET', url, **kwargs)
  File "/usr/lib/python3/dist-packages/pip/download.py", line 386, in request
    return super(PipSession, self).request(method, url, *args, **kwargs)
  File "/usr/share/python-wheels/requests-2.12.4-py2.py3-none-any.whl/requests/sessions.py", line 488, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/share/python-wheels/requests-2.12.4-py2.py3-none-any.whl/requests/sessions.py", line 609, in send
    r = adapter.send(request, **kwargs)
  File "/usr/share/python-wheels/CacheControl-0.11.7-py2.py3-none-any.whl/cachecontrol/adapter.py", line 47, in send
    resp = super(CacheControlAdapter, self).send(request, **kw)
  File "/usr/share/python-wheels/requests-2.12.4-py2.py3-none-any.whl/requests/adapters.py", line 423, in send
    timeout=timeout
  File "/usr/share/python-wheels/urllib3-1.19.1-py2.py3-none-any.whl/urllib3/connectionpool.py", line 643, in urlopen
    _stacktrace=sys.exc_info()[2])
  File "/usr/share/python-wheels/urllib3-1.19.1-py2.py3-none-any.whl/urllib3/util/retry.py", line 315, in increment
    total -= 1
TypeError: unsupported operand type(s) for -=: 'Retry' and 'int'

I've installed various python dependencies and everything I could find from topics on this and I still can't get stressberry to install, what amI missing?

Path to stressberry-run

The install and run instructions are

[sudo] apt install stress
pip install stressberry (Use pip3 install to be safe)
stressberry-run out.dat
-bash: stressberry-run: command not found

but stressberry-run is not in the current PATH. It looks like stressberry-run is in ~/.local/bin

$ sudo find / -name stressberry-run -print
/home/pi/.local/bin/stressberry-run

Unable to start Pi 4 4gb

I installed stressberry as said but i cant run it

Linux k4s-2 4.19.57-v7l+ #1244 SMP Thu Jul 4 18:48:07 BST 2019 armv7l GNU/Linux

PRETTY_NAME="Raspbian GNU/Linux 10 (buster)"
NAME="Raspbian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
[sudo] apt install stress
pip3 install stressberry --user
pi@k4s-2:~ $ sudo stressberry-run out.dat
sudo: stressberry-run: command not found

Argon NEO Pi 4 Raspberry Pi Case

This is an aluminium case that has a removable top.

Tests were made with a Raspberry Pi 4 Model B Rev 1.4 with 8GB RAM.

The tests were taken using Ubuntu Mate 20.10, installed via PINN with this Kernel:
Linux rpi4 5.8.0-1006-raspi #9-Ubuntu SMP PREEMPT Fri Oct 16 12:55:30 UTC 2020 aarch64 arch64 aarch64 GNU/Linux

With the core working at 1.5 GHz.

For the tests, Linux was initialized it in console mode, in order to prevent any interferences from GUI apps. Network was also disabled.

Before doing the temperature tests, stressberry was run once, just in order to heat the cabinet to its usual temperature.

Then, two tests were done:

1. With the top closed

image

2. With the top opened

image

Test results:

image

neo-tests.zip

No such file or directory: 'out.dat' + other messages

When I installed as per the guidance (on a Pi4 with Buster full version), this message came up in yellow:

The scripts stressberry-plot and stressberry-run are installed in '/home/pi/.local/bin' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.

I don't really know what that wants me to do, so I continued. Now when I try the command, I get:
-bash: stressberry-plot: command not found

I find that stressberry is installed to:
/home/pi/.local/bin

So I tried running it from there and still no joy. I tried installing with a different command (sudo -H pip3 install stressberry) and got a bit further, but still not running:
stressberry-plot: error: argument infiles: can't open 'out.dat': [Errno 2] No such file or directory: 'out.dat'

I then try creating an empty out.dat file and tried again. Now I get:

pi@raspberrypi:~ $ sudo MPLBACKEND=Agg stressberry-plot out.dat
Traceback (most recent call last):
  File "/usr/local/bin/stressberry-plot", line 10, in <module>
    sys.exit(plot())
  File "/usr/local/lib/python3.7/dist-packages/stressberry/cli.py", line 146, in plot
    terminal_temps = [d["temperature"][-1] for d in data]
  File "/usr/local/lib/python3.7/dist-packages/stressberry/cli.py", line 146, in <listcomp>
    terminal_temps = [d["temperature"][-1] for d in data]
TypeError: 'NoneType' object is not subscriptable

I've gone as far as my limited Linux abilities will allow me to get, so I'm here asking for help. The instructions seem very clear and straight forward, but it just won't seem to work for me.

I was initially using Raspbian Lite but changed to the full version in case some kind of dependency is missing - but still no joy. FYI I'm using SSH from my PC to do this.

CooliPi 4B in passive mode

P1470094
P1470054
CooliPi-passive.zip
out-passive

Hi,

the length of the test (5 minutes ?) is way too short. It takes half an hour for the temperature to settle. See https://www.coolipi.com/Performance.html
I also miss ambient temperature, because you can't make a fair comparison if you don't know it.

Mine was 25.5-26 degC. Raspberry Pi 4 model B. Overclocked to 1850MHz, over_voltage=2
GPU wasn't intentionally overclocked. Monitor - 1920x1200 via HDMI.

The best stress test isn't stress or stress-ng, but linpack. At least for Raspberry Pi 4.

I've also noticed different cooling performance with a monitor connected and then without a monitor. 4K monitor would make the device heat up even more.

So I suggest you also require these metadata.

CooliPi 4B is primarily a passive heatsink with a case, this setup is mainly for industrial users and for overclockers.

Best Regards.

Lada ([email protected])

Reporting results on an overclocked Raspberry Pi 4B with Argon One case

Got a RPi4 a few weeks ago and have been tweaking and setting it up ever since. I had my eye on the Argon One case for it, and it just arrived today.

The case has an aluminum top plate that directly connects to the chips on the board, similar to the well-known Flirc case. It also has an active fan in it.

This board will be used as a retro gaming setup with RetroArch, and I wanted to overclock it to eke out the maximum performance in early 3D platforms like PlayStation, N64, and Dreamcast. The Pi CPU is overclocked to 1950 MHz. (The GPU and 3D blocks are overclocked as well, but I don't think it matters for this test.)

Anyway, I'm very pleased with the results. Even with an aggressive overclock, it keeps things very cool!

out2

Results file, as TXT since GitHub won't allow me to upload it directly as DAT: out2.txt

Rpi 4 4gb, Active cooled and Passive Results

My Setup
Dual fan heatsink with MX-4 for the CPU an additional smaller copper heatink on the ram and thermal pads to make up the hight to the main heatsink. PoE pins removed for space and a thin thermal pad on the Wifi chip to help hold down the large heatsink....any maybe cool the wifi chip

20190703_183421

RPI_4_Heat sink with fan off and ON .zip

mix

Fan Off peaks at 62°C and Fans ON peaked at 42°C
Very quite fans not scilent , but measured at 33db from 6" away.

Error after 150s idle phase

Shell output after 150s idle phase (RPi 3b, no overclock, clean Buster without any tweaks etc.)
:
Exception in thread Thread-1: Traceback (most recent call last): File "/usr/lib/python3.7/threading.py", line 917, in _bootstrap_inner self.run() File "/usr/lib/python3.7/threading.py", line 865, in run self._target(*self._args, **self._kwargs) File "/home/pi/.local/lib/python3.7/site-packages/stressberry/cli/run.py", line 96, in <lambda> target=lambda: test(args.duration, args.idle, args.cores), args=() File "/home/pi/.local/lib/python3.7/site-packages/stressberry/main.py", line 99, in test stress_cpu(num_cpus=cores, time=stress_duration) File "/home/pi/.local/lib/python3.7/site-packages/stressberry/main.py", line 7, in stress_cpu subprocess.check_call(["stress", "--cpu", str(num_cpus), "--timeout", f"{time}s"]) File "/usr/lib/python3.7/subprocess.py", line 342, in check_call retcode = call(*popenargs, **kwargs) File "/usr/lib/python3.7/subprocess.py", line 323, in call with Popen(*popenargs, **kwargs) as p: File "/usr/lib/python3.7/subprocess.py", line 775, in __init__ restore_signals, start_new_session) File "/usr/lib/python3.7/subprocess.py", line 1522, in _execute_child raise child_exception_type(errno_num, err_msg, err_filename) FileNotFoundError: [Errno 2] No such file or directory: 'stress': 'stress'

Data for upload

Hi Martin, would you add my data, please?

Ambient temperature (Measured with DHT22) = 24.70°C

I made a combination of aluminum heatsink, with a 5.8v - 30x30mm fan attached to the heatsink, and it works GREAT!

Twitter: @baijorge

Data.zip

Results for a Raspberry Pi 4B with FLIRC Case

I thought I'd return to benchmarking and show some results regarding the FLIRC case.

These results are for a Raspberry Pi 4B with 4GB RAM, using the FLIRC case. The setup is pictured below:

DSC_8378

This results in the following temperature graph, which has a peak temperature of 51.0 °C and idle temperature of 37.0 °C:

out
The raw results for the graph can be found in the following out.txt file.

GObject introspection?

Tried to generate plot file, to see the curve and compare data.

stressberry-plot $(date +%F)_out.dat -o $(date +%F)_stress.png
Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/matplotlib/backends/backend_gtk3.py", line 14, in <module>
    gi.require_version("Gtk", "3.0")
  File "/usr/lib/python3/dist-packages/gi/__init__.py", line 118, in require_version
    raise ValueError('Namespace %s not available' % namespace)
ValueError: Namespace Gtk not available

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/bin/stressberry-plot", line 7, in <module>
    import matplotlib.pyplot as plt
  File "/usr/local/lib/python3.5/dist-packages/matplotlib/pyplot.py", line 116, in <module>
    _backend_mod, new_figure_manager, draw_if_interactive, _show = pylab_setup()
  File "/usr/local/lib/python3.5/dist-packages/matplotlib/backends/__init__.py", line 60, in pylab_setup
    [backend_name], 0)
  File "/usr/local/lib/python3.5/dist-packages/matplotlib/backends/backend_gtk3agg.py", line 9, in <module>
    from . import backend_agg, backend_gtk3
  File "/usr/local/lib/python3.5/dist-packages/matplotlib/backends/backend_gtk3.py", line 20, in <module>
    "Gtk3 backend requires the GObject introspection bindings for Gtk 3 "
ImportError: Gtk3 backend requires the GObject introspection bindings for Gtk 3 to be installed.

I am running my raspberry pi in minimal mode, so no GUI or others. What packages do I need to install?

Raspberry Pi 4B@1800MHz / Joy-It alu case with PiFan@3V3

I submit you my own data for displaying this on your project page. It's about a Raspberry Pi 4B 4GB with actual firmware/eeprom in a "Joy-It" aluminium case. On the top side are small holes for airflow, but without a fan the temperature raises up to over 80°C in stressberry test!
I add a small (30x30 mm) fan 5V (also usable with 3.3V) under the top cover for blowing cool air into the case and over the Raspberry Pi board (and ARM cpu). I use the 3V3 and ground pins from the Pi for a low noise operating, because the small fan is too loud at 5V!
With default clocking (arm/gpu@1500/500MHz) the temperatures raises only up to ~53°C with stressberry-test. At arm/gpu@1800/600MHz with a little but noticeable performance boost the temperatures raises up to ~60°C. Not bad at all for a low cost solution :)

Some other data:

  • original Raspberry Pi power supply 5.1V/3A
  • Raspbian Buster with 64bit kernel installed
  • Joy-It aluminium case for round about 12 €
  • "PiFan" 30x30 mm fan 5V (also for 3.3V) for round about 3 €

begin --- config.txt ---
#uncomment to overclock the arm. 1500 MHz is the default.
arm_freq=1800
gpu_freq=600
over_voltage=2

end --- config.txt ---

outdat.zip

20200109_184228
20200109_184429
out

cu ...
Dirk

README needs a change

When I used pip to install stressberry I got an issue returned that stressberry needs python3.
So I tried to install stressberry with pip3 instead and it got installed without the issue.

FileNotFoundError: [Errno 2] No such file or directory: 'stress'

Installed stressberry using pip3 install -U stressberry and tried to run it for the first time. Got that error.

Full error message:

Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python3.5/threading.py", line 914, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.5/threading.py", line 862, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/local/lib/python3.5/dist-packages/stressberry/main.py", line 54, in test_short
    stress_cpu(4, time=300)
  File "/usr/local/lib/python3.5/dist-packages/stressberry/main.py", line 12, in stress_cpu
    '--timeout', '{}s'.format(time)
  File "/usr/lib/python3.5/subprocess.py", line 266, in check_call
    retcode = call(*popenargs, **kwargs)
  File "/usr/lib/python3.5/subprocess.py", line 247, in call
    with Popen(*popenargs, **kwargs) as p:
  File "/usr/lib/python3.5/subprocess.py", line 676, in __init__
    restore_signals, start_new_session)
  File "/usr/lib/python3.5/subprocess.py", line 1282, in _execute_child
    raise child_exception_type(errno_num, err_msg)
FileNotFoundError: [Errno 2] No such file or directory: 'stress'

Ice Tower Low Profile Cooler - Test Results

Hey there,
I did a bunch of tests using the Ice Tower Low Profile version Cooler.
IceTowerResults.zip

Ice Tower
Ice Tower with Noctua

I did tests without the Fan, with the Fan and also swapped the included Fan for a Noctua Fan. I also tested the Overclocking capabilities of this cooler.

For the Overclocks I used these settings:

Frequency overvolt level
1500 0
1750 2
2000 4
2147 6

Firmware:

BOOTLOADER: up-to-date
CURRENT: Tue 10 Sep 10:41:50 UTC 2019 (1568112110)
 LATEST: Tue 10 Sep 10:41:50 UTC 2019 (1568112110)
VL805: up-to-date
CURRENT: 000137ab
 LATEST: 000137ab

all

First of looking at the passive capabilities, you can see that Even a hefty overclock to 2147MHz is doable, though I am not quite sure if it has stabilised in 5 minutes.
no_fan

Then comparing the 2 used fans one can see that the Noctua is about 1-2 °C cooler but I think it also spins faster.
fan_15
fan_175

Then here is a graph with all the results with the Noctua fan:
noctua

And lastly I swapped the included thermal pad for some thermal grease which especially gave a big boost in performance for the 2.147GHz overclock.
paste1500
paste2147

I am not sure how much of this you would want to include in README?

Hex Wrench case w/ Copper Shim

Thanks for the test tools!

I noticed that the hex wrench case wasn't making good contact with the thermal material provided. I added a 1mm copper shim and used Arctic Sliver 5 thermal paste with this case. It made a huge difference, about 20*C vs the tests on #45 .

Here are my results with the Hex Wrench case:

out.dat.txt
out

20200206_183034 - Copy

Change default stress time to 10 mins?

I realize the existing data is for 5 mins but from reading a bunch of articles on Raspberry Pi testing it looks like 10 mins is considered a good minimum (I've seen some use 20).

The results are definitely different and more telling when I run my tests with -d 600

Runtime Error, failed to import.

`RuntimeError: module compiled against API version 0xb but this version of numpy is 0xa

Traceback (most recent call last):

  File "/usr/local/bin/stressberry-plot", line 7, in <module>

    import matplotlib.pyplot as plt

  File "/usr/local/lib/python3.5/dist-packages/matplotlib/pyplot.py", line 29, in <module>

    import matplotlib.colorbar

  File "/usr/local/lib/python3.5/dist-packages/matplotlib/colorbar.py", line 32, in <module>

    import matplotlib.artist as martist

  File "/usr/local/lib/python3.5/dist-packages/matplotlib/artist.py", line 16, in <module>

    from .path import Path

  File "/usr/local/lib/python3.5/dist-packages/matplotlib/path.py", line 25, in <module>

    from . import _path, rcParams

ImportError: numpy.core.multiarray failed to import
`

Error occured when running "stressberry-plot out.dat"

ImportError: libf77blas.so.3: cannot open shared object file: No such file or directory

Hi,
Thanks for the tool.
I followed the instructions for running a stress test, but when I issue the command
MPLBACKEND=Agg stressberry-plot out.dat -o out.png
or
stressberry-plot out.dat -o out.png

I get this error :

Traceback (most recent call last):
  File "/home/pi/.local/lib/python3.7/site-packages/numpy/core/__init__.py", line 22, in <module>
    from . import multiarray
  File "/home/pi/.local/lib/python3.7/site-packages/numpy/core/multiarray.py", line 12, in <module>
    from . import overrides
  File "/home/pi/.local/lib/python3.7/site-packages/numpy/core/overrides.py", line 7, in <module>
    from numpy.core._multiarray_umath import (
ImportError: libf77blas.so.3: cannot open shared object file: No such file or directory

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/pi/.local/bin/stressberry-plot", line 10, in <module>
    sys.exit(plot())
  File "/home/pi/.local/lib/python3.7/site-packages/stressberry/cli/plot.py", line 9, in plot
    import dufte
  File "/home/pi/.local/lib/python3.7/site-packages/dufte/__init__.py", line 2, in <module>
    from .main import legend, style
  File "/home/pi/.local/lib/python3.7/site-packages/dufte/main.py", line 3, in <module>
    import matplotlib as mpl
  File "/home/pi/.local/lib/python3.7/site-packages/matplotlib/__init__.py", line 107, in <module>
    from . import cbook, rcsetup
  File "/home/pi/.local/lib/python3.7/site-packages/matplotlib/cbook/__init__.py", line 28, in <module>
    import numpy as np
  File "/home/pi/.local/lib/python3.7/site-packages/numpy/__init__.py", line 140, in <module>
    from . import core
  File "/home/pi/.local/lib/python3.7/site-packages/numpy/core/__init__.py", line 48, in <module>
    raise ImportError(msg)
ImportError: 

IMPORTANT: PLEASE READ THIS FOR ADVICE ON HOW TO SOLVE THIS ISSUE!

Importing the numpy C-extensions failed. This error can happen for
many reasons, often due to issues with your setup or how NumPy was
installed.

We have compiled some common reasons and troubleshooting tips at:

    https://numpy.org/devdocs/user/troubleshooting-importerror.html

Please note and check the following:

  * The Python version is: Python3.7 from "/usr/bin/python3"
  * The NumPy version is: "1.19.1"

and make sure that they are the versions you expect.
Please carefully study the documentation linked above for further help.

Original error was: libf77blas.so.3: cannot open shared object file: No such file or directory

I'm using a Raspberry Pi 4 2Gb running Retropie 4.6.6 (Raspbian GNU/Linux 10 (buster))

Raspberry Pi 4B [1.5GHz vs 2.15GHz]

I'm using RPi 4B (with 4GB memory) embedded in the Smraza case with active cooling (fan on HIGH 5V pin).

I made stress tests for the base 1.5GHz and overclocked to 2.15GHz with over_voltage=6 and arm_freq=2147. I was initially a bit pessimistic about the case, but it looks like it did a pretty decent job in keeping the cpu below ~60-65°C.

data

PS. I had to use the --cooldown 10 for the overclocked case, as otherwise it wasn't getting within the default 0.2 °C range within 60 seconds (and also-i 60 because I was rushing :)). Just in case I'm attaching the .dat files for both cases data.zip.

PPS. Thanks for the tool!

AttributeError: 'NoneType' object has no attribute 'plot'

I'm having trouble plotting data while running on the raspberry pi 4 itself, command line. (Raspbian 10 buster).

 ./stressberry-plot out.dat -o out.png
Unable to init server: Could not connect: Connection refused
Unable to init server: Could not connect: Connection refused

(stressberry-plot:9112): Gdk-CRITICAL **: 10:13:18.390: gdk_cursor_new_for_display: assertion 'GDK_IS_DISPLAY (display)' failed

(stressberry-plot:9112): Gdk-CRITICAL **: 10:13:18.393: gdk_cursor_new_for_display: assertion 'GDK_IS_DISPLAY (display)' failed
Traceback (most recent call last):
  File "./stressberry-plot", line 10, in <module>
    sys.exit(plot())
  File "/home/pi/.local/lib/python3.7/site-packages/stressberry/cli.py", line 152, in plot
    ax1.plot(
AttributeError: 'NoneType' object has no attribute 'plot'

Any idea what might be wrong here?

Results for a Raspberry Pi 3B+ with FLIRC Case

I thought I'd share some results, seen as I came across this project while finding a way to test the cooling of my Pi's new case.

These results are for a Raspberry Pi 3B+, using a FLIRC case, with a SanDisk Ultra Fit 128 GB USB 3.1 pen drive attached. The Pi had been left idle for a long time before the test, so the idle temperature is reasonable. The setup is pictured below:

dsc_3826

This results in the following temperature graph, which has a peak temperature of 60.148 °C and idle temperature of 44.008 °C:

out

The previous case a simple acrylic case anecdotally had a resting temperature of around 52 °C, but I didn't test this before attaching the new case. The raw results for the graph can be found in the following out.txt file.

CooliPi 4B with fan on

P1470212s
out-fan_on

CooliPi-fan_on.zip

Hi,

the length of the test (5 minutes ?) is way too short. It takes half an hour for the temperature to settle. See https://www.coolipi.com/Performance.html
I also miss ambient temperature, because you can't make a fair comparison if you don't know it.

Mine was 25.5-26 degC. Raspberry Pi 4 model B. Overclocked to 1850MHz, over_voltage=2
GPU wasn't intentionally overclocked. Monitor - 1920x1200 via HDMI.

The best stress test isn't stress or stress-ng, but linpack. At least for Raspberry Pi 4.

I've also noticed different cooling performance with a monitor connected and then without a monitor. 4K monitor would make the device heat up even more.

So I suggest you also require these metadata.

CooliPi 4B is primarily a passive heatsink with a case, this setup is mainly for industrial users and for overclockers.

Best Regards.

Lada ([email protected])

ImportError: libf77blas.so.3: cannot open shared object file: No such file or directory

Hi there!

I tried installing and running as you suggested, on RPi 3B+ on the latest distro.
I got the following error:

Traceback (most recent call last):
  File "/home/pi/.local/lib/python3.5/site-packages/numpy/core/__init__.py", line 17, in <module>
    from . import multiarray
  File "/home/pi/.local/lib/python3.5/site-packages/numpy/core/multiarray.py", line 14, in <module>
    from . import overrides
  File "/home/pi/.local/lib/python3.5/site-packages/numpy/core/overrides.py", line 7, in <module>
    from numpy.core._multiarray_umath import (
ImportError: libf77blas.so.3: cannot open shared object file: No such file or directory

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "./stressberry-run", line 7, in <module>
    from stressberry.cli import run
  File "/home/pi/.local/lib/python3.5/site-packages/stressberry/__init__.py", line 1, in <module>
    from . import cli
  File "/home/pi/.local/lib/python3.5/site-packages/stressberry/cli.py", line 7, in <module>
    import matplotlib.pyplot as plt
  File "/home/pi/.local/lib/python3.5/site-packages/matplotlib/__init__.py", line 141, in <module>
    from . import cbook, rcsetup
  File "/home/pi/.local/lib/python3.5/site-packages/matplotlib/cbook/__init__.py", line 33, in <module>
    import numpy as np
  File "/home/pi/.local/lib/python3.5/site-packages/numpy/__init__.py", line 142, in <module>
    from . import core
  File "/home/pi/.local/lib/python3.5/site-packages/numpy/core/__init__.py", line 47, in <module>
    raise ImportError(msg)
ImportError: 

IMPORTANT: PLEASE READ THIS FOR ADVICE ON HOW TO SOLVE THIS ISSUE!

Importing the numpy c-extensions failed.
- Try uninstalling and reinstalling numpy.
- If you have already done that, then:
  1. Check that you expected to use Python3.5 from "/usr/bin/python3",
     and that you have no directories in your PATH or PYTHONPATH that can
     interfere with the Python and numpy version "1.17.0" you're trying to use.
  2. If (1) looks fine, you can open a new issue at
     https://github.com/numpy/numpy/issues.  Please include details on:
     - how you installed Python
     - how you installed numpy
     - your operating system
     - whether or not you have multiple versions of Python installed
     - if you built from source, your compiler versions and ideally a build log

- If you're working with a numpy git repository, try `git clean -xdf`
  (removes all files not under version control) and rebuild numpy.

Note: this error has many possible causes, so please don't comment on
an existing issue about this - open a new one instead.

Original error was: libf77blas.so.3: cannot open shared object file: No such file or directory

On searching further, I found this thread - Kitt-AI/snowboy#262

where the solution was to install

sudo apt-get install libatlas-base-dev

I did that and was able to run stressberry-run successfully,.

I don't know if you need to update your instructions, or if it is a peculiarity with my setup.

Thanks,
Sridhar

ImportError: No module named functools_lru_cache

So this is happening, first install and attempted run. Halp pls. KTHXBYE.

pi@raspberrypi:~ $ stressberry-run out.dat
Traceback (most recent call last):
File "/usr/local/bin/stressberry-run", line 6, in
from stressberry.cli import run
File "/usr/local/lib/python2.7/dist-packages/stressberry/init.py", line 15, in
from . import cli
File "/usr/local/lib/python2.7/dist-packages/stressberry/cli.py", line 8, in
import matplotlib.pyplot as plt
File "/usr/local/lib/python2.7/dist-packages/matplotlib/init.py", line 133, in
from matplotlib.rcsetup import defaultParams, validate_backend, cycler
File "/usr/local/lib/python2.7/dist-packages/matplotlib/rcsetup.py", line 31, in
from matplotlib.fontconfig_pattern import parse_fontconfig_pattern
File "/usr/local/lib/python2.7/dist-packages/matplotlib/fontconfig_pattern.py", line 28, in
from backports.functools_lru_cache import lru_cache
ImportError: No module named functools_lru_cache

Running this on a Raspberry Pi 4 Model B 8 GB

Screenshot from 2021-01-31 00-20-35

download

Vcgencmd Call

When running

stressberry-run out.dat

The error comes up

Awaiting stable baseline temperature...
Traceback (most recent call last):
  File "/usr/bin/stressberry-run", line 8, in <module>
    sys.exit(run())
  File "/usr/lib/python3.8/site-packages/stressberry/cli/run.py", line 92, in run
    cooldown(interval=args.cooldown, filename=args.temperature_file)
  File "/usr/lib/python3.8/site-packages/stressberry/main.py", line 14, in cooldown
    prev_tmp = measure_temp(filename=filename)
  File "/usr/lib/python3.8/site-packages/stressberry/main.py", line 37, in measure_temp
    out = subprocess.check_output(["vcgencmd", "measure_temp"]).decode("utf-8")
  File "/usr/lib/python3.8/subprocess.py", line 411, in check_output
    return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
  File "/usr/lib/python3.8/subprocess.py", line 489, in run
    with Popen(*popenargs, **kwargs) as process:
  File "/usr/lib/python3.8/subprocess.py", line 854, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/usr/lib/python3.8/subprocess.py", line 1702, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'vcgencmd'

As we can see in here the problem is that it just calls vcgencmd

File "/usr/lib/python3.8/site-packages/stressberry/main.py", line 37, in measure_temp
    out = subprocess.check_output(["vcgencmd", "measure_temp"]).decode("utf-8")

So it would be better to change it to a full path

out = subprocess.check_output(["/opt/vc/bin/vcgencmd", "measure_temp"]).decode("utf-8")

After doing grep -rn vcgencmd /usr/lib/python3.8/site-packages/stressberry/* to see where else it needs to change

/usr/lib/python3.8/site-packages/stressberry/main.py:51: out = subprocess.check_output(["vcgencmd", "measure_clock arm"]).decode("utf-8")

And do the same, change vcgencmd to the full path.

This apparently works. Will report back if I find any other issues.

Done on a Raspberry Pi 4 with Archlinux ARM.

Stress test with a Hex Wrench case

Hell, Thanks for the test suite

Here are my results with the Hex Wrench case:
image

It is used on a JETBOT car running with a RPI4 and Google Coral stick for TensorFlow object avoidance Machine Learning. Take note that I used the test to make sure that my GPIO fed 5 Volts supply was OK == So far, so good.

image

Here is the file (had to rename to txt):

out.txt

Data PoE hat

Some data using the PoE hat.
using heatsink and automated fan.
Both in cluster and free standing.
ClusterPOE2
POE2

PoE.zip
IMG_6304
IMG_6305

Unable to run on Rpi 4 4GB

pi@rasp4:~ $ MPLBACKEND=Agg stressberry-plot out.dat -o out.png
Traceback (most recent call last):
  File "/home/pi/.local/bin/stressberry-plot", line 6, in <module>
    from stressberry.cli import plot
  File "/home/pi/.local/lib/python2.7/site-packages/stressberry/__init__.py", line 15, in <module>
    from . import cli
  File "/home/pi/.local/lib/python2.7/site-packages/stressberry/cli.py", line 8, in <module>
    import matplotlib.pyplot as plt
  File "/home/pi/.local/lib/python2.7/site-packages/matplotlib/__init__.py", line 130, in <module>
    from matplotlib.rcsetup import defaultParams, validate_backend, cycler
  File "/home/pi/.local/lib/python2.7/site-packages/matplotlib/rcsetup.py", line 29, in <module>
    from matplotlib.fontconfig_pattern import parse_fontconfig_pattern
  File "/home/pi/.local/lib/python2.7/site-packages/matplotlib/fontconfig_pattern.py", line 28, in <module>
    from backports.functools_lru_cache import lru_cache
ImportError: No module named functools_lru_cache

stressberry-run take a long time to start

stressberry-run imports matplotlib and numpy - even though they are not used.

On some distributions, those libraries may not be available. Can these be made optional or only for stressberry-plot?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.