├── .coveragerc ├── .gitignore ├── .travis.yml ├── COPYING.rst ├── MANIFEST.in ├── Makefile ├── README.rst ├── branding └── logos │ ├── DistArray-LOGO.svg │ └── pngs │ ├── DistArray-LOGO-large.png │ ├── DistArray-LOGO-mid.png │ ├── DistArray-LOGO-small.png │ └── DistArray-LOGO-smallest.png ├── distarray ├── __init__.py ├── __version__.py ├── apps │ ├── __init__.py │ ├── dacluster.py │ └── engine.py ├── error.py ├── externals │ ├── __init__.py │ ├── protocol_validator.py │ └── six.py ├── globalapi │ ├── __init__.py │ ├── context.py │ ├── distarray.py │ ├── functions.py │ ├── ipython_cleanup.py │ ├── ipython_utils.py │ ├── maps.py │ ├── random.py │ └── tests │ │ ├── __init__.py │ │ ├── launch_mpi.py │ │ ├── test_context.py │ │ ├── test_distarray.py │ │ ├── test_distributed_io.py │ │ ├── test_functions.py │ │ ├── test_maps.py │ │ └── test_random.py ├── localapi │ ├── __init__.py │ ├── construct.py │ ├── error.py │ ├── format.py │ ├── localarray.py │ ├── maps.py │ ├── mpiutils.py │ ├── proxyize.py │ ├── random.py │ └── tests │ │ ├── __init__.py │ │ ├── paralleltest_distributed_array_protocol.py │ │ ├── paralleltest_functions.py │ │ ├── paralleltest_io.py │ │ ├── paralleltest_localarray.py │ │ ├── paralleltest_maps.py │ │ ├── paralleltest_mpiutils.py │ │ ├── paralleltest_random.py │ │ ├── paralleltest_umath.py │ │ ├── test_format.py │ │ ├── test_maps.py │ │ └── test_mpiutils.py ├── metadata_utils.py ├── mpi_engine.py ├── mpionly_utils.py ├── plotting │ ├── __init__.py │ └── plotting.py ├── run_tests.py ├── testing.py ├── tests │ ├── __init__.py │ ├── test_metadata_utils.py │ ├── test_plotting.py │ ├── test_testing.py │ └── test_utils.py └── utils.py ├── docs ├── sphinx │ ├── Makefile │ ├── make.bat │ ├── requirements.txt │ └── source │ │ ├── blurb.rst │ │ ├── build-the-docs.rst │ │ ├── conf.py │ │ ├── contact-us.rst │ │ ├── distarray.apps.rst │ │ ├── distarray.globalapi.rst │ │ ├── distarray.localapi.rst │ │ ├── distarray.plotting.rst │ │ ├── distarray.rst │ │ ├── environment-modules-notes.rst │ │ ├── getting-started.rst │ │ ├── hdf5-notes.rst │ │ ├── history.rst │ │ ├── index.rst │ │ ├── installation.rst │ │ ├── overview.rst │ │ ├── releases │ │ ├── release-0.2.rst │ │ ├── release-0.3.rst │ │ ├── release-0.4.rst │ │ ├── release-0.5.rst │ │ └── release-0.6.rst │ │ └── six-license.rst ├── talks │ ├── 2014-02-03-ams │ │ └── Enthought_distarray.pdf │ ├── 2014-06-apug │ │ ├── 2014-06-apug.ipynb │ │ ├── 2014-06-apug.pdf │ │ └── custom.css │ ├── 2014-07-10-scipy-lightning │ │ └── scipy-2014-lightning.pdf │ ├── 2015-04-12-pycon │ │ └── 2015-04-12-pycon-poster.pdf │ └── 2015-07-08-scipy │ │ └── 2015-07-08-scipy.pdf └── www │ ├── Makefile │ ├── README.rst │ ├── cache │ ├── ArticlesGenerator-Readers │ └── PagesGenerator-Readers │ ├── content │ ├── images │ │ └── distarray-logo.png │ ├── pages │ │ ├── contact.rst │ │ ├── features.md │ │ └── home.rst │ ├── release-notes │ │ ├── release-0-2-0.rst │ │ ├── release-0-3-0.rst │ │ ├── release-0-4-0.rst │ │ ├── release-0-5-0.rst │ │ └── release-0-6-0.rst │ └── talks │ │ ├── 2009-03-05-siam-granger.rst │ │ ├── 2014-02-03-ams.rst │ │ ├── 2014-02-16-apug-lightning-talk.rst │ │ ├── 2014-06-11-apug.rst │ │ ├── 2014-07-09-scipy-lightning-talk.rst │ │ ├── 2014-07-10-scipy-lightning-talk.rst │ │ ├── 2015-04-12-pycon-poster.rst │ │ └── 2015-07-08-scipy-talk.rst │ ├── develop_server.sh │ ├── fabfile.py │ ├── pelican-bootstrap3 │ ├── AUTHORS.md │ ├── CONTRIBUTING.md │ ├── EXAMPLES.md │ ├── LICENSE │ ├── README.md │ ├── screenshot-article.png │ ├── screenshot.png │ ├── static │ │ ├── css │ │ │ ├── bootstrap.amelia.min.css │ │ │ ├── bootstrap.cerulean.min.css │ │ │ ├── bootstrap.cosmo.min.css │ │ │ ├── bootstrap.cupid.min.css │ │ │ ├── bootstrap.cyborg.min.css │ │ │ ├── bootstrap.darkly.min.css │ │ │ ├── bootstrap.enthought.min.css │ │ │ ├── bootstrap.enthought_dark.min.css │ │ │ ├── bootstrap.enthought_light.min.css │ │ │ ├── bootstrap.flatly.min.css │ │ │ ├── bootstrap.journal.min.css │ │ │ ├── bootstrap.lumen.min.css │ │ │ ├── bootstrap.min.css │ │ │ ├── bootstrap.readable-old.min.css │ │ │ ├── bootstrap.readable.min.css │ │ │ ├── bootstrap.shamrock.min.css │ │ │ ├── bootstrap.simplex.min.css │ │ │ ├── bootstrap.slate.min.css │ │ │ ├── bootstrap.spacelab.min.css │ │ │ ├── bootstrap.superhero.min.css │ │ │ ├── bootstrap.united.min.css │ │ │ ├── bootstrap.yeti.min.css │ │ │ ├── font-awesome.css │ │ │ ├── font-awesome.min.css │ │ │ ├── html4css1.css │ │ │ ├── pygments │ │ │ │ ├── autumn.css │ │ │ │ ├── borland.css │ │ │ │ ├── bw.css │ │ │ │ ├── colorful.css │ │ │ │ ├── default.css │ │ │ │ ├── emacs.css │ │ │ │ ├── friendly.css │ │ │ │ ├── fruity.css │ │ │ │ ├── manni.css │ │ │ │ ├── monokai.css │ │ │ │ ├── murphy.css │ │ │ │ ├── native.css │ │ │ │ ├── pastie.css │ │ │ │ ├── perldoc.css │ │ │ │ ├── solarizeddark.css │ │ │ │ ├── solarizedlight.css │ │ │ │ ├── tango.css │ │ │ │ ├── trac.css │ │ │ │ ├── vim.css │ │ │ │ ├── vs.css │ │ │ │ └── zenburn.css │ │ │ ├── style.css │ │ │ └── typogrify.css │ │ ├── fonts │ │ │ ├── FontAwesome.otf │ │ │ ├── fontawesome-webfont.eot │ │ │ ├── fontawesome-webfont.svg │ │ │ ├── fontawesome-webfont.ttf │ │ │ ├── fontawesome-webfont.woff │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ └── glyphicons-halflings-regular.woff │ │ └── js │ │ │ ├── bootstrap.min.js │ │ │ ├── github.js │ │ │ ├── jXHR.js │ │ │ ├── jquery.min.js │ │ │ └── respond.min.js │ └── templates │ │ ├── archives.html │ │ ├── article.html │ │ ├── article_list.html │ │ ├── author.html │ │ ├── authors.html │ │ ├── base.html │ │ ├── categories.html │ │ ├── category.html │ │ ├── includes │ │ ├── aboutme.html │ │ ├── addthis.html │ │ ├── article_info.html │ │ ├── cc-license.html │ │ ├── comment_count.html │ │ ├── comments.html │ │ ├── disqus_script.html │ │ ├── footer.html │ │ ├── ga.html │ │ ├── github-js.html │ │ ├── github.html │ │ ├── links.html │ │ ├── liquid_tags_nb_header.html │ │ ├── pagination.html │ │ ├── piwik.html │ │ ├── related-posts.html │ │ ├── sidebar.html │ │ ├── taglist.html │ │ ├── translations.html │ │ ├── twitter_cards.html │ │ └── twitter_timeline.html │ │ ├── index.html │ │ ├── page.html │ │ ├── tag.html │ │ └── tags.html │ ├── pelican-plugins │ └── liquid_tags │ │ ├── .gitignore │ │ ├── Readme.md │ │ ├── __init__.py │ │ ├── audio.py │ │ ├── b64img.py │ │ ├── diag.py │ │ ├── flickr.py │ │ ├── giphy.py │ │ ├── gram.py │ │ ├── graphviz.py │ │ ├── img.py │ │ ├── include_code.py │ │ ├── liquid_tags.py │ │ ├── literal.py │ │ ├── mdx_liquid_tags.py │ │ ├── notebook.py │ │ ├── pelicanhtml_1.tpl │ │ ├── pelicanhtml_2.tpl │ │ ├── pelicanhtml_3.tpl │ │ ├── soundcloud.py │ │ ├── spotify.py │ │ ├── test_audio.py │ │ ├── test_data │ │ ├── content │ │ │ ├── notebooks │ │ │ │ ├── test_nbformat3.ipynb │ │ │ │ └── test_nbformat4.ipynb │ │ │ ├── test-ipython-notebook-nbformat3.md │ │ │ └── test-ipython-notebook-nbformat4.md │ │ ├── flickr.json │ │ ├── giphy.json │ │ ├── output │ │ │ ├── index.html │ │ │ ├── test-ipython-notebook-nb-format-3.html │ │ │ └── test-ipython-notebook-nb-format-4.html │ │ ├── pelicanconf.py │ │ ├── pelicanhtml_2.tpl │ │ └── pelicanhtml_3.tpl │ │ ├── test_flickr.py │ │ ├── test_generation.py │ │ ├── test_giphy.py │ │ ├── test_notebook.py │ │ ├── test_soundcloud.py │ │ ├── tox.ini │ │ ├── video.py │ │ ├── vimeo.py │ │ └── youtube.py │ ├── pelicanconf.py │ └── publishconf.py ├── examples ├── __init__.py ├── distarray_protocol │ ├── __init__.py │ ├── images │ │ └── README.txt │ └── plot_distarray_protocol.py ├── features.ipynb ├── gauss_elimination │ ├── ge_notebook.ipynb │ └── img1.png ├── julia_set │ ├── .gitignore │ ├── README.md │ ├── __init__.py │ ├── benchmark_julia.py │ ├── julia_set.ipynb │ ├── kernel.pyx │ ├── mpi_benchmark │ ├── plot_results.py │ └── setup.py ├── pi_montecarlo │ ├── README.rst │ ├── __init__.py │ ├── benchmark.py │ ├── pi_distarray.py │ ├── pi_ipython_parallel.py │ ├── pi_numpy.py │ └── util.py └── seismic_volume │ ├── README.rst │ ├── __init__.py │ ├── create_volume.py │ ├── load_volume.py │ └── seismic_volume.ipynb ├── quickstart ├── conda-quickstart ├── conda-readme.rst ├── enpkg-quickstart └── enpkg-readme.rst ├── setup.py └── utils ├── git-hooks ├── install-hooks.sh └── pre-commit ├── iopubwatcher.py └── test_h5py.py /.coveragerc: -------------------------------------------------------------------------------- 1 | # Configuration file for coverage.py test coverage tool. 2 | 3 | [run] 4 | branch = True 5 | source = distarray 6 | omit = 7 | */tests/* 8 | distarray/externals/* 9 | 10 | [html] 11 | directory = coverage_report 12 | 13 | [report] 14 | # Regexes for lines to exclude from consideration 15 | exclude_lines = 16 | # Have to re-enable the standard pragma 17 | pragma: no cover 18 | 19 | # Don't complain about missing debug-only code: 20 | def __repr__ 21 | 22 | # Don't complain if tests don't hit defensive assertion code: 23 | raise AssertionError 24 | raise NotImplementedError 25 | 26 | # Don't complain if non-runnable code isn't run: 27 | if __name__ == .__main__.: 28 | 29 | ignore_errors = True 30 | 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Editor temporary/working/backup files # 2 | ######################################### 3 | .#* 4 | [#]*# 5 | *~ 6 | *$ 7 | *.bak 8 | *.kdev4 9 | *.org 10 | .project 11 | .pydevproject 12 | *.rej 13 | .settings/ 14 | .*.sw[nop] 15 | .sw[nop] 16 | *.tmp 17 | *.vim 18 | tags 19 | 20 | # Compiled source # 21 | ################### 22 | *.a 23 | *.com 24 | *.class 25 | *.dll 26 | *.exe 27 | *.l[ao] 28 | *.o 29 | *.py[ocd] 30 | *.so 31 | _configtest.c 32 | 33 | # Packages # 34 | ############ 35 | # it's better to unpack these files and commit the raw source 36 | # git has its own built in compression methods 37 | *.7z 38 | *.bz2 39 | *.bzip2 40 | *.dmg 41 | *.gz 42 | *.iso 43 | *.jar 44 | *.rar 45 | *.tar 46 | *.tbz2 47 | *.tgz 48 | *.zip 49 | 50 | # Python files # 51 | ################ 52 | # setup.py working directory 53 | build 54 | # sphinx build directory 55 | doc/_build 56 | # cython files 57 | cythonize.dat 58 | # setup.py dist directory 59 | dist 60 | # Egg metadata 61 | *.egg-info 62 | # tox testing tool 63 | .tox 64 | # The shelf plugin uses this dir 65 | ./.shelf 66 | MANIFEST 67 | # distutils configuration 68 | site.cfg 69 | # other temporary files 70 | .deps 71 | .libs 72 | 73 | # Paver generated files # 74 | ######################### 75 | /release 76 | 77 | # Logs and databases # 78 | ###################### 79 | *.log 80 | *.sql 81 | *.sqlite 82 | 83 | # Patches # 84 | ########### 85 | *.patch 86 | *.diff 87 | 88 | # OS generated files # 89 | ###################### 90 | .directory 91 | .fseventsd 92 | .DS_Store* 93 | .gdb_history 94 | .VolumeIcon.icns 95 | ehthumbs.db 96 | Icon? 97 | Thumbs.db 98 | 99 | # Documentation generated files # 100 | ################################# 101 | docs/sphinx/build/* 102 | docs/www/output/* 103 | docs/www/cache/* 104 | 105 | # Things specific to this project # 106 | ################################### 107 | dist 108 | unittest*.out* 109 | .parallel_out 110 | 111 | # Coverage related files # 112 | ########################## 113 | .coverage* 114 | 115 | # Nose related files # 116 | ###################### 117 | .noseids 118 | 119 | # Rope related files # 120 | ###################### 121 | .ropeproject/ 122 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | os: 3 | - linux 4 | - osx 5 | env: 6 | - PYVERSION="2.7" NENGINES=1 7 | - PYVERSION="2.7" NENGINES=9 8 | - PYVERSION="3.4" NENGINES=9 9 | - PYVERSION="3.5" NENGINES=9 10 | before_install: 11 | - | 12 | if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then 13 | ulimit -n 4096; # bump osx ulimit 14 | fi 15 | - | 16 | if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then 17 | sudo add-apt-repository -y ppa:andrikos/ppa; # PPA with parallel hdf5 18 | sudo apt-get update; 19 | fi 20 | - | 21 | if [[ ${PYVERSION:0:1} == "2" && "$TRAVIS_OS_NAME" == "linux" ]]; then 22 | wget https://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O miniconda.sh; 23 | elif [[ ${PYVERSION:0:1} == "2" && "$TRAVIS_OS_NAME" == "osx" ]]; then 24 | wget https://repo.continuum.io/miniconda/Miniconda-latest-MacOSX-x86_64.sh -O miniconda.sh; 25 | elif [[ ${PYVERSION:0:1} == "3" && "$TRAVIS_OS_NAME" == "linux" ]]; then 26 | wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh; 27 | elif [[ ${PYVERSION:0:1} == "3" && "$TRAVIS_OS_NAME" == "osx" ]]; then 28 | wget https://repo.continuum.io/miniconda/Miniconda3-latest-MacOSX-x86_64.sh -O miniconda.sh; 29 | else 30 | exit 1; 31 | fi 32 | - bash miniconda.sh -b -p $HOME/miniconda 33 | - export PATH="$HOME/miniconda/bin:$PATH" 34 | - hash -r 35 | - conda config --set always_yes yes --set changeps1 no 36 | - conda update -q conda 37 | - conda info -a 38 | - travis_wait $TRAVIS_BUILD_DIR/quickstart/conda-quickstart --pyversion $PYVERSION --name distarray-env --yes 39 | - source activate distarray-env 40 | - pip install codecov pelican 41 | - | 42 | if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then # test parallel hdf5 43 | sudo apt-get install libhdf5-mpich2-7 libhdf5-mpich2-dev; # from Nick Andrik's PPA 44 | CC=mpicc pip install git+https://github.com/h5py/h5py.git@2.2.1 --install-option="--mpi"; 45 | fi 46 | install: 47 | - python setup.py install # build DistArray 48 | - (cd $TRAVIS_BUILD_DIR/docs/sphinx && make html) # build docs 49 | - (cd $TRAVIS_BUILD_DIR/docs/www && make html) # build website 50 | before_script: 51 | - python -c "import numpy; print('Numpy version', numpy.__version__)" 52 | - export DISPLAY=:99.0 # for plotting.py 53 | - | 54 | if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then 55 | sh -e /etc/init.d/xvfb start # for plotting.py 56 | elif [[ "$TRAVIS_OS_NAME" == "osx" ]]; then 57 | sudo Xvfb :99 -ac -screen 0 1024x768x8 & # for plotting.py 58 | else 59 | exit 1; 60 | fi 61 | - (cd $TRAVIS_BUILD_DIR && dacluster start -n$NENGINES) 62 | - lsof | grep python | wc -l 63 | script: 64 | - (cd $TRAVIS_BUILD_DIR && make test_with_coverage) 65 | after_script: 66 | - lsof | grep python | wc -l 67 | - (cd $TRAVIS_BUILD_DIR && dacluster stop) 68 | after_success: 69 | - if [[ $PYVERSION == "3.4" && "$TRAVIS_OS_NAME" == "linux" && $NENGINES -eq 9 ]] ; then 70 | echo "coverage combine"; coverage combine; 71 | echo "codecov"; codecov; 72 | fi 73 | -------------------------------------------------------------------------------- /COPYING.rst: -------------------------------------------------------------------------------- 1 | Copyright (c) 2008-2014, IPython Development Team and Enthought, Inc. 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | Redistributions of source code must retain the above copyright notice, this list of 9 | conditions and the following disclaimer. 10 | 11 | Redistributions in binary form must reproduce the above copyright notice, this list 12 | of conditions and the following disclaimer in the documentation and/or other 13 | materials provided with the distribution. 14 | 15 | Neither the names of the copyright holders nor the names of their contributors 16 | may be used to endorse or promote products derived from this software without 17 | specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include Makefile 2 | include *.rst 3 | graft docs 4 | graft examples 5 | graft utils 6 | prune docs/build 7 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | .. Travis badge 2 | .. image:: https://travis-ci.org/enthought/distarray.svg?branch=master 3 | :target: https://travis-ci.org/enthought/distarray 4 | 5 | .. codecov badge 6 | .. image:: http://codecov.io/github/enthought/distarray/coverage.svg?branch=master 7 | :target: http://codecov.io/github/enthought/distarray?branch=master 8 | 9 | .. readthedocs badge 10 | .. image:: https://readthedocs.org/projects/distarray/badge/?version=master 11 | :target: http://distarray.readthedocs.org/en/master/ 12 | 13 | .. pypi badge 14 | .. image:: https://badge.fury.io/py/distarray.svg 15 | :target: http://badge.fury.io/py/distarray 16 | 17 | .. All content before the next comment will be stripped off for release. 18 | .. *** begin README content *** 19 | 20 | DistArray 21 | ========= 22 | 23 | *Think globally, act locally.* 24 | 25 | DistArray provides general multidimensional NumPy-like distributed arrays to 26 | Python. It intends to bring the strengths of NumPy to data-parallel 27 | high-performance computing. DistArray has a similar API to `NumPy`_. 28 | 29 | DistArray is ready for real-world testing and deployment; however, the project 30 | is still evolving rapidly, and we appreciate continued input from the 31 | scientific-Python community. 32 | 33 | DistArray is for users who 34 | 35 | * know and love Python and NumPy, 36 | * want to scale NumPy to larger distributed datasets, 37 | * want to interactively play with distributed data but also 38 | * want to run batch-oriented distributed programs; 39 | * want an easier way to drive and coordinate existing MPI-based codes, 40 | * have a lot of data that may already be distributed, 41 | * want a global view ("think globally") with local control ("act locally"), 42 | * need to tap into existing parallel libraries like Trilinos, PETSc, or 43 | Elemental, 44 | * want the interactivity of IPython and the performance of MPI. 45 | 46 | DistArray is designed to work with other packages that implement the 47 | `Distributed Array Protocol`_. 48 | 49 | .. _Distributed Array Protocol: http://distributed-array-protocol.readthedocs.org 50 | .. _NumPy: http://www.numpy.org 51 | 52 | Please see our documentation at `readthedocs`_ (or in the `docs` directory) for 53 | more, or ask us questions on our `mailing list`_. Pull requests gladly accepted. 54 | 55 | 56 | .. _readthedocs: http://distarray.readthedocs.org 57 | .. _mailing list: https://groups.google.com/forum/#!forum/distarray 58 | -------------------------------------------------------------------------------- /branding/logos/pngs/DistArray-LOGO-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enthought/distarray/0e014e4d08e6745f5028a53132a424f909ca354e/branding/logos/pngs/DistArray-LOGO-large.png -------------------------------------------------------------------------------- /branding/logos/pngs/DistArray-LOGO-mid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enthought/distarray/0e014e4d08e6745f5028a53132a424f909ca354e/branding/logos/pngs/DistArray-LOGO-mid.png -------------------------------------------------------------------------------- /branding/logos/pngs/DistArray-LOGO-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enthought/distarray/0e014e4d08e6745f5028a53132a424f909ca354e/branding/logos/pngs/DistArray-LOGO-small.png -------------------------------------------------------------------------------- /branding/logos/pngs/DistArray-LOGO-smallest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enthought/distarray/0e014e4d08e6745f5028a53132a424f909ca354e/branding/logos/pngs/DistArray-LOGO-smallest.png -------------------------------------------------------------------------------- /distarray/__init__.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # --------------------------------------------------------------------------- 3 | # Copyright (C) 2008-2014, IPython Development Team and Enthought, Inc. 4 | # Distributed under the terms of the BSD License. See COPYING.rst. 5 | # --------------------------------------------------------------------------- 6 | 7 | """ 8 | DistArray: Distributed NumPy-like arrays 9 | ======================================== 10 | 11 | Documentation is available in docstrings and online at 12 | http://distarray.readthedocs.org. 13 | 14 | Check out the ``examples`` directory in the source distribution for several 15 | example modules and IPython notebooks using DistArray. 16 | """ 17 | 18 | from distarray.__version__ import __version__ 19 | from distarray.run_tests import test 20 | DISTARRAY_BASE_NAME = '__distarray__' 21 | -------------------------------------------------------------------------------- /distarray/__version__.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # --------------------------------------------------------------------------- 3 | # Copyright (C) 2008-2014, IPython Development Team and Enthought, Inc. 4 | # Distributed under the terms of the BSD License. See COPYING.rst. 5 | # --------------------------------------------------------------------------- 6 | 7 | """ 8 | Version information for the DistArray package. 9 | """ 10 | 11 | __short_version__ = "0.7" 12 | __version__ = "0.7.0-dev" 13 | -------------------------------------------------------------------------------- /distarray/apps/__init__.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # --------------------------------------------------------------------------- 3 | # Copyright (C) 2008-2014, IPython Development Team and Enthought, Inc. 4 | # Distributed under the terms of the BSD License. See COPYING.rst. 5 | # --------------------------------------------------------------------------- 6 | 7 | """ 8 | Scripts for use with the DistArray package. 9 | """ 10 | -------------------------------------------------------------------------------- /distarray/apps/engine.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | # --------------------------------------------------------------------------- 4 | # Copyright (C) 2008-2014, IPython Development Team and Enthought, Inc. 5 | # Distributed under the terms of the BSD License. See COPYING.rst. 6 | # --------------------------------------------------------------------------- 7 | 8 | """ 9 | Script for facilitating MPI-only mode. 10 | 11 | Starts an MPI-process-based engine. 12 | """ 13 | 14 | from distarray.mpi_engine import Engine 15 | 16 | if __name__ == '__main__': 17 | # use argparse to generate usage text (-h) 18 | import argparse 19 | parser = argparse.ArgumentParser(description=__doc__) 20 | parser.parse_args() 21 | 22 | Engine() 23 | -------------------------------------------------------------------------------- /distarray/error.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # --------------------------------------------------------------------------- 3 | # Copyright (C) 2008-2014, IPython Development Team and Enthought, Inc. 4 | # Distributed under the terms of the BSD License. See COPYING.rst. 5 | # --------------------------------------------------------------------------- 6 | 7 | """ 8 | Exception classes for DistArray errors. 9 | """ 10 | 11 | 12 | class DistArrayError(Exception): 13 | """ Base exception class for DistArray errors. """ 14 | pass 15 | 16 | 17 | class MPIDistArrayError(DistArrayError): 18 | """ Base exception class for MPI distribution errors. """ 19 | pass 20 | 21 | 22 | class ContextError(DistArrayError): 23 | """ Exception class when a unique Context cannot be found. """ 24 | pass 25 | 26 | 27 | class InvalidCommSizeError(MPIDistArrayError): 28 | """ Exception class when a requested communicator is too large. """ 29 | pass 30 | 31 | 32 | class InvalidRankError(MPIDistArrayError): 33 | """ Exception class when an invalid rank is used in a communicator. """ 34 | pass 35 | 36 | 37 | class DistributionError(DistArrayError): 38 | """ Exception class when inconsistent distributions are used. """ 39 | pass 40 | -------------------------------------------------------------------------------- /distarray/externals/__init__.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # --------------------------------------------------------------------------- 3 | # Copyright (C) 2008-2014, IPython Development Team and Enthought, Inc. 4 | # Distributed under the terms of the BSD License. See COPYING.rst. 5 | # --------------------------------------------------------------------------- 6 | 7 | 8 | -------------------------------------------------------------------------------- /distarray/globalapi/__init__.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # --------------------------------------------------------------------------- 3 | # Copyright (C) 2008-2014, IPython Development Team and Enthought, Inc. 4 | # Distributed under the terms of the BSD License. See COPYING.rst. 5 | # --------------------------------------------------------------------------- 6 | 7 | """ 8 | Modules dealing with the global index-space view of `DistArray`\s. 9 | 10 | In other words, the view from the client. 11 | """ 12 | 13 | from __future__ import absolute_import 14 | 15 | from distarray.globalapi.distarray import DistArray 16 | from distarray.globalapi.context import Context, ContextCreationError 17 | from distarray.globalapi.maps import Distribution 18 | from distarray.globalapi.functions import * 19 | -------------------------------------------------------------------------------- /distarray/globalapi/ipython_cleanup.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # --------------------------------------------------------------------------- 3 | # Copyright (C) 2008-2014, IPython Development Team and Enthought, Inc. 4 | # Distributed under the terms of the BSD License. See COPYING.rst. 5 | # --------------------------------------------------------------------------- 6 | 7 | """ 8 | Functions for cleaning up `DistArray` objects from IPython parallel engines. 9 | """ 10 | 11 | from __future__ import print_function, absolute_import 12 | 13 | from distarray.globalapi.ipython_utils import IPythonClient 14 | 15 | 16 | def cleanup(view, module_name, prefix): 17 | """ Delete Context object with the given name from the given module""" 18 | def _cleanup(module_name, prefix): 19 | from importlib import import_module 20 | ns = import_module(module_name) 21 | for name in vars(ns).copy(): 22 | if name.startswith(prefix): 23 | delattr(ns, name) 24 | 25 | view.apply_sync(_cleanup, module_name, prefix) 26 | 27 | 28 | def cleanup_all(module_name, prefix): 29 | """ Connects to all engines and runs ``cleanup()`` on them. """ 30 | c = IPythonClient() 31 | if c is None: 32 | return 33 | try: 34 | v = c[:] 35 | cleanup(v, module_name, prefix) 36 | finally: 37 | c.close() 38 | 39 | 40 | def get_local_keys(view, prefix): 41 | """ Returns a dictionary of keyname -> target_list mapping for all names 42 | that start with ``prefix`` on engines in ``view``. 43 | """ 44 | 45 | def get_keys_engine(prefix): 46 | return [key for key in globals() if key.startswith(prefix)] 47 | 48 | keys_from_target = view.apply_async(get_keys_engine, prefix).get_dict() 49 | 50 | targets_from_key = {} 51 | for target, keys in keys_from_target.items(): 52 | for key in keys: 53 | targets_from_key.setdefault(key, []).append(target) 54 | 55 | return targets_from_key 56 | 57 | def clear(view): 58 | """ Removes all distarray-related modules from engines' sys.modules.""" 59 | 60 | def clear_engine(): 61 | from sys import modules 62 | orig_mods = set(modules) 63 | for m in modules.copy(): 64 | if m.startswith('distarray'): 65 | del modules[m] 66 | return sorted(orig_mods - set(modules)) 67 | 68 | return view.apply_async(clear_engine).get_dict() 69 | 70 | def clear_all(): 71 | c = IPythonClient() 72 | if c is None: 73 | return 74 | try: 75 | v = c[:] 76 | mods = clear(v) 77 | finally: 78 | c.close() 79 | return mods 80 | -------------------------------------------------------------------------------- /distarray/globalapi/ipython_utils.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # --------------------------------------------------------------------------- 3 | # Copyright (C) 2008-2014, IPython Development Team and Enthought, Inc. 4 | # Distributed under the terms of the BSD License. See COPYING.rst. 5 | # --------------------------------------------------------------------------- 6 | 7 | """ 8 | The single IPython entry point. 9 | """ 10 | 11 | from ipyparallel import Client as IPythonClient 12 | -------------------------------------------------------------------------------- /distarray/globalapi/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # --------------------------------------------------------------------------- 3 | # Copyright (C) 2008-2014, IPython Development Team and Enthought, Inc. 4 | # Distributed under the terms of the BSD License. See COPYING.rst. 5 | # --------------------------------------------------------------------------- 6 | 7 | -------------------------------------------------------------------------------- /distarray/globalapi/tests/launch_mpi.py: -------------------------------------------------------------------------------- 1 | """ 2 | Script to test launching an MPI-only client. 3 | 4 | $ mpiexec -np python launch_mpi.py 5 | 6 | If exits cleanly, then everything is fine. If exits with an error code, then 7 | there's a problem. 8 | 9 | """ 10 | 11 | from __future__ import print_function 12 | from distarray.globalapi import Context, Distribution 13 | import numpy as np 14 | 15 | c = Context(kind='MPI') 16 | 17 | fmt = lambda s: "{:.<25s}:".format(s) 18 | 19 | print(fmt("Context"), c) 20 | print(fmt("targets"), c.targets) 21 | 22 | if __name__ == '__main__': 23 | size = len(c.targets) * 100 24 | print(fmt("size"), size) 25 | dist = Distribution(c, (size,)) 26 | print(fmt("Distribution"), dist) 27 | da = c.ones(dist, dtype=np.int64) 28 | print(fmt("DistArray"), da) 29 | factor = 2 30 | db = da * factor 31 | print(fmt("DistArray"), db) 32 | sum = db.sum().tondarray() 33 | print(fmt("sum"), sum) 34 | print(fmt("sum == factor * size"), sum == size * factor) 35 | assert sum == size * factor 36 | -------------------------------------------------------------------------------- /distarray/localapi/__init__.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # --------------------------------------------------------------------------- 3 | # Copyright (C) 2008-2014, IPython Development Team and Enthought, Inc. 4 | # Distributed under the terms of the BSD License. See COPYING.rst. 5 | # --------------------------------------------------------------------------- 6 | 7 | """ 8 | Modules dealing with the local index-space view of `DistArray`\s. 9 | 10 | In other words, the view from an engine. 11 | """ 12 | 13 | from distarray.localapi import localarray 14 | from distarray.localapi.localarray import * 15 | from distarray.localapi.mpiutils import get_base_comm 16 | -------------------------------------------------------------------------------- /distarray/localapi/construct.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # --------------------------------------------------------------------------- 3 | # Copyright (C) 2008-2014, IPython Development Team and Enthought, Inc. 4 | # Distributed under the terms of the BSD License. See COPYING.rst. 5 | # --------------------------------------------------------------------------- 6 | 7 | from __future__ import division 8 | 9 | from distarray.localapi.mpiutils import MPI 10 | from distarray.localapi.error import NullCommError, InvalidBaseCommError 11 | 12 | 13 | # --------------------------------------------------------------------------- 14 | # Stateless functions for initializing various aspects of DistArray and 15 | # LocalArray objects. 16 | # --------------------------------------------------------------------------- 17 | 18 | # These are functions rather than methods because they need to be both 19 | # stateless and free of side-effects. It is possible that they could be 20 | # called multiple times and in multiple different contexts in the course 21 | # of a LocalArray object's lifetime (for example upon a reshape or redist). 22 | # The simplest and most robust way of insuring this is to get rid of 'self' 23 | # (which holds all state) and make them standalone functions. 24 | 25 | def init_base_comm(comm): 26 | """Sanitize an MPI.comm instance or create one.""" 27 | if comm == MPI.COMM_NULL: 28 | raise NullCommError("Cannot create a LocalArray with COMM_NULL") 29 | elif isinstance(comm, MPI.Comm): 30 | return comm 31 | else: 32 | raise InvalidBaseCommError("Not an MPI.Comm instance") 33 | 34 | 35 | def init_comm(base_comm, grid_shape): 36 | """Create an MPI communicator with a cartesian topology.""" 37 | return base_comm.Create_cart(grid_shape, len(grid_shape) * (False,), 38 | reorder=False) 39 | -------------------------------------------------------------------------------- /distarray/localapi/error.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # --------------------------------------------------------------------------- 3 | # Copyright (C) 2008-2014, IPython Development Team and Enthought, Inc. 4 | # Distributed under the terms of the BSD License. See COPYING.rst. 5 | # --------------------------------------------------------------------------- 6 | 7 | from distarray.error import DistArrayError 8 | 9 | 10 | class InvalidBaseCommError(DistArrayError): 11 | """ Exception class when an object expected to be an MPI.Comm object is not one. """ 12 | pass 13 | 14 | 15 | class IncompatibleArrayError(DistArrayError): 16 | """ Exception class when arrays are incompatible. """ 17 | pass 18 | 19 | 20 | class NullCommError(DistArrayError): 21 | """ Exception class when an MPI communicator is NULL. """ 22 | pass 23 | 24 | 25 | class InvalidDimensionError(DistArrayError): 26 | """ Exception class when a specified dimension is invalid. """ 27 | pass 28 | -------------------------------------------------------------------------------- /distarray/localapi/mpiutils.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # --------------------------------------------------------------------------- 3 | # Copyright (C) 2008-2014, IPython Development Team and Enthought, Inc. 4 | # Distributed under the terms of the BSD License. See COPYING.rst. 5 | # --------------------------------------------------------------------------- 6 | """ 7 | Entry point for MPI. 8 | """ 9 | 10 | import numpy as np 11 | 12 | from mpi4py import MPI 13 | from distarray.error import InvalidCommSizeError, InvalidRankError 14 | 15 | def get_base_comm(): 16 | return _BASE_COMM 17 | 18 | _BASE_COMM = None 19 | def set_base_comm(comm): 20 | global _BASE_COMM 21 | _BASE_COMM = comm 22 | 23 | def get_comm_private(): 24 | return MPI.COMM_WORLD.Clone() 25 | 26 | 27 | def create_comm_of_size(size=4): 28 | """ 29 | Create a subcommunicator of COMM_PRIVATE of given size. 30 | """ 31 | COMM_PRIVATE = get_comm_private() 32 | group = COMM_PRIVATE.Get_group() 33 | comm_size = COMM_PRIVATE.Get_size() 34 | if size > comm_size: 35 | raise InvalidCommSizeError("requested size (%i) is bigger than the comm size (%i)" % (size, comm_size)) 36 | else: 37 | subgroup = group.Incl(list(range(size))) 38 | newcomm = COMM_PRIVATE.Create(subgroup) 39 | return newcomm 40 | 41 | 42 | def create_comm_with_list(nodes, base_comm=None): 43 | """ 44 | Create a subcommunicator of base_comm with a list of ranks. 45 | 46 | If base_comm is not specified, defaults to COMM_PRIVATE. 47 | 48 | """ 49 | base_comm = base_comm or get_comm_private() 50 | group = base_comm.Get_group() 51 | comm_size = base_comm.Get_size() 52 | size = len(nodes) 53 | if size > comm_size: 54 | raise InvalidCommSizeError("requested size (%i) is bigger than the comm size (%i)" % (size, comm_size)) 55 | for i in nodes: 56 | if not i in range(comm_size): 57 | raise InvalidRankError("rank is not valid: %r" % i) 58 | subgroup = group.Incl(nodes) 59 | newcomm = base_comm.Create(subgroup) 60 | return newcomm 61 | 62 | 63 | mpi_dtypes = { 64 | np.dtype('f'): MPI.FLOAT, 65 | np.dtype('d'): MPI.DOUBLE, 66 | np.dtype('i'): MPI.INTEGER, 67 | np.dtype('l'): MPI.LONG 68 | } 69 | 70 | 71 | def mpi_type_for_ndarray(a): 72 | return mpi_dtypes[a.dtype] 73 | -------------------------------------------------------------------------------- /distarray/localapi/proxyize.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # ----------------------------------------------------------------------------- 3 | # Copyright (C) 2008-2014, IPython Development Team and Enthought, Inc. 4 | # Distributed under the terms of the BSD License. See COPYING.rst. 5 | # ----------------------------------------------------------------------------- 6 | 7 | from importlib import import_module 8 | 9 | from distarray.utils import DISTARRAY_BASE_NAME 10 | 11 | class Proxy(object): 12 | 13 | def __init__(self, name, obj, module_name): 14 | self.name = name 15 | self.module_name = module_name 16 | self.type_str = str(type(obj)) 17 | namespace = import_module(self.module_name) 18 | setattr(namespace, self.name, obj) 19 | 20 | def dereference(self): 21 | """ Callable only on the engines. """ 22 | namespace = import_module(self.module_name) 23 | return getattr(namespace, self.name) 24 | 25 | def cleanup(self): 26 | namespace = import_module(self.module_name) 27 | delattr(namespace, self.name) 28 | self.name = self.module_name = self.type_str = None 29 | 30 | 31 | class Proxyize(object): 32 | 33 | """Callable that, given an object, returns a Proxy object. 34 | 35 | You must call `set_state` on the instance before you can "call" it. 36 | """ 37 | 38 | def __init__(self): 39 | self.count = None 40 | self.state = None 41 | 42 | def set_state(self, state): 43 | self.state = state 44 | self.count = 0 45 | 46 | def str_counter(self): 47 | """Return the str value of `self.count`, then increment its value.""" 48 | res = str(self.count) 49 | self.count += 1 50 | return res 51 | 52 | def next_name(self): 53 | if (self.state is None) or (self.count is None): 54 | raise RuntimeError("proxyize's state must be set before being " 55 | "called.") 56 | return DISTARRAY_BASE_NAME + self.state + self.str_counter() 57 | 58 | def __call__(self, obj): 59 | """Return a `Proxy` object given an object `obj`.""" 60 | new_name = self.next_name() 61 | return Proxy(new_name, obj, '__main__') 62 | -------------------------------------------------------------------------------- /distarray/localapi/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # --------------------------------------------------------------------------- 3 | # Copyright (C) 2008-2014, IPython Development Team and Enthought, Inc. 4 | # Distributed under the terms of the BSD License. See COPYING.rst. 5 | # --------------------------------------------------------------------------- 6 | -------------------------------------------------------------------------------- /distarray/localapi/tests/paralleltest_mpiutils.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # --------------------------------------------------------------------------- 3 | # Copyright (C) 2008-2014, IPython Development Team and Enthought, Inc. 4 | # Distributed under the terms of the BSD License. See COPYING.rst. 5 | # --------------------------------------------------------------------------- 6 | 7 | import unittest 8 | import numpy 9 | from numpy.testing import assert_array_equal 10 | 11 | from distarray.localapi.localarray import zeros 12 | from distarray.localapi.maps import Distribution 13 | from distarray.error import InvalidCommSizeError, InvalidRankError 14 | from distarray.localapi.mpiutils import (MPI, create_comm_of_size, 15 | create_comm_with_list) 16 | 17 | 18 | class TestCreateCommAlternate(unittest.TestCase): 19 | """ Test alternate code paths for creating the MPI comm. 20 | 21 | In particular, test creating the comm from a list, 22 | and the failure modes for creating the comm. 23 | 24 | These code paths are not covered normally by ParallelTestCase, 25 | so this test case does not derive from that usual base class. 26 | """ 27 | 28 | def setUp(self): 29 | # Get the maximum number of nodes available. 30 | COMM_PRIVATE = MPI.COMM_WORLD.Clone() 31 | self.max_size = COMM_PRIVATE.Get_size() 32 | 33 | def test_create_comm_with_list(self): 34 | """ Test that create_comm_with_list() works correctly. """ 35 | nodes = list(range(self.max_size)) 36 | comm = create_comm_with_list(nodes) 37 | if comm == MPI.COMM_NULL: 38 | # Only proceed when not COMM_NULL. 39 | return 40 | # Run a simple test to confirm this comm works. 41 | size = len(nodes) 42 | nrows = size * 3 43 | d = Distribution.from_shape(comm=comm, shape=(nrows, 20)) 44 | a = zeros(d) 45 | expected = numpy.zeros((nrows // size, 20)) 46 | assert_array_equal(a.ndarray, expected) 47 | # Cleanup. 48 | comm.Free() 49 | 50 | def test_size_too_big(self): 51 | """ Test that a comm of size with too many nodes will fail. """ 52 | too_many = 2 * self.max_size 53 | with self.assertRaises(InvalidCommSizeError): 54 | create_comm_of_size(too_many) 55 | 56 | def test_list_too_big(self): 57 | """ Test that a comm from list with too many nodes will fail. """ 58 | too_many = 2 * self.max_size 59 | nodes = range(too_many) 60 | with self.assertRaises(InvalidCommSizeError): 61 | create_comm_with_list(nodes) 62 | 63 | def test_invalid_ranks(self): 64 | """ Test that a comm from list with invalid ranks will fail. """ 65 | max_size = self.max_size 66 | # Nodes should be 0..max_size - 1, so create invalid values. 67 | nodes = range(10, max_size + 10) 68 | with self.assertRaises(InvalidRankError): 69 | create_comm_with_list(nodes) 70 | 71 | 72 | if __name__ == '__main__': 73 | try: 74 | unittest.main() 75 | except SystemExit: 76 | pass 77 | -------------------------------------------------------------------------------- /distarray/localapi/tests/paralleltest_random.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # --------------------------------------------------------------------------- 3 | # Copyright (C) 2008-2014, IPython Development Team and Enthought, Inc. 4 | # Distributed under the terms of the BSD License. See COPYING.rst. 5 | # --------------------------------------------------------------------------- 6 | 7 | import unittest 8 | import numpy as np 9 | 10 | from distarray.localapi import random as local_random 11 | from distarray.localapi.maps import Distribution 12 | from distarray.testing import ParallelTestCase 13 | 14 | 15 | class TestBasic(ParallelTestCase): 16 | """Run basic shape/size tests on functions in `random.py`.""" 17 | 18 | def shape_asserts(self, la): 19 | self.assertEqual(la.dist, ('b', 'b')) 20 | self.assertEqual(la.global_shape, (16, 16)) 21 | self.assertEqual(la.ndim, 2) 22 | self.assertEqual(la.global_size, 16*16) 23 | self.assertEqual(la.comm_size, 4) 24 | self.assertTrue(la.comm_rank in range(4)) 25 | self.assertEqual(la.grid_shape, (4, 1)) 26 | self.assertEqual(len(la.distribution), 2) 27 | self.assertEqual(la.global_shape, (16, 16)) 28 | self.assertEqual(la.local_shape, (4, 16)) 29 | self.assertEqual(la.ndarray.shape, la.local_shape) 30 | self.assertEqual(la.ndarray.dtype, la.dtype) 31 | 32 | def test_label_state(self): 33 | """ Test we can label the local random generator with the rank. """ 34 | # This test is mainly intended for coverage, as the client-side 35 | # test of the behavior does not label the routine as covered. 36 | s0, orig_array, s2, s3, s4 = np.random.get_state() 37 | local_random.label_state(self.comm) 38 | s0, rank_array, s2, s3, s4 = np.random.get_state() 39 | # State should have changed from labeling. 40 | state_equal = np.all(orig_array == rank_array) 41 | self.assertFalse(state_equal) 42 | 43 | def test_beta(self): 44 | d = Distribution.from_shape(comm=self.comm, 45 | shape=(16, 16), grid_shape=(4, 1)) 46 | la = local_random.beta(2, 5, distribution=d) 47 | self.shape_asserts(la) 48 | 49 | def test_normal(self): 50 | d = Distribution.from_shape(comm=self.comm, 51 | shape=(16, 16), grid_shape=(4, 1)) 52 | la = local_random.normal(distribution=d) 53 | self.shape_asserts(la) 54 | 55 | def test_rand(self): 56 | d = Distribution.from_shape(comm=self.comm, 57 | shape=(16, 16), grid_shape=(4, 1)) 58 | la = local_random.rand(d) 59 | self.shape_asserts(la) 60 | 61 | def test_randint(self): 62 | d = Distribution.from_shape(comm=self.comm, 63 | shape=(16, 16), grid_shape=(4, 1)) 64 | la = local_random.randint(0, 10, distribution=d) 65 | self.shape_asserts(la) 66 | 67 | def test_randn(self): 68 | d = Distribution.from_shape(comm=self.comm, 69 | shape=(16, 16), grid_shape=(4, 1)) 70 | la = local_random.randn(distribution=d) 71 | self.shape_asserts(la) 72 | 73 | 74 | if __name__ == '__main__': 75 | try: 76 | unittest.main() 77 | except SystemExit: 78 | pass 79 | -------------------------------------------------------------------------------- /distarray/localapi/tests/test_format.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # --------------------------------------------------------------------------- 3 | # Copyright (C) 2008-2014, IPython Development Team and Enthought, Inc. 4 | # Distributed under the terms of the BSD License. See COPYING.rst. 5 | # --------------------------------------------------------------------------- 6 | 7 | 8 | import unittest 9 | import six 10 | 11 | from distarray.localapi import format as fmt 12 | 13 | 14 | class TestMagic(unittest.TestCase): 15 | 16 | def test_magic_0(self): 17 | expected = six.b('\x93DARRY\x03\x02') 18 | 19 | prefix = six.b('\x93DARRY') 20 | major = 3 21 | minor = 2 22 | 23 | result = fmt.magic(major=major, minor=minor, prefix=prefix) 24 | self.assertEqual(result, expected) 25 | 26 | def test_magic_1(self): 27 | expected = six.b('\x93NUMPY\x01\x00') 28 | 29 | prefix = six.b('\x93NUMPY') 30 | major = 1 31 | minor = 0 32 | 33 | result = fmt.magic(major=major, minor=minor, prefix=prefix) 34 | self.assertEqual(result, expected) 35 | 36 | 37 | class TestReadMagic(unittest.TestCase): 38 | 39 | def test_read_magic_0(self): 40 | prefix = six.b('\x93DARRY') 41 | prefix_len = 8 42 | fp = six.BytesIO(six.b('\x93DARRY\x03\x02')) 43 | 44 | major, minor = fmt.read_magic(fp, prefix=prefix, prefix_len=prefix_len) 45 | 46 | expected = (3, 2) 47 | self.assertEqual((major, minor), expected) 48 | 49 | def test_read_magic_1(self): 50 | prefix = six.b('\x93NUMPY') 51 | prefix_len = 8 52 | fp = six.BytesIO(six.b('\x93NUMPY\x01\x01')) 53 | 54 | major, minor = fmt.read_magic(fp, prefix=prefix, prefix_len=prefix_len) 55 | 56 | expected = (1, 1) 57 | self.assertEqual((major, minor), expected) 58 | -------------------------------------------------------------------------------- /distarray/localapi/tests/test_mpiutils.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # --------------------------------------------------------------------------- 3 | # Copyright (C) 2008-2014, IPython Development Team and Enthought, Inc. 4 | # Distributed under the terms of the BSD License. See COPYING.rst. 5 | # --------------------------------------------------------------------------- 6 | 7 | import unittest 8 | import numpy 9 | 10 | from distarray.localapi.mpiutils import mpi_type_for_ndarray 11 | 12 | 13 | class TestMpiTypes(unittest.TestCase): 14 | """ Test the mpi_type_for_ndarray method. """ 15 | 16 | def test_mpi_type_for_ndarray(self): 17 | """ Test the mpi_type_for_ndarray method. """ 18 | arr = numpy.ones((3, 3)) 19 | mpi_dtype = mpi_type_for_ndarray(arr) 20 | # The specific values returned are beyond the scope of this project, 21 | # so just check that we get something. 22 | self.assertIsNotNone(mpi_dtype) 23 | 24 | 25 | if __name__ == '__main__': 26 | unittest.main(verbosity=2) 27 | -------------------------------------------------------------------------------- /distarray/plotting/__init__.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # --------------------------------------------------------------------------- 3 | # Copyright (C) 2008-2014, IPython Development Team and Enthought, Inc. 4 | # Distributed under the terms of the BSD License. See COPYING.rst. 5 | # --------------------------------------------------------------------------- 6 | 7 | """ 8 | Plotting functions for distarrays. 9 | """ 10 | 11 | from distarray.plotting.plotting import * 12 | -------------------------------------------------------------------------------- /distarray/run_tests.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # --------------------------------------------------------------------------- 3 | # Copyright (C) 2008-2014, IPython Development Team and Enthought, Inc. 4 | # Distributed under the terms of the BSD License. See COPYING.rst. 5 | # --------------------------------------------------------------------------- 6 | 7 | """ 8 | Functions for running DistArray tests. 9 | """ 10 | 11 | from __future__ import print_function 12 | 13 | import os 14 | import sys 15 | import shlex 16 | import subprocess 17 | 18 | import distarray 19 | 20 | 21 | def _run_shell_command(specific_cmd): 22 | """Run a command with subprocess and pass the results through to stdout. 23 | 24 | First, change directory to the project directory. 25 | """ 26 | path = os.path.split(os.path.split(os.path.abspath(distarray.__file__))[0])[0] 27 | os.chdir(path) 28 | proc = subprocess.Popen(shlex.split(specific_cmd), 29 | stdout=subprocess.PIPE, 30 | stderr=subprocess.STDOUT) 31 | while True: 32 | char = proc.stdout.read(1).decode() 33 | if not char: 34 | return proc.wait() 35 | else: 36 | print(char, end="") 37 | sys.stdout.flush() 38 | 39 | 40 | def test(): 41 | """Run all DistArray tests.""" 42 | cmd = "make test" 43 | return _run_shell_command(cmd) 44 | 45 | 46 | if __name__ == "__main__": 47 | sys.exit(test()) 48 | -------------------------------------------------------------------------------- /distarray/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enthought/distarray/0e014e4d08e6745f5028a53132a424f909ca354e/distarray/tests/__init__.py -------------------------------------------------------------------------------- /distarray/tests/test_plotting.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # --------------------------------------------------------------------------- 3 | # Copyright (C) 2008-2014, IPython Development Team and Enthought, Inc. 4 | # Distributed under the terms of the BSD License. See COPYING.rst. 5 | # --------------------------------------------------------------------------- 6 | 7 | """ 8 | Tests for plotting.py 9 | 10 | Many of these tests require a 4-engine cluster to be running locally. The 11 | engines should be launched with MPI, using the MPIEngineSetLauncher. 12 | """ 13 | 14 | # Note: This test is here instead of in distarray/plotting/tests so that it can 15 | # be conditionally skipped. Having it in inside plotting/ would cause a 16 | # failure upon running the test due to the `import *` in the plotting 17 | # directory's `__init__.py`. 18 | 19 | import unittest 20 | 21 | from distarray.testing import DefaultContextTestCase 22 | from distarray.globalapi import Distribution 23 | from distarray.testing import import_or_skip 24 | 25 | 26 | class TestPlotting(DefaultContextTestCase): 27 | """Test Context methods""" 28 | 29 | @classmethod 30 | def setUpClass(cls): 31 | # raise a skipTest if plotting import fails 32 | # (because matplotlib isn't installed, probably) 33 | cls.plt = import_or_skip("distarray.plotting") 34 | super(TestPlotting, cls).setUpClass() 35 | cls.da = Distribution(cls.context, (64, 64)) 36 | cls.arr = cls.context.ones(cls.da) 37 | 38 | def test_plot_array_distribution(self): 39 | # Only tests that this runs, not that it's correct 40 | process_coords = [(0, 0), (1, 0), (2, 0), (3, 0)] 41 | self.plt.plot_array_distribution(self.arr, process_coords) 42 | 43 | 44 | if __name__ == '__main__': 45 | unittest.main(verbosity=2) 46 | -------------------------------------------------------------------------------- /distarray/tests/test_testing.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # --------------------------------------------------------------------------- 3 | # Copyright (C) 2008-2014, IPython Development Team and Enthought, Inc. 4 | # Distributed under the terms of the BSD License. See COPYING.rst. 5 | # --------------------------------------------------------------------------- 6 | 7 | import unittest 8 | from distarray import testing 9 | 10 | 11 | class TestRaiseTypeError(unittest.TestCase): 12 | 13 | def test_good_dim_dict(self): 14 | dim_dict = {} 15 | success, msg = testing.validate_dim_dict(3, dim_dict) 16 | self.assertTrue(success) 17 | 18 | def test_good_bad_dim_dict(self): 19 | dim_dict = {'dist_type': 'b'} 20 | with self.assertRaises(TypeError): 21 | testing.validate_dim_dict(3, dim_dict) 22 | 23 | def test_good_dim_data(self): 24 | dim_data = ({}, {}, {}) 25 | success, msg = testing.validate_dim_data(dim_data) 26 | self.assertTrue(success) 27 | 28 | def test_good_bad_dim_data(self): 29 | dim_data = ({'dist_type': 'b'}, {}, {}) 30 | with self.assertRaises(TypeError): 31 | testing.validate_dim_data(dim_data) 32 | 33 | def test_good_distbuffer(self): 34 | dim_data = ({},) 35 | distbuffer = dict(__version__='0.10.0', 36 | buffer=bytearray([1,2,3,4]), 37 | dim_data=dim_data) 38 | success, msg = testing.validate_distbuffer(distbuffer) 39 | self.assertTrue(success) 40 | 41 | def test_bad_distbuffer(self): 42 | dim_data = ({},) 43 | distbuffer = dict(__venison__='0.10.0', 44 | biffer=bytearray([1,2,3,4]), 45 | dim_doodle=dim_data) 46 | with self.assertRaises(TypeError): 47 | testing.validate_distbuffer(distbuffer) 48 | 49 | 50 | if __name__ == '__main__': 51 | unittest.main(verbosity=2) 52 | -------------------------------------------------------------------------------- /distarray/tests/test_utils.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # --------------------------------------------------------------------------- 3 | # Copyright (C) 2008-2014, IPython Development Team and Enthought, Inc. 4 | # Distributed under the terms of the BSD License. See COPYING.rst. 5 | # --------------------------------------------------------------------------- 6 | 7 | import unittest 8 | 9 | from numpy import arange 10 | from numpy.testing import assert_array_equal 11 | 12 | from distarray import utils 13 | from distarray.globalapi.ipython_utils import IPythonClient 14 | from distarray.mpionly_utils import is_solo_mpi_process 15 | 16 | 17 | class TestMultPartitions(unittest.TestCase): 18 | """ 19 | Test the multiplicative parition code. 20 | """ 21 | 22 | def test_mult_partitions(self): 23 | self.assertEqual(utils.mult_partitions(1, 2), [(1, 1)]) 24 | self.assertEqual(utils.mult_partitions(2, 2), [(1, 2)]) 25 | self.assertEqual(utils.mult_partitions(1, 7), [(1,) * 7]) 26 | self.assertEqual(utils.mult_partitions(7, 2), [(1, 7)]) 27 | self.assertEqual(utils.mult_partitions(7, 3), [(1, 1, 7)]) 28 | self.assertEqual(utils.mult_partitions(16, 4), [(1, 1, 1, 16), 29 | (1, 1, 2, 8), 30 | (1, 1, 4, 4), 31 | (1, 2, 2, 4), 32 | (2, 2, 2, 2)]) 33 | self.assertEqual(utils.mult_partitions(6, 3), [(1, 1, 6), (1, 2, 3)]) 34 | 35 | 36 | class TestSliceIntersection(unittest.TestCase): 37 | 38 | def test_containment(self): 39 | arr = arange(20) 40 | slc = utils.slice_intersection(slice(1,10), slice(2, 4)) 41 | assert_array_equal(arr[slc], arr[slice(2, 4, 1)]) 42 | 43 | def test_overlapping(self): 44 | arr = arange(20) 45 | slc = utils.slice_intersection(slice(1,10), slice(4, 15)) 46 | assert_array_equal(arr[slc], arr[slice(4, 10)]) 47 | 48 | def test_disjoint(self): 49 | arr = arange(20) 50 | slc = utils.slice_intersection(slice(1,10), slice(11, 15)) 51 | assert_array_equal(arr[slc], arr[slice(11, 10)]) 52 | 53 | 54 | class TestAllEqual(unittest.TestCase): 55 | 56 | def test_all_equal_false(self): 57 | self.assertFalse(utils.all_equal([1, 2, 3, 4, 5])) 58 | 59 | def test_all_equal_true(self): 60 | self.assertTrue(utils.all_equal([7, 7, 7, 7, 7])) 61 | 62 | def test_all_equal_vacuously_true(self): 63 | self.assertTrue(utils.all_equal([])) 64 | self.assertTrue(utils.all_equal([99])) 65 | 66 | 67 | class TestHasExactlyOne(unittest.TestCase): 68 | 69 | def test_has_exactly_one_true(self): 70 | iterable = [None, None, None, 55, None] 71 | self.assertTrue(utils.has_exactly_one(iterable)) 72 | 73 | def test_has_exactly_one_all_none(self): 74 | iterable = [None, None, None, None, None] 75 | self.assertFalse(utils.has_exactly_one(iterable)) 76 | 77 | def test_has_exactly_one_multi_non_none(self): 78 | iterable = [None, 5, 'abc', None, None] 79 | self.assertFalse(utils.has_exactly_one(iterable)) 80 | 81 | 82 | if __name__ == '__main__': 83 | unittest.main(verbosity=2) 84 | -------------------------------------------------------------------------------- /docs/sphinx/requirements.txt: -------------------------------------------------------------------------------- 1 | mock 2 | sphinx 3 | sphinxcontrib-programoutput 4 | -------------------------------------------------------------------------------- /docs/sphinx/source/blurb.rst: -------------------------------------------------------------------------------- 1 | *Think globally, act locally.* 2 | 3 | DistArray provides general multidimensional NumPy-like distributed arrays to 4 | Python. It intends to bring the strengths of NumPy to data-parallel 5 | high-performance computing. DistArray has a similar API to `NumPy`_. 6 | 7 | DistArray is ready for real-world testing and deployment; however, the project 8 | is still evolving rapidly, and we appreciate continued input from the 9 | scientific-Python community. 10 | 11 | DistArray is for users who 12 | 13 | * know and love Python and NumPy, 14 | * want to scale NumPy to larger distributed datasets, 15 | * want to interactively play with distributed data but also 16 | * want to run batch-oriented distributed programs; 17 | * want an easier way to drive and coordinate existing MPI-based codes, 18 | * have a lot of data that may already be distributed, 19 | * want a global view ("think globally") with local control ("act locally"), 20 | * need to tap into existing parallel libraries like Trilinos, PETSc, or 21 | Elemental, 22 | * want the interactivity of IPython and the performance of MPI. 23 | 24 | DistArray is designed to work with other packages that implement the 25 | `Distributed Array Protocol`_. 26 | 27 | .. _Distributed Array Protocol: http://distributed-array-protocol.readthedocs.org 28 | .. _NumPy: http://www.numpy.org 29 | -------------------------------------------------------------------------------- /docs/sphinx/source/build-the-docs.rst: -------------------------------------------------------------------------------- 1 | Building the docs 2 | ----------------- 3 | 4 | Dependencies to build the documentation: 5 | 6 | * Sphinx >= 1.3 7 | * sphinxcontrib.programoutput 8 | 9 | If you have the dependencies listed above, and you want to build the 10 | documentation (also available at http://distarray.readthedocs.org), navigate to 11 | the ``docs/sphinx`` subdirectory of the DistArray source and use the Makefile there. 12 | 13 | For example, to build the html documentation:: 14 | 15 | make html 16 | 17 | from the ``docs`` directory. 18 | 19 | Try:: 20 | 21 | make help 22 | 23 | for more options. 24 | -------------------------------------------------------------------------------- /docs/sphinx/source/contact-us.rst: -------------------------------------------------------------------------------- 1 | Contact Us 2 | ---------- 3 | 4 | If you have questions or would like to contribute, contact us 5 | 6 | * on the DistArray mailing list: distarray@googlegroups.com, or 7 | * through the DistArray GitHub repo: https://github.com/enthought/distarray 8 | (for bug reports and pull requests). 9 | -------------------------------------------------------------------------------- /docs/sphinx/source/distarray.apps.rst: -------------------------------------------------------------------------------- 1 | apps Package 2 | ============ 3 | 4 | :mod:`apps` Package 5 | ------------------- 6 | 7 | .. automodule:: distarray.apps.__init__ 8 | :members: 9 | :undoc-members: 10 | :show-inheritance: 11 | 12 | :mod:`dacluster` Module 13 | ----------------------- 14 | 15 | .. automodule:: distarray.apps.dacluster 16 | :members: 17 | :undoc-members: 18 | :show-inheritance: 19 | 20 | .. program-output:: python -m distarray.apps.dacluster -h 21 | 22 | :mod:`engine` Module 23 | -------------------- 24 | 25 | .. automodule:: distarray.apps.engine 26 | :members: 27 | :undoc-members: 28 | :show-inheritance: 29 | 30 | .. program-output:: python -m distarray.apps.engine -h 31 | -------------------------------------------------------------------------------- /docs/sphinx/source/distarray.globalapi.rst: -------------------------------------------------------------------------------- 1 | globalapi Package 2 | ================= 3 | 4 | :mod:`globalapi` Package 5 | ------------------------ 6 | 7 | .. automodule:: distarray.globalapi.__init__ 8 | :members: 9 | :undoc-members: 10 | :show-inheritance: 11 | 12 | :mod:`context` Module 13 | --------------------- 14 | 15 | .. automodule:: distarray.globalapi.context 16 | :members: 17 | :undoc-members: 18 | :show-inheritance: 19 | 20 | :mod:`distarray` Module 21 | ----------------------- 22 | 23 | .. automodule:: distarray.globalapi.distarray 24 | :members: 25 | :undoc-members: 26 | :show-inheritance: 27 | 28 | :mod:`functions` Module 29 | ----------------------- 30 | 31 | .. automodule:: distarray.globalapi.functions 32 | :members: 33 | :undoc-members: 34 | :show-inheritance: 35 | 36 | :mod:`ipython_cleanup` Module 37 | ----------------------------- 38 | 39 | .. automodule:: distarray.globalapi.ipython_cleanup 40 | :members: 41 | :undoc-members: 42 | :show-inheritance: 43 | 44 | :mod:`ipython_utils` Module 45 | --------------------------- 46 | 47 | .. automodule:: distarray.globalapi.ipython_utils 48 | :members: 49 | :undoc-members: 50 | :show-inheritance: 51 | 52 | :mod:`maps` Module 53 | ------------------ 54 | 55 | .. automodule:: distarray.globalapi.maps 56 | :members: 57 | :undoc-members: 58 | :show-inheritance: 59 | 60 | :mod:`random` Module 61 | -------------------- 62 | 63 | .. automodule:: distarray.globalapi.random 64 | :members: 65 | :undoc-members: 66 | :show-inheritance: 67 | -------------------------------------------------------------------------------- /docs/sphinx/source/distarray.localapi.rst: -------------------------------------------------------------------------------- 1 | localapi Package 2 | ================ 3 | 4 | :mod:`localapi` Package 5 | ----------------------- 6 | 7 | .. automodule:: distarray.localapi.__init__ 8 | :members: 9 | :undoc-members: 10 | :show-inheritance: 11 | 12 | :mod:`construct` Module 13 | ----------------------- 14 | 15 | .. automodule:: distarray.localapi.construct 16 | :members: 17 | :undoc-members: 18 | :show-inheritance: 19 | 20 | :mod:`error` Module 21 | ------------------- 22 | 23 | .. automodule:: distarray.localapi.error 24 | :members: 25 | :undoc-members: 26 | :show-inheritance: 27 | 28 | :mod:`format` Module 29 | -------------------- 30 | 31 | .. automodule:: distarray.localapi.format 32 | :members: 33 | :undoc-members: 34 | :show-inheritance: 35 | 36 | :mod:`localarray` Module 37 | ------------------------ 38 | 39 | .. automodule:: distarray.localapi.localarray 40 | :members: 41 | :undoc-members: 42 | :show-inheritance: 43 | 44 | :mod:`maps` Module 45 | ------------------ 46 | 47 | .. automodule:: distarray.localapi.maps 48 | :members: 49 | :undoc-members: 50 | :show-inheritance: 51 | 52 | :mod:`mpiutils` Module 53 | ---------------------- 54 | 55 | .. automodule:: distarray.localapi.mpiutils 56 | :members: 57 | :undoc-members: 58 | :show-inheritance: 59 | 60 | :mod:`proxyize` Module 61 | ---------------------- 62 | 63 | .. automodule:: distarray.localapi.proxyize 64 | :members: 65 | :undoc-members: 66 | :show-inheritance: 67 | 68 | :mod:`random` Module 69 | -------------------- 70 | 71 | .. automodule:: distarray.localapi.random 72 | :members: 73 | :undoc-members: 74 | :show-inheritance: 75 | -------------------------------------------------------------------------------- /docs/sphinx/source/distarray.plotting.rst: -------------------------------------------------------------------------------- 1 | plotting Package 2 | ================ 3 | 4 | :mod:`plotting` Package 5 | ----------------------- 6 | 7 | .. automodule:: distarray.plotting.__init__ 8 | :members: 9 | :undoc-members: 10 | :show-inheritance: 11 | 12 | :mod:`plotting` Module 13 | ---------------------- 14 | 15 | .. automodule:: distarray.plotting.plotting 16 | :members: 17 | :undoc-members: 18 | :show-inheritance: 19 | -------------------------------------------------------------------------------- /docs/sphinx/source/distarray.rst: -------------------------------------------------------------------------------- 1 | DistArray API Reference 2 | ======================= 3 | 4 | :mod:`distarray` Package 5 | ------------------------ 6 | 7 | .. automodule:: distarray.__init__ 8 | :members: 9 | :undoc-members: 10 | :show-inheritance: 11 | 12 | :mod:`__version__` Module 13 | ------------------------- 14 | 15 | .. automodule:: distarray.__version__ 16 | :members: 17 | :special-members: 18 | :undoc-members: 19 | :show-inheritance: 20 | 21 | :mod:`error` Module 22 | ------------------- 23 | 24 | .. automodule:: distarray.error 25 | :members: 26 | :undoc-members: 27 | :show-inheritance: 28 | 29 | :mod:`metadata_utils` Module 30 | ---------------------------- 31 | 32 | .. automodule:: distarray.metadata_utils 33 | :members: 34 | :undoc-members: 35 | :show-inheritance: 36 | 37 | :mod:`mpi_engine` Module 38 | ------------------------ 39 | 40 | .. automodule:: distarray.mpi_engine 41 | :members: 42 | :undoc-members: 43 | :show-inheritance: 44 | 45 | :mod:`mpionly_utils` Module 46 | --------------------------- 47 | 48 | .. automodule:: distarray.mpionly_utils 49 | :members: 50 | :undoc-members: 51 | :show-inheritance: 52 | 53 | :mod:`run_tests` Module 54 | ---------------------------- 55 | 56 | .. automodule:: distarray.run_tests 57 | :members: 58 | :undoc-members: 59 | :show-inheritance: 60 | 61 | :mod:`testing` Module 62 | --------------------- 63 | 64 | .. automodule:: distarray.testing 65 | :members: 66 | :undoc-members: 67 | :show-inheritance: 68 | 69 | :mod:`utils` Module 70 | ------------------- 71 | 72 | .. automodule:: distarray.utils 73 | :members: 74 | :undoc-members: 75 | :show-inheritance: 76 | 77 | Subpackages 78 | ----------- 79 | 80 | .. toctree:: 81 | 82 | distarray.apps 83 | distarray.globalapi 84 | distarray.localapi 85 | distarray.plotting 86 | 87 | -------------------------------------------------------------------------------- /docs/sphinx/source/getting-started.rst: -------------------------------------------------------------------------------- 1 | Getting Started 2 | --------------- 3 | 4 | To see some examples of what DistArray can do, check out our IPython notebooks 5 | on nbviewer (also in the ``examples`` directory of the DistArray source). 6 | 7 | * `DistArray Features `_ 8 | * `Seismic Volume `_ 9 | * `Julia Set `_ 10 | * `Gaussian Elimination `_ 11 | -------------------------------------------------------------------------------- /docs/sphinx/source/hdf5-notes.rst: -------------------------------------------------------------------------------- 1 | Building HDF5 and h5py for DistArray 2 | ==================================== 3 | 4 | If you want to use DistArray's parallel IO capabilities on HDF5 files, 5 | parallel-enabled HDF5 and h5py installations are required. Unfortunately, 6 | installing these can be somewhat of a pain. 7 | 8 | Update 2015-10-05 9 | ----------------- 10 | 11 | The "Original Notes" below are pretty old at this point. Recently I have had 12 | success installing a parallel-enabled HDF5 (1.8.15) using Homebrew on OS X:: 13 | 14 | $ brew install hdf5 --with-mpi 15 | 16 | The instructions for building ``h5py`` on top of a parallel hdf5 have also 17 | changed, but are available 18 | `here `_. 19 | 20 | 21 | Original Notes 22 | -------------- 23 | 24 | These are notes from trying to build HDF5 1.8.12 and h5py 2.2.1 against mpi4py 25 | 1.3 and openmpi-1.6.5 on OS X 10.8.5. 26 | 27 | HDF5 28 | ---- 29 | 30 | Download the HDF5 source (1.8.12) and configure it with parallel support. From 31 | the source directory:: 32 | 33 | $ CFLAGS=-O0 CC=/Users/robertgrant/localroot/bin/mpicc ./configure --enable-shared --enable-parallel --prefix=/Users/robertgrant/localroot 34 | 35 | The CFLAGS setting is to get around a known problem with the tests on OS X 10.8 36 | (http://www.hdfgroup.org/HDF5/release/known_problems/). 37 | 38 | Build it:: 39 | 40 | $ make 41 | 42 | Test it:: 43 | 44 | $ make check 45 | 46 | This produced some errors related to ph5diff, which the website claims are "not 47 | valid errors", so I ignored them 48 | (http://www.hdfgroup.org/HDF5/faq/parallel.html#ph5difftest). 49 | 50 | Install HDF5:: 51 | 52 | $ make install 53 | 54 | h5py 55 | ---- 56 | 57 | Build h5py against this version of HDF5. Without setting ``HDF5_DIR``, on my 58 | system the build found Canopy's serial version of HDF5. In the h5py source 59 | directory:: 60 | 61 | $ HDF5_DIR=/Users/robertgrant/localroot/ CC=mpicc python setup.py build --mpi 62 | 63 | This gives me an error about "MPI Message" addressed here:: 64 | 65 | https://github.com/h5py/h5py/issues/401 66 | 67 | After patching api_compat.h as suggested, it builds. One could also use the 68 | ``master`` version of h5py from GitHub instead of the latest release. 69 | 70 | Run the tests:: 71 | 72 | $ python setup.py test 73 | 74 | and install h5py:: 75 | 76 | $ python setup.py install 77 | 78 | You should now be able to run the example code listed here:: 79 | 80 | http://docs.h5py.org/en/latest/mpi.html#using-parallel-hdf5-from-h5py 81 | -------------------------------------------------------------------------------- /docs/sphinx/source/history.rst: -------------------------------------------------------------------------------- 1 | History 2 | ------- 3 | 4 | DistArray was started by Brian Granger in 2008 and is currently being developed 5 | by Enthought in partnership with Bill Spotz from Sandia's (Py)Trilinos project 6 | and Brian Granger and Min RK from the IPython project. 7 | -------------------------------------------------------------------------------- /docs/sphinx/source/index.rst: -------------------------------------------------------------------------------- 1 | .. DistArray documentation master file, created by 2 | sphinx-quickstart on Fri Jan 31 01:11:34 2014. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | 7 | DistArray |version| 8 | =================== 9 | 10 | .. include:: blurb.rst 11 | .. include:: getting-started.rst 12 | .. include:: overview.rst 13 | .. include:: installation.rst 14 | .. include:: build-the-docs.rst 15 | .. include:: history.rst 16 | .. include:: contact-us.rst 17 | 18 | 19 | Other Documentation 20 | ------------------- 21 | 22 | .. toctree:: 23 | :maxdepth: 1 24 | 25 | DistArray API Reference 26 | The Distributed Array Protocol 27 | Notes on building HDF5 and h5py 28 | Notes on building environment-modules 29 | Licensing for bundled `six` module (Python 2 / 3 compatibility) 30 | 31 | 32 | Release Notes 33 | ------------- 34 | .. toctree:: 35 | :maxdepth: 1 36 | :glob: 37 | 38 | releases/* 39 | 40 | 41 | Indices and tables 42 | ================== 43 | 44 | * :ref:`genindex` 45 | * :ref:`modindex` 46 | * :ref:`search` 47 | -------------------------------------------------------------------------------- /docs/sphinx/source/installation.rst: -------------------------------------------------------------------------------- 1 | Installation 2 | ------------ 3 | 4 | DistArray requires the following Python libraries: 5 | 6 | * `numpy`_, 7 | * `ipyparallel`_, and 8 | * `mpi4py`_. 9 | 10 | .. _numpy: http://www.numpy.org 11 | .. _ipyparallel: https://github.com/ipython/ipyparallel 12 | .. _mpi4py: http://mpi4py.scipy.org 13 | 14 | Optionally, DistArray can make use of: 15 | 16 | * `h5py`_ built against a parallel-enabled build of HDF5 (for HDF5 IO), and 17 | * `matplotlib`_ (for making plots of DistArray distributions). 18 | 19 | .. _h5py: http://www.h5py.org/ 20 | .. _matplotlib: http://matplotlib.org/ 21 | 22 | If you have the above, you should be able to install DistArray with:: 23 | 24 | python setup.py install 25 | 26 | or:: 27 | 28 | pip install distarray 29 | 30 | 31 | Experimental quickstart scripts 32 | ------------------------------- 33 | 34 | Alternatively, we have experimental installation scripts in the ``quickstart`` 35 | directory of the root of this source tree. Given a Canopy or Anaconda 36 | installation and a couple of other prerequisites, these scripts attempt to 37 | install DistArray and its dependencies for you. See the readme files in that 38 | directory for more information. 39 | 40 | 41 | Testing Your Installation 42 | ------------------------- 43 | 44 | To test your installation, you will first need to start an IPython.parallel 45 | cluster with MPI enabled. The easist way is to use the ``dacluster`` command 46 | that comes with DistArray:: 47 | 48 | dacluster start 49 | 50 | See ``dacluster``'s help for more:: 51 | 52 | dacluster --help 53 | 54 | You should then be able to run all the tests from the DistArray source 55 | directory with:: 56 | 57 | make test 58 | 59 | If you've installed DistArray with ``python setup.py develop``, you should be 60 | able to run the tests from anywhere with:: 61 | 62 | python -m distarray.run_tests 63 | -------------------------------------------------------------------------------- /docs/sphinx/source/overview.rst: -------------------------------------------------------------------------------- 1 | Overview 2 | -------- 3 | 4 | NumPy is at the foundation of the scientific Python stack for good reason: 5 | NumPy arrays are easy to use, they have many powerful features like ufuncs, 6 | slicing, and broadcasting, and they work easily with external libraries. 7 | 8 | As data sets grow and parallel hardware becomes more widely available, 9 | wouldn't it be great if NumPy easily supported parallel execution, without 10 | losing its nice interface in a miasma of low-level parallel coordination? 11 | What would that look like? 12 | 13 | What we want is transparent distribution of NumPy arrays over the CPU, 14 | cluster, and supercomputer. We want to interact with distributed NumPy arrays 15 | the way we think about them and get the benefit of all that parallelism. We 16 | also want to be able to drop down a level to control what's going on at the 17 | data-local level when performance demands it. 18 | 19 | Such a NumPy opens doors to providing a high-level NumPy-like interface to 20 | distributed libraries like Trilinos, PETSc, Global Arrays, Elemental, and 21 | ScaLAPACK, among others. 22 | 23 | All this coordination has overhead and is at risk of becoming a performance 24 | bottleneck. This NumPy will need a way to allow direct execution at a 25 | data-local level. We will also need a way to communicate directly between 26 | local processes when needed, rather than doing everything at a global level. 27 | 28 | This distributed NumPy should be a good citizen and work easily with regular 29 | NumPy arrays, with MPI, with IPython parallel, and with external distributed 30 | algorithms. 31 | 32 | DistArray is our vision of what distributed NumPy can be. It brings the best 33 | parts of NumPy to data-parallel computing. We want to *think globally* about 34 | our arrays, interacting with them as if they are just really big NumPy arrays, 35 | all the while *acting locally* on them for performance and control. 36 | -------------------------------------------------------------------------------- /docs/sphinx/source/six-license.rst: -------------------------------------------------------------------------------- 1 | Licence for `six.py` version 1.5.2 2 | ---------------------------------- 3 | 4 | Copyright (c) 2010-2014 Benjamin Peterson 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/talks/2014-02-03-ams/Enthought_distarray.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enthought/distarray/0e014e4d08e6745f5028a53132a424f909ca354e/docs/talks/2014-02-03-ams/Enthought_distarray.pdf -------------------------------------------------------------------------------- /docs/talks/2014-06-apug/2014-06-apug.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enthought/distarray/0e014e4d08e6745f5028a53132a424f909ca354e/docs/talks/2014-06-apug/2014-06-apug.pdf -------------------------------------------------------------------------------- /docs/talks/2014-06-apug/custom.css: -------------------------------------------------------------------------------- 1 | /* make the default font-size bigger in slides mode */ 2 | 3 | .reveal { 4 | font-size: 250%; 5 | } 6 | -------------------------------------------------------------------------------- /docs/talks/2014-07-10-scipy-lightning/scipy-2014-lightning.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enthought/distarray/0e014e4d08e6745f5028a53132a424f909ca354e/docs/talks/2014-07-10-scipy-lightning/scipy-2014-lightning.pdf -------------------------------------------------------------------------------- /docs/talks/2015-04-12-pycon/2015-04-12-pycon-poster.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enthought/distarray/0e014e4d08e6745f5028a53132a424f909ca354e/docs/talks/2015-04-12-pycon/2015-04-12-pycon-poster.pdf -------------------------------------------------------------------------------- /docs/talks/2015-07-08-scipy/2015-07-08-scipy.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enthought/distarray/0e014e4d08e6745f5028a53132a424f909ca354e/docs/talks/2015-07-08-scipy/2015-07-08-scipy.pdf -------------------------------------------------------------------------------- /docs/www/README.rst: -------------------------------------------------------------------------------- 1 | DistArray Website 2 | ================= 3 | 4 | To build, install `pelican`_, with ``pip`` and try:: 5 | 6 | make html 7 | 8 | You can then see the generated website locally by doing:: 9 | 10 | make serve 11 | 12 | and checking out ``localhost:8000`` in a web browser. 13 | 14 | To deploy the website to our Github-hosted gh-pages, install `ghp-import`_ with 15 | ``pip`` and try:: 16 | 17 | make github 18 | 19 | To add content, add ``.rst`` or ``.md`` files to the directory ``www/content``. 20 | Check out the other files there for examples (as well as the `pelican`_ 21 | documentation). 22 | 23 | If you want to change major features or styling of the site, you can change 24 | settings in ``pelicanconf.py``. We're currently using the 25 | ``pelican-bootstrap3`` theme for Pelican, and the ``flatly`` theme for 26 | Bootstrap. The easiest way to change the look of the site is to choose another 27 | Bootstrap theme from `bootswatch`_, but there are also other `pelican themes`_ 28 | available. 29 | 30 | 31 | .. _pelican: http://blog.getpelican.com/ 32 | .. _pelican themes: https://github.com/getpelican/pelican-themes``. 33 | .. _bootswatch: http://bootswatch.com/ 34 | .. _ghp-import: https://pypi.python.org/pypi/ghp-import 35 | -------------------------------------------------------------------------------- /docs/www/cache/ArticlesGenerator-Readers: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enthought/distarray/0e014e4d08e6745f5028a53132a424f909ca354e/docs/www/cache/ArticlesGenerator-Readers -------------------------------------------------------------------------------- /docs/www/cache/PagesGenerator-Readers: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enthought/distarray/0e014e4d08e6745f5028a53132a424f909ca354e/docs/www/cache/PagesGenerator-Readers -------------------------------------------------------------------------------- /docs/www/content/images/distarray-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enthought/distarray/0e014e4d08e6745f5028a53132a424f909ca354e/docs/www/content/images/distarray-logo.png -------------------------------------------------------------------------------- /docs/www/content/pages/contact.rst: -------------------------------------------------------------------------------- 1 | :title: Contact Us 2 | 3 | .. include:: ../../../sphinx/source/contact-us.rst 4 | :start-line: 3 5 | -------------------------------------------------------------------------------- /docs/www/content/pages/features.md: -------------------------------------------------------------------------------- 1 | Title: Features 2 | 3 | {% notebook ../../../../examples/features.ipynb cells[1:] %} 4 | -------------------------------------------------------------------------------- /docs/www/content/pages/home.rst: -------------------------------------------------------------------------------- 1 | :title: DistArray 2 | :url: 3 | :save_as: index.html 4 | 5 | .. include:: ../../../sphinx/source/blurb.rst 6 | .. include:: ../../../sphinx/source/getting-started.rst 7 | .. include:: ../../../sphinx/source/overview.rst 8 | .. include:: ../../../sphinx/source/installation.rst 9 | .. include:: ../../../sphinx/source/history.rst 10 | -------------------------------------------------------------------------------- /docs/www/content/release-notes/release-0-2-0.rst: -------------------------------------------------------------------------------- 1 | :date: 2014-04-14 2 | :category: Release Notes 3 | :tags: releases 4 | 5 | .. include:: ../../../sphinx/source/releases/release-0.2.rst 6 | -------------------------------------------------------------------------------- /docs/www/content/release-notes/release-0-3-0.rst: -------------------------------------------------------------------------------- 1 | :date: 2014-06-04 2 | :category: Release Notes 3 | :tags: releases 4 | 5 | .. include:: ../../../sphinx/source/releases/release-0.3.rst 6 | -------------------------------------------------------------------------------- /docs/www/content/release-notes/release-0-4-0.rst: -------------------------------------------------------------------------------- 1 | :date: 2014-07-07 2 | :category: Release Notes 3 | :tags: releases 4 | 5 | .. include:: ../../../sphinx/source/releases/release-0.4.rst 6 | -------------------------------------------------------------------------------- /docs/www/content/release-notes/release-0-5-0.rst: -------------------------------------------------------------------------------- 1 | :date: 2014-08-03 2 | :category: Release Notes 3 | :tags: releases 4 | 5 | .. include:: ../../../sphinx/source/releases/release-0.5.rst 6 | -------------------------------------------------------------------------------- /docs/www/content/release-notes/release-0-6-0.rst: -------------------------------------------------------------------------------- 1 | :date: 2015-10-15 2 | :category: Release Notes 3 | :tags: releases 4 | 5 | .. include:: ../../../sphinx/source/releases/release-0.6.rst 6 | -------------------------------------------------------------------------------- /docs/www/content/talks/2009-03-05-siam-granger.rst: -------------------------------------------------------------------------------- 1 | :date: 2009-03-05 2 | :category: Talks 3 | :tags: talks 4 | 5 | Early DistArray talk at SIAM CSE09 6 | ================================== 7 | 8 | In 2009, Brian Granger gave a talk on a early version of DistArray. 9 | 10 | * `SIAM site`_ 11 | * `SIAM abstract` 12 | * Description at the `IPython website`_ 13 | * `Slides`_ 14 | 15 | .. _IPython website: http://ipython.org/presentation.html#id7 16 | .. _Slides: http://ipython.scipy.org/talks/0903_siamcse09_ipython_dist_bgranger.pdf 17 | .. _SIAM site: http://www.siam.org/meetings/cse09/ 18 | .. _SIAM abstract: http://meetings.siam.org/sess/dsp_talk.cfm?p=28752 19 | -------------------------------------------------------------------------------- /docs/www/content/talks/2014-02-03-ams.rst: -------------------------------------------------------------------------------- 1 | :date: 2014-02-03 2 | :category: Talks 3 | :tags: talks 4 | 5 | DistArray at AMS 6 | ================ 7 | 8 | Jonathan Rocher presented DistArray at meeting of the American Meteorological 9 | Society in February 2014. 10 | 11 | * `AMS site`_ 12 | * `Recorded presentation`_ 13 | * `Slides`_ 14 | 15 | .. _Slides: https://github.com/enthought/distarray/blob/master/docs/talks/2014-02-03-ams/Enthought_distarray.pdf?raw=true 16 | .. _AMS site: https://ams.confex.com/ams/94Annual/webprogram/Paper242484.html 17 | .. _Recorded presentation: https://ams.confex.com/ams/94Annual/videogateway.cgi/id/26661?recordingid=26661 18 | -------------------------------------------------------------------------------- /docs/www/content/talks/2014-02-16-apug-lightning-talk.rst: -------------------------------------------------------------------------------- 1 | :date: 2014-02-16 2 | :category: Talks 3 | :tags: talks 4 | 5 | APUG Lightning Talk 6 | =================== 7 | 8 | Blake Griffith gave a DistArray lightning talk to the Austin Python User's 9 | group in February 2014. Check it out! 10 | 11 | * `Blog post`_ 12 | * `Slides`_ 13 | 14 | .. _Blog post: http://cwl.cx/posts/distarray-lightning-talk-slides.html 15 | .. _Slides: http://cwl.cx/distarray.slides.html 16 | -------------------------------------------------------------------------------- /docs/www/content/talks/2014-06-11-apug.rst: -------------------------------------------------------------------------------- 1 | :date: 2014-06-11 2 | :category: Talks 3 | :tags: talks 4 | 5 | DistArray at APUG 6 | ================= 7 | 8 | Robert Grant presented DistArray to the Austin Python User's group in June 9 | 2014. 10 | 11 | * `APUG Announcement`_ 12 | * `Slides`_ 13 | * `IPython Notebook`_ 14 | * `Recorded presentation`_ 15 | 16 | .. _APUG Announcement: http://www.meetup.com/austinpython/events/183962712/ 17 | .. _Slides: https://github.com/enthought/distarray/blob/master/docs/talks/2014-06-apug/2014-06-apug.pdf?raw=true 18 | .. _IPython Notebook: http://nbviewer.ipython.org/github/enthought/distarray/blob/master/docs/talks/2014-06-apug/2014-06-apug.ipynb 19 | .. _Recorded presentation: https://youtu.be/gqCJON4Jknw?t=4m14s 20 | -------------------------------------------------------------------------------- /docs/www/content/talks/2014-07-09-scipy-lightning-talk.rst: -------------------------------------------------------------------------------- 1 | :date: 2014-07-09 2 | :category: Talks 3 | :tags: talks 4 | 5 | SciPy 2014 Distributed Array Protocol Lightning Talk 6 | ==================================================== 7 | 8 | Bill Spotz's lightning talk on the Distributed Array Protocol at Scipy 2014. 9 | 10 | * `Recorded presentation`_ 11 | 12 | .. _Recorded presentation: https://youtu.be/JDrhn0-r9Eg?list=PLYx7XA2nY5GfuhCvStxgbynFNrxr3VFog&t=1942 13 | -------------------------------------------------------------------------------- /docs/www/content/talks/2014-07-10-scipy-lightning-talk.rst: -------------------------------------------------------------------------------- 1 | :date: 2014-07-10 2 | :category: Talks 3 | :tags: talks 4 | 5 | SciPy 2014 DistArray Lightning Talk 6 | =================================== 7 | 8 | Check out Kurt Smith's DistArray lightning talk at Scipy 2014! 9 | 10 | * `Recorded presentation`_ 11 | * `Slides`_ 12 | 13 | .. _Recorded presentation: http://youtu.be/ln4nE_EVDCg?t=14m2s 14 | .. _Slides: https://github.com/enthought/distarray/blob/master/docs/talks/2014-07-10-scipy-lightning/scipy-2014-lightning.pdf?raw=true 15 | -------------------------------------------------------------------------------- /docs/www/content/talks/2015-04-12-pycon-poster.rst: -------------------------------------------------------------------------------- 1 | :date: 2015-04-12 2 | :category: Talks 3 | :tags: talks 4 | 5 | PyCon 2015 Poster 6 | ================= 7 | 8 | Kurt Smith presented at DistArray Poster at PyCon 2015 in Montreal. 9 | 10 | Special thanks to Erick Michaud for his help designing the poster! 11 | 12 | * `Poster`_ 13 | 14 | .. _Poster: https://github.com/enthought/distarray/blob/master/docs/talks/2015-04-12-pycon/2015-04-12-pycon-poster.pdf?raw=true 15 | -------------------------------------------------------------------------------- /docs/www/content/talks/2015-07-08-scipy-talk.rst: -------------------------------------------------------------------------------- 1 | :date: 2015-07-08 2 | :category: Talks 3 | :tags: talks 4 | 5 | SciPy 2015 DistArray Talk 6 | ========================= 7 | 8 | Robert Grant gave a DistArray talk at SciPy 2015 in Austin, TX. 9 | 10 | * `Slides`_ 11 | * `Recorded presentation`_ 12 | 13 | .. _Slides: https://github.com/enthought/distarray/raw/master/docs/talks/2015-07-08-scipy/2015-07-08-scipy.pdf?raw=true 14 | .. _Recorded presentation: https://www.youtube.com/watch?v=Dac1pfEn2rE 15 | -------------------------------------------------------------------------------- /docs/www/develop_server.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ## 3 | # This section should match your Makefile 4 | ## 5 | PY=${PY:-python} 6 | PELICAN=${PELICAN:-pelican} 7 | PELICANOPTS= 8 | 9 | BASEDIR=$(pwd) 10 | INPUTDIR=$BASEDIR/content 11 | OUTPUTDIR=$BASEDIR/output 12 | CONFFILE=$BASEDIR/pelicanconf.py 13 | 14 | ### 15 | # Don't change stuff below here unless you are sure 16 | ### 17 | 18 | SRV_PID=$BASEDIR/srv.pid 19 | PELICAN_PID=$BASEDIR/pelican.pid 20 | 21 | function usage(){ 22 | echo "usage: $0 (stop) (start) (restart) [port]" 23 | echo "This starts Pelican in debug and reload mode and then launches" 24 | echo "an HTTP server to help site development. It doesn't read" 25 | echo "your Pelican settings, so if you edit any paths in your Makefile" 26 | echo "you will need to edit your settings as well." 27 | exit 3 28 | } 29 | 30 | function alive() { 31 | kill -0 $1 >/dev/null 2>&1 32 | } 33 | 34 | function shut_down(){ 35 | PID=$(cat $SRV_PID) 36 | if [[ $? -eq 0 ]]; then 37 | if alive $PID; then 38 | echo "Stopping HTTP server" 39 | kill $PID 40 | else 41 | echo "Stale PID, deleting" 42 | fi 43 | rm $SRV_PID 44 | else 45 | echo "HTTP server PIDFile not found" 46 | fi 47 | 48 | PID=$(cat $PELICAN_PID) 49 | if [[ $? -eq 0 ]]; then 50 | if alive $PID; then 51 | echo "Killing Pelican" 52 | kill $PID 53 | else 54 | echo "Stale PID, deleting" 55 | fi 56 | rm $PELICAN_PID 57 | else 58 | echo "Pelican PIDFile not found" 59 | fi 60 | } 61 | 62 | function start_up(){ 63 | local port=$1 64 | echo "Starting up Pelican and HTTP server" 65 | shift 66 | $PELICAN --debug --autoreload -r $INPUTDIR -o $OUTPUTDIR -s $CONFFILE $PELICANOPTS & 67 | pelican_pid=$! 68 | echo $pelican_pid > $PELICAN_PID 69 | cd $OUTPUTDIR 70 | $PY -m pelican.server $port & 71 | srv_pid=$! 72 | echo $srv_pid > $SRV_PID 73 | cd $BASEDIR 74 | sleep 1 75 | if ! alive $pelican_pid ; then 76 | echo "Pelican didn't start. Is the Pelican package installed?" 77 | return 1 78 | elif ! alive $srv_pid ; then 79 | echo "The HTTP server didn't start. Is there another service using port 8000?" 80 | return 1 81 | fi 82 | echo 'Pelican and HTTP server processes now running in background.' 83 | } 84 | 85 | ### 86 | # MAIN 87 | ### 88 | [[ ($# -eq 0) || ($# -gt 2) ]] && usage 89 | port='' 90 | [[ $# -eq 2 ]] && port=$2 91 | 92 | if [[ $1 == "stop" ]]; then 93 | shut_down 94 | elif [[ $1 == "restart" ]]; then 95 | shut_down 96 | start_up $port 97 | elif [[ $1 == "start" ]]; then 98 | if ! start_up $port; then 99 | shut_down 100 | fi 101 | else 102 | usage 103 | fi 104 | -------------------------------------------------------------------------------- /docs/www/fabfile.py: -------------------------------------------------------------------------------- 1 | from fabric.api import * 2 | import fabric.contrib.project as project 3 | import os 4 | import sys 5 | import SimpleHTTPServer 6 | import SocketServer 7 | 8 | # Local path configuration (can be absolute or relative to fabfile) 9 | env.deploy_path = 'output' 10 | DEPLOY_PATH = env.deploy_path 11 | 12 | # Remote server configuration 13 | production = 'root@localhost:22' 14 | dest_path = '/var/www' 15 | 16 | # Rackspace Cloud Files configuration settings 17 | env.cloudfiles_username = 'my_rackspace_username' 18 | env.cloudfiles_api_key = 'my_rackspace_api_key' 19 | env.cloudfiles_container = 'my_cloudfiles_container' 20 | 21 | 22 | def clean(): 23 | if os.path.isdir(DEPLOY_PATH): 24 | local('rm -rf {deploy_path}'.format(**env)) 25 | local('mkdir {deploy_path}'.format(**env)) 26 | 27 | def build(): 28 | local('pelican -s pelicanconf.py') 29 | 30 | def rebuild(): 31 | clean() 32 | build() 33 | 34 | def regenerate(): 35 | local('pelican -r -s pelicanconf.py') 36 | 37 | def serve(): 38 | os.chdir(env.deploy_path) 39 | 40 | PORT = 8000 41 | class AddressReuseTCPServer(SocketServer.TCPServer): 42 | allow_reuse_address = True 43 | 44 | server = AddressReuseTCPServer(('', PORT), SimpleHTTPServer.SimpleHTTPRequestHandler) 45 | 46 | sys.stderr.write('Serving on port {0} ...\n'.format(PORT)) 47 | server.serve_forever() 48 | 49 | def reserve(): 50 | build() 51 | serve() 52 | 53 | def preview(): 54 | local('pelican -s publishconf.py') 55 | 56 | def cf_upload(): 57 | rebuild() 58 | local('cd {deploy_path} && ' 59 | 'swift -v -A https://auth.api.rackspacecloud.com/v1.0 ' 60 | '-U {cloudfiles_username} ' 61 | '-K {cloudfiles_api_key} ' 62 | 'upload -c {cloudfiles_container} .'.format(**env)) 63 | 64 | @hosts(production) 65 | def publish(): 66 | local('pelican -s publishconf.py') 67 | project.rsync_project( 68 | remote_dir=dest_path, 69 | exclude=".DS_Store", 70 | local_dir=DEPLOY_PATH.rstrip('/') + '/', 71 | delete=True, 72 | extra_opts='-c', 73 | ) 74 | -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/AUTHORS.md: -------------------------------------------------------------------------------- 1 | The primary author of this project is: 2 | 3 | - [Daan Debie](https://github.com/DandyDev) aka `DandyDev` 4 | 5 | And Pelican Bootstrap 3 would not have been possible without the outstanding contributions of the following fine people: 6 | 7 | - [Magnun Leno](https://github.com/magnunleno) aka `magnunleno` 8 | - [Hilmar Lapp](https://github.com/hlapp) aka `hlapp` 9 | - [mwcz](https://github.com/mwcz) 10 | - [Sebastian Kempken](https://github.com/skempken) aka `skempken` 11 | - [Sagar Behere](https://github.com/sagarbehere) aka `sagarbehere` 12 | - [Romulo Jales](https://github.com/romulojales) aka `romulojales` 13 | - [Mike Abrahamsen](https://github.com/mikeabrahamsen) aka `mikeabrahamsen` 14 | 15 | (For a full contribution overview [look here](https://github.com/DandyDev/pelican-bootstrap3/graphs/contributors). 16 | If you name is missing, please tell me!) -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Guidelines For Contributing 2 | 3 | - Create a new git branch specific to your change, as opposed to making your commits in the master branch. 4 | - Don't put multiple fixes/features in the same branch / pull request. 5 | - Give a proper description in your pull request of what you're trying to fix. 6 | - First line of your commit message should start with present-tense verb, be 50 characters or less, and include the 7 | relevant issue number(s) if applicable. Example: _Ensure proper PLUGIN_PATH behavior. Refs #428._ If the commit completely 8 | fixes an existing issue or request on the tracker, please use `Fixes #585` or `Fix #585` syntax (so the relevant issue is automatically closed 9 | upon PR merge). 10 | - Make sure that new features are configurable using a theme variable (eg. `DISPLAY_CHUCKNORRIS_ADVICE`). Should default to 11 | _False_, so users will not get any surprises when upgrading. 12 | - If you introduce new theme variables, new behaviour or changes from the default Pelican behaviour, make sure you make 13 | mention of it in the [README](README.md) 14 | - Make sure changes do not break backwards compatibility, especially with regards to settings. 15 | - Only changes that stand to benefit a majority of users or use cases are suitable for contributing back to the main repository. For tweaks that are likely specific to your site or likings, try using `CUSTOM_CSS`. 16 | - If doing so would require a CSS selector that isn't supported by the theme, create a patch that adds the necessary CSS selector, not the CSS tweak. 17 | -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/EXAMPLES.md: -------------------------------------------------------------------------------- 1 | # Examples in the wild 2 | 3 | This is a non-exhaustive list of websites that use **pelican-boostrap3** as their theme. It shows the versatility of 4 | the theme (which is one of the perks of using Bootstrap 3). If your website provides a unique take on 5 | **pelican-bootstrap3** and you want your website to be listed here, don't hesitate to ask or make a pull-request! 6 | I reserve the right to refuse websites if they're not unique enough for my tastes or if I find them offensive. 7 | If your website is listed here, but you don't want it to be, let me know and I'll remove it. 8 | 9 | 10 | [DandyDev.net](http://dandydev.net) by [DandyDev](https://github.com/DandyDev) (Main author of pelican-bootstrap3) - Basic pelican-bootstrap3 setup using the _Simplex_ Bootswatch theme. 11 | 12 | [Winlus blog](http://www.heroicdebugging.biz/) by [ingwinlu](https://github.com/ingwinlu) - Customized pelican-bootstrap3 based design using panels. Shows off the `USE_PAGER` setting. 13 | 14 | [Mind Bending](http://mindbending.org/en) by [magnunleno](https://github.com/magnunleno) - Heavily customized design based on pelican-bootstrap3 with lots of stuff added. Some of that stuff was neatly contributed back to pelican-boostrap3. 15 | 16 | [toumorokoshi](http://toumorokoshi.github.io/) by [toumorokoshi](https://github.com/toumorokoshi) - Clean version of pelican-bootstrap3 with a nice profile area added in. 17 | 18 | [Christine Doig](http://chdoig.github.io/) by [chdoig](https://github.com/chdoig) - Barely recognizable anymore as pelican-boostrap3, but it is in fact [based on this theme](http://chdoig.github.io/create-pelican-blog.html). The Twitter widget has been contributed back to pelican-bootstrap3 19 | 20 | [Rebecca Weiss](http://www.rebeccaweiss.info/) by [rjweiss](https://github.com/rjweiss) 21 | 22 | [Theory And Practice](http://theoryandpractice.org/) by [cranmer](https://github.com/cranmer) - Nice customization of the frontpage, using widgets. 23 | 24 | [The official ncf website](http://www.ncf.io/) by [Normation](https://github.com/Normation) 25 | 26 | [Lappland. Inside Out.](http://lappland.io/) by [hlapp](https://github.com/hlapp) 27 | 28 | [Kev009.com](http://kev009.com/wp/) by [kev009](https://github.com/kev009) 29 | 30 | [dave_tucker:blog](http://dtucker.co.uk/) by [dave-tucker](https://github.com/dave-tucker) 31 | 32 | [Dopey's Corner](http://dopey.io/) 33 | 34 | [Toni Mueller](http://www.tonimueller.org/) by [muellert](https://github.com/muellert) 35 | 36 | [Caffeinated Engineering](http://caffeinatedengineering.com/) by [mattyjones](https://github.com/mattyjones) 37 | 38 | [Duncan Murdock](http://www.duncanmurdock.name/) by [damurdock](https://github.com/damurdock) 39 | 40 | [Ryan Gregory James](http://csc.ucdavis.edu/~rgjames/) by [Autoplectic](https://github.com/Autoplectic) 41 | 42 | [JPoser/Blog](http://jposer.net/) by [JPoser](https://github.com/JPoser) 43 | 44 | [Base-Art](http://base-art.net/) by [philn](https://github.com/philn) 45 | 46 | [Jason Antman's Blog](http://blog.jasonantman.com/) by [jantman](https://github.com/jantman) 47 | 48 | [Bryce Boe](http://bryceboe.com/) by [bboe](https://github.com/bboe) 49 | -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Daan Debie 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/screenshot-article.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enthought/distarray/0e014e4d08e6745f5028a53132a424f909ca354e/docs/www/pelican-bootstrap3/screenshot-article.png -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enthought/distarray/0e014e4d08e6745f5028a53132a424f909ca354e/docs/www/pelican-bootstrap3/screenshot.png -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/static/css/pygments/borland.css: -------------------------------------------------------------------------------- 1 | .highlight pre .hll { background-color: #ffffcc } 2 | .highlight pre, .highlighttable pre { background: #ffffff; } 3 | .highlight pre .c { color: #008800; font-style: italic } /* Comment */ 4 | .highlight pre .err { color: #a61717; background-color: #e3d2d2 } /* Error */ 5 | .highlight pre .k { color: #000080; font-weight: bold } /* Keyword */ 6 | .highlight pre .cm { color: #008800; font-style: italic } /* Comment.Multiline */ 7 | .highlight pre .cp { color: #008080 } /* Comment.Preproc */ 8 | .highlight pre .c1 { color: #008800; font-style: italic } /* Comment.Single */ 9 | .highlight pre .cs { color: #008800; font-weight: bold } /* Comment.Special */ 10 | .highlight pre .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ 11 | .highlight pre .ge { font-style: italic } /* Generic.Emph */ 12 | .highlight pre .gr { color: #aa0000 } /* Generic.Error */ 13 | .highlight pre .gh { color: #999999 } /* Generic.Heading */ 14 | .highlight pre .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ 15 | .highlight pre .go { color: #888888 } /* Generic.Output */ 16 | .highlight pre .gp { color: #555555 } /* Generic.Prompt */ 17 | .highlight pre .gs { font-weight: bold } /* Generic.Strong */ 18 | .highlight pre .gu { color: #aaaaaa } /* Generic.Subheading */ 19 | .highlight pre .gt { color: #aa0000 } /* Generic.Traceback */ 20 | .highlight pre .kc { color: #000080; font-weight: bold } /* Keyword.Constant */ 21 | .highlight pre .kd { color: #000080; font-weight: bold } /* Keyword.Declaration */ 22 | .highlight pre .kn { color: #000080; font-weight: bold } /* Keyword.Namespace */ 23 | .highlight pre .kp { color: #000080; font-weight: bold } /* Keyword.Pseudo */ 24 | .highlight pre .kr { color: #000080; font-weight: bold } /* Keyword.Reserved */ 25 | .highlight pre .kt { color: #000080; font-weight: bold } /* Keyword.Type */ 26 | .highlight pre .m { color: #0000FF } /* Literal.Number */ 27 | .highlight pre .s { color: #0000FF } /* Literal.String */ 28 | .highlight pre .na { color: #FF0000 } /* Name.Attribute */ 29 | .highlight pre .nt { color: #000080; font-weight: bold } /* Name.Tag */ 30 | .highlight pre .ow { font-weight: bold } /* Operator.Word */ 31 | .highlight pre .w { color: #bbbbbb } /* Text.Whitespace */ 32 | .highlight pre .mf { color: #0000FF } /* Literal.Number.Float */ 33 | .highlight pre .mh { color: #0000FF } /* Literal.Number.Hex */ 34 | .highlight pre .mi { color: #0000FF } /* Literal.Number.Integer */ 35 | .highlight pre .mo { color: #0000FF } /* Literal.Number.Oct */ 36 | .highlight pre .sb { color: #0000FF } /* Literal.String.Backtick */ 37 | .highlight pre .sc { color: #800080 } /* Literal.String.Char */ 38 | .highlight pre .sd { color: #0000FF } /* Literal.String.Doc */ 39 | .highlight pre .s2 { color: #0000FF } /* Literal.String.Double */ 40 | .highlight pre .se { color: #0000FF } /* Literal.String.Escape */ 41 | .highlight pre .sh { color: #0000FF } /* Literal.String.Heredoc */ 42 | .highlight pre .si { color: #0000FF } /* Literal.String.Interpol */ 43 | .highlight pre .sx { color: #0000FF } /* Literal.String.Other */ 44 | .highlight pre .sr { color: #0000FF } /* Literal.String.Regex */ 45 | .highlight pre .s1 { color: #0000FF } /* Literal.String.Single */ 46 | .highlight pre .ss { color: #0000FF } /* Literal.String.Symbol */ 47 | .highlight pre .il { color: #0000FF } /* Literal.Number.Integer.Long */ 48 | -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/static/css/pygments/bw.css: -------------------------------------------------------------------------------- 1 | .highlight pre .hll { background-color: #ffffcc } 2 | .highlight pre, .highlighttable pre { background: #ffffff; } 3 | .highlight pre .c { font-style: italic } /* Comment */ 4 | .highlight pre .err { border: 1px solid #FF0000 } /* Error */ 5 | .highlight pre .k { font-weight: bold } /* Keyword */ 6 | .highlight pre .cm { font-style: italic } /* Comment.Multiline */ 7 | .highlight pre .c1 { font-style: italic } /* Comment.Single */ 8 | .highlight pre .cs { font-style: italic } /* Comment.Special */ 9 | .highlight pre .ge { font-style: italic } /* Generic.Emph */ 10 | .highlight pre .gh { font-weight: bold } /* Generic.Heading */ 11 | .highlight pre .gp { font-weight: bold } /* Generic.Prompt */ 12 | .highlight pre .gs { font-weight: bold } /* Generic.Strong */ 13 | .highlight pre .gu { font-weight: bold } /* Generic.Subheading */ 14 | .highlight pre .kc { font-weight: bold } /* Keyword.Constant */ 15 | .highlight pre .kd { font-weight: bold } /* Keyword.Declaration */ 16 | .highlight pre .kn { font-weight: bold } /* Keyword.Namespace */ 17 | .highlight pre .kr { font-weight: bold } /* Keyword.Reserved */ 18 | .highlight pre .s { font-style: italic } /* Literal.String */ 19 | .highlight pre .nc { font-weight: bold } /* Name.Class */ 20 | .highlight pre .ni { font-weight: bold } /* Name.Entity */ 21 | .highlight pre .ne { font-weight: bold } /* Name.Exception */ 22 | .highlight pre .nn { font-weight: bold } /* Name.Namespace */ 23 | .highlight pre .nt { font-weight: bold } /* Name.Tag */ 24 | .highlight pre .ow { font-weight: bold } /* Operator.Word */ 25 | .highlight pre .sb { font-style: italic } /* Literal.String.Backtick */ 26 | .highlight pre .sc { font-style: italic } /* Literal.String.Char */ 27 | .highlight pre .sd { font-style: italic } /* Literal.String.Doc */ 28 | .highlight pre .s2 { font-style: italic } /* Literal.String.Double */ 29 | .highlight pre .se { font-weight: bold; font-style: italic } /* Literal.String.Escape */ 30 | .highlight pre .sh { font-style: italic } /* Literal.String.Heredoc */ 31 | .highlight pre .si { font-weight: bold; font-style: italic } /* Literal.String.Interpol */ 32 | .highlight pre .sx { font-style: italic } /* Literal.String.Other */ 33 | .highlight pre .sr { font-style: italic } /* Literal.String.Regex */ 34 | .highlight pre .s1 { font-style: italic } /* Literal.String.Single */ 35 | .highlight pre .ss { font-style: italic } /* Literal.String.Symbol */ 36 | -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/static/css/pygments/vs.css: -------------------------------------------------------------------------------- 1 | .highlight pre .hll { background-color: #ffffcc } 2 | .highlight pre, .highlighttable pre { background: #ffffff; } 3 | .highlight pre .c { color: #008000 } /* Comment */ 4 | .highlight pre .err { border: 1px solid #FF0000 } /* Error */ 5 | .highlight pre .k { color: #0000ff } /* Keyword */ 6 | .highlight pre .cm { color: #008000 } /* Comment.Multiline */ 7 | .highlight pre .cp { color: #0000ff } /* Comment.Preproc */ 8 | .highlight pre .c1 { color: #008000 } /* Comment.Single */ 9 | .highlight pre .cs { color: #008000 } /* Comment.Special */ 10 | .highlight pre .ge { font-style: italic } /* Generic.Emph */ 11 | .highlight pre .gh { font-weight: bold } /* Generic.Heading */ 12 | .highlight pre .gp { font-weight: bold } /* Generic.Prompt */ 13 | .highlight pre .gs { font-weight: bold } /* Generic.Strong */ 14 | .highlight pre .gu { font-weight: bold } /* Generic.Subheading */ 15 | .highlight pre .kc { color: #0000ff } /* Keyword.Constant */ 16 | .highlight pre .kd { color: #0000ff } /* Keyword.Declaration */ 17 | .highlight pre .kn { color: #0000ff } /* Keyword.Namespace */ 18 | .highlight pre .kp { color: #0000ff } /* Keyword.Pseudo */ 19 | .highlight pre .kr { color: #0000ff } /* Keyword.Reserved */ 20 | .highlight pre .kt { color: #2b91af } /* Keyword.Type */ 21 | .highlight pre .s { color: #a31515 } /* Literal.String */ 22 | .highlight pre .nc { color: #2b91af } /* Name.Class */ 23 | .highlight pre .ow { color: #0000ff } /* Operator.Word */ 24 | .highlight pre .sb { color: #a31515 } /* Literal.String.Backtick */ 25 | .highlight pre .sc { color: #a31515 } /* Literal.String.Char */ 26 | .highlight pre .sd { color: #a31515 } /* Literal.String.Doc */ 27 | .highlight pre .s2 { color: #a31515 } /* Literal.String.Double */ 28 | .highlight pre .se { color: #a31515 } /* Literal.String.Escape */ 29 | .highlight pre .sh { color: #a31515 } /* Literal.String.Heredoc */ 30 | .highlight pre .si { color: #a31515 } /* Literal.String.Interpol */ 31 | .highlight pre .sx { color: #a31515 } /* Literal.String.Other */ 32 | .highlight pre .sr { color: #a31515 } /* Literal.String.Regex */ 33 | .highlight pre .s1 { color: #a31515 } /* Literal.String.Single */ 34 | .highlight pre .ss { color: #a31515 } /* Literal.String.Symbol */ 35 | -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/static/css/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 120px; 3 | } 4 | 5 | #sidebar .list-group, #sidebar .list-group-item { 6 | background-color: transparent; 7 | } 8 | 9 | /* for list-groups nested within a list-group-item, reset the bottom margin */ 10 | .list-group-item > .list-group { 11 | margin-bottom: 0px; 12 | } 13 | 14 | /* for list-group-items nested within a list-group-item, reset the bottom 15 | padding of the last item, b/c the containing item has paddimg already 16 | */ 17 | .list-group-item .list-group-item:last-child { 18 | padding-bottom: 0px; 19 | } 20 | 21 | .list-group-item { 22 | border: none; 23 | } 24 | 25 | .tag-0 { 26 | font-size: 16pt; 27 | } 28 | 29 | .tag-1 { 30 | font-size: 13pt; 31 | } 32 | 33 | .tag-2 { 34 | font-size: 10pt; 35 | } 36 | 37 | .tag-3 { 38 | font-size: 8pt; 39 | } 40 | 41 | .tag-4 { 42 | font-size: 6pt; 43 | } 44 | 45 | #sidebar { 46 | padding-top: 0px; 47 | -ms-word-break: break-all; 48 | word-break: break-all; 49 | word-break: break-word; 50 | -webkit-hyphens: auto; 51 | -moz-hyphens: auto; 52 | -ms-hyphens: auto; 53 | hyphens: auto; 54 | } 55 | 56 | #sidebar a { 57 | color: inherit; 58 | } 59 | 60 | .icon-label { 61 | margin-left: 10px; 62 | } 63 | 64 | /* Example for how to control spacing between icon and label in specific 65 | lists in the sidebar. To change, override in your CUSTOM_CSS */ 66 | #sidebar #social i { 67 | margin-right: 3px; 68 | } 69 | 70 | a { 71 | color: #397CC5; 72 | } 73 | 74 | a:hover { 75 | color: #285689; 76 | } 77 | 78 | .entry-content a { 79 | text-decoration: none; 80 | } 81 | 82 | .entry-content a:hover { 83 | text-decoration: none; 84 | border-bottom: 1px solid; 85 | } 86 | 87 | .entry-content img { 88 | max-width: 100%; 89 | height: auto; 90 | } 91 | 92 | .entry-content figcaption, .caption { 93 | font-size: small; 94 | margin-bottom: 2px; 95 | } 96 | 97 | .floatright, .align-right { 98 | float: right; 99 | } 100 | 101 | .floatleft, .align-left { 102 | float: left; 103 | } 104 | 105 | .floatcenter, .align-center { 106 | display: block; 107 | margin-left: auto; 108 | margin-right: auto; 109 | } 110 | 111 | figure.floatright, .align-right { 112 | margin-left: 4px; 113 | } 114 | 115 | figure.floatleft, .align-left { 116 | margin-right: 4px; 117 | } 118 | 119 | figure.floatcenter, .align-center { 120 | margin-bottom: 11px; 121 | } 122 | 123 | .highlighttable pre { 124 | /* Removes bootstrap default margin-bottom */ 125 | margin-bottom: 0px; 126 | } 127 | 128 | .highlighttable { 129 | /* Adds them margin-bottom to highlightable instead of
 */
130 |     margin-bottom: 11px;
131 | }
132 | 
133 | .highlighttable {
134 |     width: 100%;
135 | }
136 | 
137 | #categories ul, #tags ul {
138 |     list-style: none;
139 |     padding: 0;
140 |     margin-left: 0;
141 | }
142 | 
143 | .docutils.footnote td.label {
144 |     display: table-cell;
145 |     font-size: inherit;
146 |     font-weight: inherit;
147 |     line-height: inherit;
148 |     color: inherit;
149 |     text-align: inherit;
150 |     white-space: inherit;
151 |     border-radius: inherit;
152 | }
153 | 
154 | .categories-timestamp {
155 |     color: #AAAAAA;
156 |     font-size: 0.9em;
157 |     margin-right: 10px;
158 | }
159 | 
160 | .tagcloud li {
161 |     padding: 0px;
162 | }
163 | 


--------------------------------------------------------------------------------
/docs/www/pelican-bootstrap3/static/css/typogrify.css:
--------------------------------------------------------------------------------
1 | .caps {font-size:.92em;}
2 | .amp {color:#666; font-size:1.05em;font-family:"Warnock Pro", "Goudy Old Style","Palatino","Book Antiqua",serif; font-style:italic;}    
3 | .dquo {margin-left:-.38em;}
4 | 


--------------------------------------------------------------------------------
/docs/www/pelican-bootstrap3/static/fonts/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/enthought/distarray/0e014e4d08e6745f5028a53132a424f909ca354e/docs/www/pelican-bootstrap3/static/fonts/FontAwesome.otf


--------------------------------------------------------------------------------
/docs/www/pelican-bootstrap3/static/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/enthought/distarray/0e014e4d08e6745f5028a53132a424f909ca354e/docs/www/pelican-bootstrap3/static/fonts/fontawesome-webfont.eot


--------------------------------------------------------------------------------
/docs/www/pelican-bootstrap3/static/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/enthought/distarray/0e014e4d08e6745f5028a53132a424f909ca354e/docs/www/pelican-bootstrap3/static/fonts/fontawesome-webfont.ttf


--------------------------------------------------------------------------------
/docs/www/pelican-bootstrap3/static/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/enthought/distarray/0e014e4d08e6745f5028a53132a424f909ca354e/docs/www/pelican-bootstrap3/static/fonts/fontawesome-webfont.woff


--------------------------------------------------------------------------------
/docs/www/pelican-bootstrap3/static/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/enthought/distarray/0e014e4d08e6745f5028a53132a424f909ca354e/docs/www/pelican-bootstrap3/static/fonts/glyphicons-halflings-regular.eot


--------------------------------------------------------------------------------
/docs/www/pelican-bootstrap3/static/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/enthought/distarray/0e014e4d08e6745f5028a53132a424f909ca354e/docs/www/pelican-bootstrap3/static/fonts/glyphicons-halflings-regular.ttf


--------------------------------------------------------------------------------
/docs/www/pelican-bootstrap3/static/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/enthought/distarray/0e014e4d08e6745f5028a53132a424f909ca354e/docs/www/pelican-bootstrap3/static/fonts/glyphicons-halflings-regular.woff


--------------------------------------------------------------------------------
/docs/www/pelican-bootstrap3/static/js/github.js:
--------------------------------------------------------------------------------
 1 | var github = (function(){
 2 |   function escapeHtml(str) {
 3 |     return $('
').text(str).html(); 4 | } 5 | function render(target, repos){ 6 | var i = 0, fragment = '', t = $(target)[0]; 7 | fragment += '
    '; 8 | 9 | for(i = 0; i < repos.length; i++) { 10 | fragment += '
  • '+repos[i].name+'

    '+escapeHtml(repos[i].description||'')+'

  • '; 11 | } 12 | fragment += '
'; 13 | t.innerHTML = fragment; 14 | } 15 | return { 16 | showRepos: function(options){ 17 | $.ajax({ 18 | url: "https://api.github.com/users/"+options.user+"/repos?callback=?" 19 | , dataType: 'jsonp' 20 | , error: function (err) { $(options.target + ' li.loading').addClass('error').text("Error loading feed"); } 21 | , success: function(data) { 22 | var repos = []; 23 | if (!data || !data.data) { return; } 24 | for (var i = 0; i < data.data.length; i++) { 25 | if (options.skip_forks && data.data[i].fork) { continue; } 26 | repos.push(data.data[i]); 27 | } 28 | repos.sort(function(a, b) { 29 | var aDate = new Date(a.pushed_at).valueOf(), 30 | bDate = new Date(b.pushed_at).valueOf(); 31 | 32 | if (aDate === bDate) { return 0; } 33 | return aDate > bDate ? -1 : 1; 34 | }); 35 | 36 | if (options.count) { repos.splice(options.count); } 37 | render(options.target, repos); 38 | } 39 | }); 40 | } 41 | }; 42 | })(); 43 | -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/static/js/jXHR.js: -------------------------------------------------------------------------------- 1 | // jXHR.js (JSON-P XHR) 2 | // v0.1 (c) Kyle Simpson 3 | // MIT License 4 | 5 | (function(global){ 6 | var SETTIMEOUT = global.setTimeout, // for better compression 7 | doc = global.document, 8 | callback_counter = 0; 9 | 10 | global.jXHR = function() { 11 | var script_url, 12 | script_loaded, 13 | jsonp_callback, 14 | scriptElem, 15 | publicAPI = null; 16 | 17 | function removeScript() { try { scriptElem.parentNode.removeChild(scriptElem); } catch (err) { } } 18 | 19 | function reset() { 20 | script_loaded = false; 21 | script_url = ""; 22 | removeScript(); 23 | scriptElem = null; 24 | fireReadyStateChange(0); 25 | } 26 | 27 | function ThrowError(msg) { 28 | try { publicAPI.onerror.call(publicAPI,msg,script_url); } catch (err) { throw new Error(msg); } 29 | } 30 | 31 | function handleScriptLoad() { 32 | if ((this.readyState && this.readyState!=="complete" && this.readyState!=="loaded") || script_loaded) { return; } 33 | this.onload = this.onreadystatechange = null; // prevent memory leak 34 | script_loaded = true; 35 | if (publicAPI.readyState !== 4) ThrowError("Script failed to load ["+script_url+"]."); 36 | removeScript(); 37 | } 38 | 39 | function fireReadyStateChange(rs,args) { 40 | args = args || []; 41 | publicAPI.readyState = rs; 42 | if (typeof publicAPI.onreadystatechange === "function") publicAPI.onreadystatechange.apply(publicAPI,args); 43 | } 44 | 45 | publicAPI = { 46 | onerror:null, 47 | onreadystatechange:null, 48 | readyState:0, 49 | open:function(method,url){ 50 | reset(); 51 | internal_callback = "cb"+(callback_counter++); 52 | (function(icb){ 53 | global.jXHR[icb] = function() { 54 | try { fireReadyStateChange.call(publicAPI,4,arguments); } 55 | catch(err) { 56 | publicAPI.readyState = -1; 57 | ThrowError("Script failed to run ["+script_url+"]."); 58 | } 59 | global.jXHR[icb] = null; 60 | }; 61 | })(internal_callback); 62 | script_url = url.replace(/=\?/,"=jXHR."+internal_callback); 63 | fireReadyStateChange(1); 64 | }, 65 | send:function(){ 66 | SETTIMEOUT(function(){ 67 | scriptElem = doc.createElement("script"); 68 | scriptElem.setAttribute("type","text/javascript"); 69 | scriptElem.onload = scriptElem.onreadystatechange = function(){handleScriptLoad.call(scriptElem);}; 70 | scriptElem.setAttribute("src",script_url); 71 | doc.getElementsByTagName("head")[0].appendChild(scriptElem); 72 | },0); 73 | fireReadyStateChange(2); 74 | }, 75 | setRequestHeader:function(){}, // noop 76 | getResponseHeader:function(){return "";}, // basically noop 77 | getAllResponseHeaders:function(){return [];} // ditto 78 | }; 79 | 80 | reset(); 81 | 82 | return publicAPI; 83 | }; 84 | })(window); 85 | -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/templates/archives.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block title %}Archives - {{ SITENAME }}{% endblock %} 3 | {% block breadcrumbs %} 4 | {% if DISPLAY_BREADCRUMBS %} 5 | 9 | {% endif %} 10 | {% endblock %} 11 | 12 | {% block content %} 13 |
14 |

Archives for {{ SITENAME }}

15 |
16 | {% for article in dates %} 17 |

18 | 19 | {{ article.title }}{% if article.subtitle %} - {{ article.subtitle }}{% endif %} 20 |

21 | {% endfor %} 22 |
23 |
24 | {% endblock %} 25 | -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/templates/article_list.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block content %} 3 | {% if articles %} 4 | {% for article in (articles_page.object_list if articles_page else articles) %} 5 |
6 |

{{ article.title }}

7 | {% if DISPLAY_ARTICLE_INFO_ON_INDEX %} 8 |
9 | {% include "includes/article_info.html" %} 10 |
11 | {% endif %} 12 |
{{ article.summary }} 13 | {% include 'includes/comment_count.html' %} 14 | more ... 15 |
16 |
17 |
18 | {% endfor %} 19 | {% endif %} 20 | 21 | {% include 'includes/pagination.html' %} 22 | {% endblock content %} 23 | -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/templates/author.html: -------------------------------------------------------------------------------- 1 | {% extends "article_list.html" %} 2 | 3 | {% block title %}Articles by {{ author }} - {{ SITENAME }}{% endblock %} 4 | 5 | {% block breadcrumbs %} 6 | {% if DISPLAY_BREADCRUMBS %} 7 | 12 | {% endif %} 13 | {% endblock %} 14 | -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/templates/authors.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Authors - {{ SITENAME }}{% endblock %} 4 | 5 | {% block breadcrumbs %} 6 | {% if DISPLAY_BREADCRUMBS %} 7 | 11 | {% endif %} 12 | {% endblock %} 13 | 14 | {% block content %} 15 |

Authors on {{ SITENAME }}

16 | {% for author, articles in authors|sort %} 17 |
  • {{ author }} ({{ articles|count }})
  • 18 | {% endfor %} 19 | {% endblock %} 20 | -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/templates/categories.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block title %}Categories - {{ SITENAME }}{% endblock %} 3 | 4 | {% block breadcrumbs %} 5 | {% if DISPLAY_BREADCRUMBS %} 6 | 10 | {% endif %} 11 | {% endblock %} 12 | 13 | {% block content %} 14 |
    15 |

    All Categories for {{ SITENAME }}

    16 |
    17 | {% for category, articles in categories %} 18 |
    19 | 24 |
    25 |
    26 | {% for article in articles %} 27 |

    {{ article.title }}

    28 | {% endfor %} 29 |
    30 |
    31 |
    32 | {% endfor %} 33 |
    34 | 35 |
    36 | {% endblock %} 37 | -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/templates/category.html: -------------------------------------------------------------------------------- 1 | {% extends "article_list.html" %} 2 | {% block title %}{{ category }} - {{ SITENAME }}{% endblock %} 3 | {% block meta %} 4 | 5 | 6 | {% endblock %} 7 | {% block breadcrumbs %} 8 | {% if DISPLAY_BREADCRUMBS %} 9 | 14 | {% endif %} 15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/templates/includes/aboutme.html: -------------------------------------------------------------------------------- 1 | {% if AVATAR %} 2 |

    3 | 4 |

    5 | {% endif %} 6 |

    7 | About {{ AUTHOR }}
    8 | {{ ABOUT_ME }} 9 |

    10 | -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/templates/includes/addthis.html: -------------------------------------------------------------------------------- 1 | {% if ADDTHIS_PROFILE %} 2 |
    3 | 4 |
    5 | {% if ADDTHIS_FACEBOOK_LIKE|default(true) %} 6 | 7 | {% endif %} 8 | {% if ADDTHIS_TWEET|default(true) %} 9 | 10 | {% endif %} 11 | {% if ADDTHIS_GOOGLE_PLUSONE|default(true) %} 12 | 13 | {% endif %} 14 |
    15 | {% if ADDTHIS_DATA_TRACK_ADDRESSBAR|default(true) %} 16 | 17 | {% endif %} 18 | 19 | 20 | {% endif %} -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/templates/includes/article_info.html: -------------------------------------------------------------------------------- 1 |
    2 | Date 3 | 4 | 5 | 6 | {% if SHOW_ARTICLE_AUTHOR %} 7 | {% if article.author %} 8 | By 9 | {{ article.author }} 10 | {% endif %} 11 | {% endif %} 12 | 13 | {% if SHOW_ARTICLE_CATEGORY %} 14 | Category 15 | {{ article.category }} 16 | {% endif %} 17 | 18 | {% if PDF_PROCESSOR %} 19 | 20 | PDF 21 | 22 | {% endif %} 23 | 24 | {% include 'includes/taglist.html' %} 25 | {% import 'includes/translations.html' as translations with context %} 26 | {{ translations.translations_for(article) }} 27 |
    28 | -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/templates/includes/comment_count.html: -------------------------------------------------------------------------------- 1 | {% if DISQUS_SITENAME and DISQUS_DISPLAY_COUNTS %}

    View comments.

    {% endif %} 2 | -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/templates/includes/comments.html: -------------------------------------------------------------------------------- 1 | {% if DISQUS_SITENAME %} 2 |
    3 |
    4 |

    Comments

    5 | 6 |
    7 | 36 | 38 | comments powered by Disqus 39 | 40 |
    41 | {% endif %} 42 | -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/templates/includes/disqus_script.html: -------------------------------------------------------------------------------- 1 | {% if DISQUS_SITENAME %} 2 | 3 | 16 | 17 | {% endif %} -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/templates/includes/footer.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |
    5 | {% if articles %} 6 | {% set copy_date = articles[0].date.strftime('%Y') %} 7 | {% else %} 8 | {% set copy_date = '' %} 9 | {% endif %} 10 |
    © {{ copy_date }} {{ AUTHOR }} 11 | · Powered by pelican-bootstrap3, 12 | Pelican, 13 | Bootstrap 14 | {%- if CC_LICENSE or CC_LICENSE_DERIVATIVES or CC_LICENSE_COMMERCIAL %} 15 | {% from 'includes/cc-license.html' import cc_license_mark %} 16 |

    {{ cc_license_mark(cc_name=CC_LICENSE,derivatives=CC_LICENSE_DERIVATIVES,commercial=CC_LICENSE_COMMERCIAL,attr_markup=CC_ATTR_MARKUP,attr_props={'title':SITENAME,'name':article.author if article else AUTHOR,'url':SITEURL}) }}

    17 | {% endif %} 18 |
    19 | 20 |
    21 |
    22 |
    -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/templates/includes/ga.html: -------------------------------------------------------------------------------- 1 | {% if GOOGLE_ANALYTICS %} 2 | 3 | 18 | 19 | {% endif %} 20 | {% if GOOGLE_ANALYTICS_UNIVERSAL %} 21 | 22 | 31 | 32 | {% endif %} -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/templates/includes/github-js.html: -------------------------------------------------------------------------------- 1 | {% if GITHUB_USER %} 2 | {% if GITHUB_REPO_COUNT is not defined %} 3 | {% set GITHUB_REPO_COUNT = 5 %} 4 | {% endif %} 5 | {% if GITHUB_SKIP_FORK is not defined %} 6 | {% set GITHUB_SKIP_FORK = "false" %} 7 | {% else %} 8 | {% if GITHUB_SKIP_FORK %} 9 | {% set GITHUB_SKIP_FORK = "true" %} 10 | {% else %} 11 | {% set GITHUB_SKIP_FORK = "false" %} 12 | {% endif %} 13 | {% endif %} 14 | 15 | 33 | 34 | 35 | {% endif %} -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/templates/includes/github.html: -------------------------------------------------------------------------------- 1 | {% if GITHUB_USER %} 2 | 3 |
  • GitHub Repos

    4 |
    5 |

    Status updating...

    6 |
    7 | {% if GITHUB_SHOW_USER_LINK is defined %} 8 | @{{ GITHUB_USER }} on GitHub 9 | {% endif %} 10 |
  • 11 | {% endif %} -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/templates/includes/links.html: -------------------------------------------------------------------------------- 1 | {% if LINKS %} 2 |
  • Links

    3 | 12 |
  • 13 | {% endif %} -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/templates/includes/pagination.html: -------------------------------------------------------------------------------- 1 | {% if articles_page and articles_paginator.num_pages > 1 %} 2 | {% if USE_PAGER %} 3 |
      4 | {% if articles_page.has_previous() %} 5 | 6 | {% else %} 7 | 8 | {% endif %} 9 | {% if articles_page.has_next() %} 10 | 12 | {% else %} 13 | 14 | {% endif %} 15 |
    16 | {% else %} 17 |
      18 | {% if articles_page.has_previous() %} 19 | {% set num = articles_page.previous_page_number() %} 20 | 22 | {% else %} 23 | 24 | {% endif %} 25 | {% for num in range( 1, 1 + articles_paginator.num_pages ) %} 26 |
    • {{ num }}
    • 28 | {% endfor %} 29 | {% if articles_page.has_next() %} 30 | 32 | {% else %} 33 | 34 | {% endif %} 35 |
    36 | {% endif %} 37 | {% endif %} -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/templates/includes/piwik.html: -------------------------------------------------------------------------------- 1 | {% if PIWIK_SITE_ID and PIWIK_URL %} 2 | {% if PIWIK_SSL_URL is not defined %} 3 | {% set PIWIK_SSL_URL = PIWIK_URL %} 4 | {% endif %} 5 | 6 | 19 | 20 | {% endif %} -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/templates/includes/related-posts.html: -------------------------------------------------------------------------------- 1 | {% if article.related_posts %} 2 | 10 | {% endif %} 11 | -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/templates/includes/taglist.html: -------------------------------------------------------------------------------- 1 | {% if article.tags %} 2 | Tags 3 | {% for tag in article.tags %} 4 | {{ tag }} 5 | {% if not loop.last %} 6 | / 7 | {% endif %} 8 | {% endfor %} 9 | {% endif %} 10 | -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/templates/includes/translations.html: -------------------------------------------------------------------------------- 1 | {% macro translations_for(article) %} 2 | {% if article.translations %} 3 | Lang 4 | {% for translation in article.translations %} 5 | {{ translation.lang }} 6 | {% endfor %} 7 | {% endif %} 8 | {% endmacro %} -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/templates/includes/twitter_cards.html: -------------------------------------------------------------------------------- 1 | {% if TWITTER_CARDS and USE_OPEN_GRAPH %} 2 | {# Do not include duplicates tag with og ones. #} 3 | {# Twitter is able to infer them from og. #} 4 | 5 | {% if TWITTER_USERNAME %} 6 | 7 | 8 | {% endif %} 9 | 10 | {% if article %} 11 | {% if article.og_image %} 12 | 14 | {% elif OPEN_GRAPH_IMAGE %} 15 | 17 | {% endif %} 18 | {% elif page %} 19 | {% if page.og_image %} 20 | 22 | {% elif OPEN_GRAPH_IMAGE %} 23 | 25 | {% endif %} 26 | {% endif %} 27 | {% endif %} 28 | -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/templates/includes/twitter_timeline.html: -------------------------------------------------------------------------------- 1 | {% if TWITTER_WIDGET_ID %} 2 | 3 |
  • Latest Tweets

  • 4 | 7 | 8 | 9 | 10 | {% endif %} -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/templates/index.html: -------------------------------------------------------------------------------- 1 | {% extends "article_list.html" %} 2 | 3 | {% block canonical_rel %}{% endblock %} 4 | 5 | -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/templates/page.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block title %}{{ page.title }} - {{ SITENAME }}{% endblock %} 3 | {% block html_lang %}{{ page.lang }}{% endblock %} 4 | {% block meta %} 5 | {% if page.author %} 6 | 7 | {% else %} 8 | 9 | {% endif %} 10 | {% if page.summary %} 11 | 12 | {% endif %} 13 | {% endblock %} 14 | {% block opengraph %} 15 | {% if OPEN_GRAPH_FB_APP_ID %} 16 | 17 | {% endif %} 18 | 19 | 20 | 21 | 22 | 23 | {% if page.og_image %} 24 | 26 | {% elif OPEN_GRAPH_IMAGE %} 27 | 29 | {% endif %} 30 | {% endblock %} 31 | 32 | {% block canonical_rel %} 33 | 34 | {% endblock %} 35 | 36 | {% block breadcrumbs %} 37 | {% if DISPLAY_BREADCRUMBS %} 38 | 44 | {% endif %} 45 | {% endblock %} 46 | 47 | {% block content %} 48 |
    49 |

    {{ page.title }}

    50 | {% import 'includes/translations.html' as translations with context %} 51 | {{ translations.translations_for(page) }} 52 | {% if PDF_PROCESSOR %} 53 | 54 | get the pdf 55 | 56 | {% endif %} 57 |
    58 | {{ page.content }} 59 | {% if page.comments == 'enabled' %} 60 | {% include 'includes/comments.html' %} 61 | {% endif %} 62 |
    63 |
    64 | {% endblock %} 65 | -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/templates/tag.html: -------------------------------------------------------------------------------- 1 | {% extends "article_list.html" %} 2 | {% block title %}{{ tag }} - {{ SITENAME }}{% endblock %} 3 | {% block meta %} 4 | 5 | 6 | {% endblock %} 7 | {% block breadcrumbs %} 8 | {% if DISPLAY_BREADCRUMBS %} 9 | 14 | {% endif %} 15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /docs/www/pelican-bootstrap3/templates/tags.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Tags - {{ SITENAME }}{% endblock %} 4 | 5 | {% block breadcrumbs %} 6 | {% if DISPLAY_BREADCRUMBS %} 7 | 11 | {% endif %} 12 | {% endblock %} 13 | 14 | {% block content %} 15 |
    16 |

    Tags for {{ SITENAME }}

    17 |
    18 | {%- for tag, articles in tags|sort %} 19 |
    20 |
    21 |

    22 | {{ tag }} {{ articles|count }} 23 |

    24 |
    25 |
    26 |
    27 | {% for article in articles %} 28 |

    {{ article.title }}

    29 | {% endfor %} 30 |
    31 |
    32 |
    33 | {% endfor %} 34 |
    35 | 36 |
    37 | {% endblock %} 38 | -------------------------------------------------------------------------------- /docs/www/pelican-plugins/liquid_tags/.gitignore: -------------------------------------------------------------------------------- 1 | .tox 2 | test_data/cache/ 3 | test_data/output/theme/ 4 | _nb_header.html 5 | -------------------------------------------------------------------------------- /docs/www/pelican-plugins/liquid_tags/__init__.py: -------------------------------------------------------------------------------- 1 | from .liquid_tags import * 2 | -------------------------------------------------------------------------------- /docs/www/pelican-plugins/liquid_tags/audio.py: -------------------------------------------------------------------------------- 1 | """ 2 | Audio Tag 3 | --------- 4 | This implements a Liquid-style audio tag for Pelican, 5 | based on the pelican video plugin [1]_ 6 | 7 | Syntax 8 | ------ 9 | {% audio url/to/audio [url/to/audio] [/url/to/audio] %} 10 | 11 | Example 12 | ------- 13 | {% audio http://example.tld/foo.mp3 http://example.tld/foo.ogg %} 14 | 15 | Output 16 | ------ 17 | 18 | 19 | [1] https://github.com/getpelican/pelican-plugins/blob/master/liquid_tags/video.py 20 | """ 21 | import os 22 | import re 23 | from .mdx_liquid_tags import LiquidTags 24 | 25 | SYNTAX = "{% audio url/to/audio [url/to/audio] [/url/to/audio] %}" 26 | AUDIO = re.compile(r'(/\S+|https?:\S+)(?:\s+(/\S+|https?:\S+))?(?:\s+(/\S+|https?:\S+))?') 27 | 28 | AUDIO_TYPEDICT = {'.mp3': 'audio/mpeg', 29 | '.ogg': 'audio/ogg', 30 | '.oga': 'audio/ogg', 31 | '.opus': 'audio/ogg', 32 | '.wav': 'audio/wav', 33 | '.mp4': 'audio/mp4'} 34 | 35 | 36 | def create_html(markup): 37 | match = AUDIO.search(markup) 38 | if match: 39 | groups = match.groups() 40 | audio_files = [g for g in groups if g] 41 | 42 | if any(audio_files): 43 | audio_out = '' 60 | 61 | else: 62 | raise ValueError("Error processing input, " 63 | "expected syntax: {0}".format(SYNTAX)) 64 | 65 | return audio_out 66 | 67 | 68 | @LiquidTags.register('audio') 69 | def audio(preprocessor, tag, markup): 70 | return create_html(markup) 71 | 72 | 73 | # --------------------------------------------------- 74 | # This import allows image tag to be a Pelican plugin 75 | from liquid_tags import register 76 | -------------------------------------------------------------------------------- /docs/www/pelican-plugins/liquid_tags/b64img.py: -------------------------------------------------------------------------------- 1 | """ 2 | Image Tag 3 | --------- 4 | This implements a Liquid-style image tag for Pelican, 5 | based on the liquid img tag which is based on the octopress image tag [1]_ 6 | 7 | Syntax 8 | ------ 9 | {% b64img [class name(s)] [http[s]:/]/path/to/image [width [height]] [title text | "title text" ["alt text"]] %} 10 | 11 | Examples 12 | -------- 13 | {% b64img /images/ninja.png Ninja Attack! %} 14 | {% b64img left half http://site.com/images/ninja.png Ninja Attack! %} 15 | {% b64img left half http://site.com/images/ninja.png 150 150 "Ninja Attack!" "Ninja in attack posture" %} 16 | 17 | Output 18 | ------ 19 | 20 | Ninja Attack! 21 | Ninja in attack posture 22 | 23 | [1] https://github.com/imathis/octopress/blob/master/plugins/image_tag.rb 24 | """ 25 | import re 26 | import base64 27 | import urllib2 28 | from .mdx_liquid_tags import LiquidTags 29 | import six 30 | 31 | SYNTAX = '{% b64img [class name(s)] [http[s]:/]/path/to/image [width [height]] [title text | "title text" ["alt text"]] %}' 32 | 33 | # Regular expression to match the entire syntax 34 | ReImg = re.compile("""(?P\S.*\s+)?(?P(?:https?:\/\/|\/|\S+\/)\S+)(?:\s+(?P\d+))?(?:\s+(?P\d+))?(?P\s+.+)?""") 35 | 36 | # Regular expression to split the title and alt text 37 | ReTitleAlt = re.compile("""(?:"|')(?P<title>[^"']+)?(?:"|')\s+(?:"|')(?P<alt>[^"']+)?(?:"|')""") 38 | 39 | 40 | def _get_file(src): 41 | """ Return content from local or remote file. """ 42 | try: 43 | if '://' in src or src[0:2] == '//': # Most likely this is remote file 44 | response = urllib2.urlopen(src) 45 | return response.read() 46 | else: 47 | with open(src, 'rb') as fh: 48 | return fh.read() 49 | except Exception as e: 50 | raise RuntimeError('Error generating base64image: {}'.format(e)) 51 | 52 | 53 | def base64image(src): 54 | """ Generate base64 encoded image from srouce file. """ 55 | return base64.b64encode(_get_file(src)) 56 | 57 | 58 | @LiquidTags.register('b64img') 59 | def b64img(preprocessor, tag, markup): 60 | attrs = None 61 | 62 | # Parse the markup string 63 | match = ReImg.search(markup) 64 | if match: 65 | attrs = dict([(key, val.strip()) 66 | for (key, val) in six.iteritems(match.groupdict()) if val]) 67 | else: 68 | raise ValueError('Error processing input. ' 69 | 'Expected syntax: {0}'.format(SYNTAX)) 70 | 71 | # Check if alt text is present -- if so, split it from title 72 | if 'title' in attrs: 73 | match = ReTitleAlt.search(attrs['title']) 74 | if match: 75 | attrs.update(match.groupdict()) 76 | if not attrs.get('alt'): 77 | attrs['alt'] = attrs['title'] 78 | 79 | attrs['src'] = 'data:;base64,{}'.format(base64image(attrs['src'])) 80 | 81 | # Return the formatted text 82 | return "<img {0}>".format(' '.join('{0}="{1}"'.format(key, val) 83 | for (key, val) in six.iteritems(attrs))) 84 | 85 | 86 | #---------------------------------------------------------------------- 87 | # This import allows image tag to be a Pelican plugin 88 | from .liquid_tags import register 89 | -------------------------------------------------------------------------------- /docs/www/pelican-plugins/liquid_tags/giphy.py: -------------------------------------------------------------------------------- 1 | """ 2 | Giphy Tag 3 | --------- 4 | 5 | This implements a Liquid-style Giphy tag for Pelican. 6 | 7 | IMPORTANT: You have to request a production API key from giphy `here <https://api.giphy.com/submit>`. 8 | For the first runs you could also use the public beta key you can get `here <https://github.com/giphy/GiphyAPI>`. 9 | 10 | Syntax 11 | ------ 12 | {% giphy gif_id ["alt text"|'alt text'] %} 13 | 14 | Example 15 | ------- 16 | {% giphy aMSJFS6oFX0fC 'ive had some free time' %} 17 | 18 | Output 19 | ------ 20 | <a href="http://giphy.com/gifs/veronica-mars-aMSJFS6oFX0fC"><img src="http://media4.giphy.com/media/aMSJFS6oFX0fC/giphy.gif" alt="ive had some free time"></a> 21 | """ 22 | import json 23 | import re 24 | try: 25 | from urllib.request import urlopen 26 | except ImportError: 27 | from urllib import urlopen 28 | from .mdx_liquid_tags import LiquidTags 29 | 30 | 31 | SYNTAX = '''{% giphy gif_id ["alt text"|'alt text'] %}''' 32 | GIPHY = re.compile('''(?P<gif_id>[\S+]+)(?:\s+(['"]{0,1})(?P<alt>.+)(\\2))?''') 33 | 34 | 35 | def get_gif(api_key, gif_id): 36 | '''Returns dict with gif informations from the API.''' 37 | url = 'http://api.giphy.com/v1/gifs/{}?api_key={}'.format(gif_id, api_key) 38 | r = urlopen(url) 39 | 40 | return json.loads(r.read().decode('utf-8')) 41 | 42 | 43 | def create_html(api_key, attrs): 44 | '''Returns complete html tag string.''' 45 | gif = get_gif(api_key, attrs['gif_id']) 46 | 47 | if 'alt' not in attrs.keys(): 48 | attrs['alt'] = 'source: {}'.format(gif['data']['source']) 49 | 50 | html_out = '<a href="{}">'.format(gif['data']['url']) 51 | html_out += '<img src="{}" alt="{}">'.format( 52 | gif['data']['images']['original']['url'], 53 | attrs['alt']) 54 | html_out += '</a>' 55 | 56 | return html_out 57 | 58 | 59 | def main(api_key, markup): 60 | '''Doing the regex parsing and running the create_html function.''' 61 | match = GIPHY.search(markup) 62 | 63 | attrs = None 64 | 65 | if match: 66 | attrs = dict( 67 | [(key, value.strip()) 68 | for (key, value) in match.groupdict().items() if value]) 69 | 70 | else: 71 | raise ValueError('Error processing input. ' 72 | 'Expected syntax: {}'.format(SYNTAX)) 73 | 74 | return create_html(api_key, attrs) 75 | 76 | 77 | @LiquidTags.register('giphy') 78 | def giphy(preprocessor, tag, markup): 79 | api_key = preprocessor.configs.getConfig('GIPHY_API_KEY') 80 | 81 | if api_key is None: 82 | raise ValueError('Please set GIPHY_API_KEY.') 83 | 84 | return main(api_key, markup) 85 | 86 | 87 | # --------------------------------------------------- 88 | # This import allows image tag to be a Pelican plugin 89 | from liquid_tags import register 90 | -------------------------------------------------------------------------------- /docs/www/pelican-plugins/liquid_tags/img.py: -------------------------------------------------------------------------------- 1 | """ 2 | Image Tag 3 | --------- 4 | This implements a Liquid-style image tag for Pelican, 5 | based on the octopress image tag [1]_ 6 | 7 | Syntax 8 | ------ 9 | {% img [class name(s)] [http[s]:/]/path/to/image [width [height]] [title text | "title text" ["alt text"]] %} 10 | 11 | Examples 12 | -------- 13 | {% img /images/ninja.png Ninja Attack! %} 14 | {% img left half http://site.com/images/ninja.png Ninja Attack! %} 15 | {% img left half http://site.com/images/ninja.png 150 150 "Ninja Attack!" "Ninja in attack posture" %} 16 | 17 | Output 18 | ------ 19 | <img src="/images/ninja.png"> 20 | <img class="left half" src="http://site.com/images/ninja.png" title="Ninja Attack!" alt="Ninja Attack!"> 21 | <img class="left half" src="http://site.com/images/ninja.png" width="150" height="150" title="Ninja Attack!" alt="Ninja in attack posture"> 22 | 23 | [1] https://github.com/imathis/octopress/blob/master/plugins/image_tag.rb 24 | """ 25 | import re 26 | from .mdx_liquid_tags import LiquidTags 27 | import six 28 | 29 | SYNTAX = '{% img [class name(s)] [http[s]:/]/path/to/image [width [height]] [title text | "title text" ["alt text"]] %}' 30 | 31 | # Regular expression to match the entire syntax 32 | ReImg = re.compile("""(?P<class>\S.*\s+)?(?P<src>(?:https?:\/\/|\/|\S+\/)\S+)(?:\s+(?P<width>\d+))?(?:\s+(?P<height>\d+))?(?P<title>\s+.+)?""") 33 | 34 | # Regular expression to split the title and alt text 35 | ReTitleAlt = re.compile("""(?:"|')(?P<title>[^"']+)?(?:"|')\s+(?:"|')(?P<alt>[^"']+)?(?:"|')""") 36 | 37 | 38 | @LiquidTags.register('img') 39 | def img(preprocessor, tag, markup): 40 | attrs = None 41 | 42 | # Parse the markup string 43 | match = ReImg.search(markup) 44 | if match: 45 | attrs = dict([(key, val.strip()) 46 | for (key, val) in six.iteritems(match.groupdict()) if val]) 47 | else: 48 | raise ValueError('Error processing input. ' 49 | 'Expected syntax: {0}'.format(SYNTAX)) 50 | 51 | # Check if alt text is present -- if so, split it from title 52 | if 'title' in attrs: 53 | match = ReTitleAlt.search(attrs['title']) 54 | if match: 55 | attrs.update(match.groupdict()) 56 | if not attrs.get('alt'): 57 | attrs['alt'] = attrs['title'] 58 | 59 | # Return the formatted text 60 | return "<img {0}>".format(' '.join('{0}="{1}"'.format(key, val) 61 | for (key, val) in six.iteritems(attrs))) 62 | 63 | #---------------------------------------------------------------------- 64 | # This import allows image tag to be a Pelican plugin 65 | from .liquid_tags import register 66 | 67 | -------------------------------------------------------------------------------- /docs/www/pelican-plugins/liquid_tags/liquid_tags.py: -------------------------------------------------------------------------------- 1 | from pelican import signals 2 | from .mdx_liquid_tags import LiquidTags, LT_CONFIG 3 | 4 | 5 | def addLiquidTags(gen): 6 | if not gen.settings.get('MD_EXTENSIONS'): 7 | from pelican.settings import DEFAULT_CONFIG 8 | gen.settings['MD_EXTENSIONS'] = DEFAULT_CONFIG['MD_EXTENSIONS'] 9 | 10 | if LiquidTags not in gen.settings['MD_EXTENSIONS']: 11 | configs = dict() 12 | for key,value in LT_CONFIG.items(): 13 | configs[key]=value 14 | for key,value in gen.settings.items(): 15 | if key in LT_CONFIG: 16 | configs[key]=value 17 | gen.settings['MD_EXTENSIONS'].append(LiquidTags(configs)) 18 | 19 | 20 | def register(): 21 | signals.initialized.connect(addLiquidTags) 22 | -------------------------------------------------------------------------------- /docs/www/pelican-plugins/liquid_tags/literal.py: -------------------------------------------------------------------------------- 1 | """ 2 | Literal Tag 3 | ----------- 4 | This implements a tag that allows explicitly showing commands which would 5 | otherwise be interpreted as a liquid tag. 6 | 7 | For example, the line 8 | 9 | {% literal video arg1 arg2 %} 10 | 11 | would result in the following line: 12 | 13 | {% video arg1 arg2 %} 14 | 15 | This is useful when the resulting line would be interpreted as another 16 | liquid-style tag. 17 | """ 18 | from .mdx_liquid_tags import LiquidTags 19 | 20 | @LiquidTags.register('literal') 21 | def literal(preprocessor, tag, markup): 22 | return '{%% %s %%}' % markup 23 | 24 | #---------------------------------------------------------------------- 25 | # This import allows image tag to be a Pelican plugin 26 | from liquid_tags import register 27 | 28 | -------------------------------------------------------------------------------- /docs/www/pelican-plugins/liquid_tags/pelicanhtml_1.tpl: -------------------------------------------------------------------------------- 1 | {%- extends 'html_basic.tpl' -%} 2 | 3 | {% block stream_stdout -%} 4 | <div class="box-flex1 output_subarea output_stream output_stdout"> 5 | <pre class="ipynb">{{output.text |ansi2html}}</pre> 6 | </div> 7 | {%- endblock stream_stdout %} 8 | 9 | {% block stream_stderr -%} 10 | <div class="box-flex1 output_subarea output_stream output_stderr"> 11 | <pre class="ipynb">{{output.text |ansi2html}}</pre> 12 | </div> 13 | {%- endblock stream_stderr %} 14 | 15 | {% block pyerr -%} 16 | <div class="box-flex1 output_subarea output_pyerr"> 17 | <pre class="ipynb">{{super()}}</pre> 18 | </div> 19 | {%- endblock pyerr %} 20 | 21 | {%- block data_text %} 22 | <pre class="ipynb">{{output.text | ansi2html}}</pre> 23 | {%- endblock -%} 24 | 25 | {% block input %} 26 | {% if "# <!-- collapse=True -->" in cell.input %} 27 | <div class="collapseheader box-flex1"><span style="font-weight: bold;">Expand Code</span> 28 | <div class="input_area box-flex1" style="display:none"> 29 | {{ cell.input.replace("# <!-- collapse=True -->\n", "") | highlight2html(metadata=cell.metadata) }} 30 | </div> 31 | </div> 32 | {% elif "# <!-- collapse=False -->" in cell.input %} 33 | <div class="collapseheader box-flex1"><span style="font-weight: bold;">Collapse Code</span> 34 | <div class="input_area box-flex1"> 35 | {{ cell.input.replace("# <!-- collapse=False -->\n", "") | highlight2html(metadata=cell.metadata) }} 36 | </div> 37 | </div> 38 | {% else %} 39 | <div class="input_area box-flex1"> 40 | {{ cell.input | highlight2html(metadata=cell.metadata) }} 41 | </div> 42 | {% endif %} 43 | {%- endblock input %} 44 | 45 | -------------------------------------------------------------------------------- /docs/www/pelican-plugins/liquid_tags/pelicanhtml_2.tpl: -------------------------------------------------------------------------------- 1 | {%- extends 'basic.tpl' -%} 2 | 3 | {% block stream_stdout -%} 4 | <div class="box-flex1 output_subarea output_stream output_stdout"> 5 | <pre class="ipynb">{{output.text |ansi2html}}</pre> 6 | </div> 7 | {%- endblock stream_stdout %} 8 | 9 | {% block stream_stderr -%} 10 | <div class="box-flex1 output_subarea output_stream output_stderr"> 11 | <pre class="ipynb">{{output.text |ansi2html}}</pre> 12 | </div> 13 | {%- endblock stream_stderr %} 14 | 15 | {% block pyerr -%} 16 | <div class="box-flex1 output_subarea output_pyerr"> 17 | <pre class="ipynb">{{super()}}</pre> 18 | </div> 19 | {%- endblock pyerr %} 20 | 21 | {%- block data_text %} 22 | <pre class="ipynb">{{output.text | ansi2html}}</pre> 23 | {%- endblock -%} 24 | 25 | {% block input %} 26 | {% if "# <!-- collapse=True -->" in cell.input %} 27 | <div class="collapseheader box-flex1"><span style="font-weight: bold;">Expand Code</span> 28 | <div class="input_area box-flex1" style="display:none"> 29 | {{ cell.input.replace("# <!-- collapse=True -->\n", "") | highlight2html(metadata=cell.metadata) }} 30 | </div> 31 | </div> 32 | {% elif "# <!-- collapse=False -->" in cell.input %} 33 | <div class="collapseheader box-flex1"><span style="font-weight: bold;">Collapse Code</span> 34 | <div class="input_area box-flex1"> 35 | {{ cell.input.replace("# <!-- collapse=False -->\n", "") | highlight2html(metadata=cell.metadata) }} 36 | </div> 37 | </div> 38 | {% else %} 39 | <div class="input_area box-flex1"> 40 | {{ cell.input | highlight2html(metadata=cell.metadata) }} 41 | </div> 42 | {% endif %} 43 | {%- endblock input %} 44 | 45 | -------------------------------------------------------------------------------- /docs/www/pelican-plugins/liquid_tags/pelicanhtml_3.tpl: -------------------------------------------------------------------------------- 1 | {%- extends 'basic.tpl' -%} 2 | 3 | {% block stream_stdout -%} 4 | <div class="output_subarea output_stream output_stdout output_text"> 5 | <pre class="ipynb"> 6 | {{- output.text | ansi2html -}} 7 | </pre> 8 | </div> 9 | {%- endblock stream_stdout %} 10 | 11 | {% block stream_stderr -%} 12 | <div class="output_subarea output_stream output_stderr output_text"> 13 | <pre class="ipynb"> 14 | {{- output.text | ansi2html -}} 15 | </pre> 16 | </div> 17 | {%- endblock stream_stderr %} 18 | 19 | {% block error -%} 20 | <div class="output_subarea output_text output_error"> 21 | <pre class="ipynb"> 22 | {{- super() -}} 23 | </pre> 24 | </div> 25 | {%- endblock error %} 26 | 27 | {%- block data_text scoped %} 28 | <div class="output_text output_subarea {{extra_class}}"> 29 | <pre class="ipynb"> 30 | {{- output.data['text/plain'] | ansi2html -}} 31 | </pre> 32 | </div> 33 | {%- endblock -%} 34 | 35 | {% block input %} 36 | {% if "# <!-- collapse=True -->" in cell.source %} 37 | <div class="collapseheader inner_cell"><span style="font-weight: bold;">Expand Code</span> 38 | <div class="input_area" style="display:none"> 39 | {{ cell.source.replace("# <!-- collapse=True -->\n", "") | highlight2html(metadata=cell.metadata) }} 40 | </div> 41 | </div> 42 | {% elif "# <!-- collapse=False -->" in cell.source %} 43 | <div class="collapseheader inner_cell"><span style="font-weight: bold;">Collapse Code</span> 44 | <div class="input_area"> 45 | {{ cell.source.replace("# <!-- collapse=False -->\n", "") | highlight2html(metadata=cell.metadata) }} 46 | </div> 47 | </div> 48 | {% else %} 49 | <div class="inner_cell"> 50 | <div class="input_area"> 51 | {{ cell.source | highlight_code(metadata=cell.metadata) }} 52 | </div> 53 | </div> 54 | {% endif %} 55 | {%- endblock input %} 56 | -------------------------------------------------------------------------------- /docs/www/pelican-plugins/liquid_tags/soundcloud.py: -------------------------------------------------------------------------------- 1 | """ 2 | Soundcloud Tag 3 | -------------- 4 | This implements a Liquid-style soundcloud tag for Pelican. 5 | 6 | It asks the official Soundcloud-API for the widget html code. 7 | 8 | Syntax 9 | ------ 10 | `{% soundcloud track_url %}` 11 | 12 | Example 13 | ------- 14 | `{% soundcloud https://soundcloud.com/luftmentsh/hakotel %}` 15 | 16 | Output 17 | ------ 18 | `<iframe width="100%" height="400" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/?visual=true&url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F33875102&show_artwork=true"></iframe>` 19 | """ 20 | from .mdx_liquid_tags import LiquidTags 21 | import re 22 | import json 23 | try: 24 | from urllib.request import urlopen 25 | except ImportError: 26 | from urllib import urlopen 27 | 28 | 29 | SYNTAX = '{% soundcloud track_url %}' 30 | PARSE_SYNTAX = re.compile(r'(?P<track_url>https?://soundcloud.com/[\S]+)') 31 | 32 | 33 | def get_widget(track_url): 34 | r = urlopen( 35 | 'http://soundcloud.com/oembed', 36 | data='format=json&url={}'.format(track_url).encode('utf-8')) 37 | 38 | return json.loads(r.read().decode('utf-8'))['html'] 39 | 40 | 41 | def match_it(markup): 42 | match = PARSE_SYNTAX.search(markup) 43 | if match: 44 | return match.groupdict() 45 | else: 46 | raise ValueError('Error processing input. ' 47 | 'Expected syntax: {}'.format(SYNTAX)) 48 | 49 | 50 | @LiquidTags.register('soundcloud') 51 | def soundcloud(preprocessor, tag, markup): 52 | track_url = match_it(markup)['track_url'] 53 | 54 | return get_widget(track_url) 55 | 56 | 57 | # --------------------------------------------------- 58 | # This import allows image tag to be a Pelican plugin 59 | from liquid_tags import register 60 | -------------------------------------------------------------------------------- /docs/www/pelican-plugins/liquid_tags/spotify.py: -------------------------------------------------------------------------------- 1 | """ 2 | Spotify Tag 3 | --------- 4 | This implements a Liquid-style spotify tag for Pelican, 5 | based on the jekyll / octopress youtube tag [1]_ 6 | 7 | Syntax 8 | ------ 9 | {% spotify id %} 10 | 11 | Example 12 | ------- 13 | {% spotify 1HNZcRFlIKwHAJD3LxvX4d %} 14 | 15 | Output 16 | ------ 17 | <iframe 18 | src='https://embed.spotify.com/?uri=spotify:track:1HNZcRFlIKwHAJD3LxvX4d' 19 | width='300' height='380' frameborder='0' allowtransparency='true'> 20 | </iframe> 21 | """ 22 | import re 23 | from .mdx_liquid_tags import LiquidTags 24 | 25 | SYNTAX = "{% spotify id %}" 26 | 27 | SPOTIFY = re.compile(r'(\w+)(\s+(\d+)\s(\d+))?') 28 | 29 | 30 | @LiquidTags.register('spotify') 31 | def spotify(preprocessor, tag, markup): 32 | spotify_id = None 33 | 34 | match = SPOTIFY.search(markup) 35 | if match: 36 | groups = match.groups() 37 | spotify_id = groups[0] 38 | 39 | if spotify_id: 40 | spotify_out = """ 41 | <iframe src='https://embed.spotify.com/?uri=spotify:track:{}' 42 | width='300' 43 | height='380' 44 | frameborder='0' 45 | allowtransparency='true'></iframe>""".format(spotify_id).strip() 46 | else: 47 | raise ValueError("Error processing input, " 48 | "expected syntax: {0}".format(SYNTAX)) 49 | 50 | return spotify_out 51 | 52 | 53 | # --------------------------------------------------- 54 | # This import allows image tag to be a Pelican plugin 55 | from liquid_tags import register # noqa 56 | -------------------------------------------------------------------------------- /docs/www/pelican-plugins/liquid_tags/test_audio.py: -------------------------------------------------------------------------------- 1 | from . import audio 2 | import pytest 3 | import re 4 | 5 | 6 | @pytest.mark.parametrize('input,expected', [ 7 | ('http://foo.bar https://bar.foo', 8 | ('http://foo.bar', 'https://bar.foo', None)), 9 | ('http://test.foo', 10 | ('http://test.foo', None, None)), 11 | ('https://test.foo', 12 | ('https://test.foo', None, None)), 13 | ('http://foo.foo https://bar.bar http://zonk.zonk', 14 | ('http://foo.foo', 'https://bar.bar', 'http://zonk.zonk')) 15 | ]) 16 | def test_regex(input, expected): 17 | assert re.match(audio.AUDIO, input).groups() == expected 18 | 19 | 20 | @pytest.mark.parametrize('input,expected', [ 21 | ('http://foo.foo/foo.mp3', 22 | ('<audio controls>' 23 | '<source src="http://foo.foo/foo.mp3" type="audio/mpeg">' 24 | 'Your browser does not support the audio element.</audio>')), 25 | ('https://foo.foo/foo.ogg http://bar.bar/bar.opus', 26 | ('<audio controls>' 27 | '<source src="https://foo.foo/foo.ogg" type="audio/ogg">' 28 | '<source src="http://bar.bar/bar.opus" type="audio/ogg">' 29 | 'Your browser does not support the audio element.</audio>')), 30 | ('http://1.de/1.wav http://2.de/2.mp4 http://3.de/3.ogg', 31 | ('<audio controls>' 32 | '<source src="http://1.de/1.wav" type="audio/wav">' 33 | '<source src="http://2.de/2.mp4" type="audio/mp4">' 34 | '<source src="http://3.de/3.ogg" type="audio/ogg">' 35 | 'Your browser does not support the audio element.</audio>')) 36 | ]) 37 | def test_create_html(input, expected): 38 | assert audio.create_html(input) == expected 39 | -------------------------------------------------------------------------------- /docs/www/pelican-plugins/liquid_tags/test_data/content/test-ipython-notebook-nbformat3.md: -------------------------------------------------------------------------------- 1 | Title: test ipython notebook nb format 3 2 | Date: 2015-03-03 3 | Authors: Testing Man 4 | 5 | 6 | Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod 7 | tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At 8 | vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, 9 | no sea takimata sanctus est Lorem ipsum dolor sit amet. 10 | 11 | #Loading an entire notebook nbformat = 3.0 12 | 13 | {% notebook test_nbformat3.ipynb %} 14 | 15 | #Loading selected cells from a notebook nbformat = 3.0 16 | 17 | {% notebook test_nbformat3.ipynb cells[1:5] %} 18 | -------------------------------------------------------------------------------- /docs/www/pelican-plugins/liquid_tags/test_data/content/test-ipython-notebook-nbformat4.md: -------------------------------------------------------------------------------- 1 | Title: test ipython notebook nb format 4 2 | Date: 2015-03-03 3 | Authors: Testing Man 4 | 5 | 6 | Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod 7 | tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At 8 | vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, 9 | no sea takimata sanctus est Lorem ipsum dolor sit amet. 10 | 11 | #Loading an entire notebook nbformat = 4.0 12 | 13 | {% notebook test_nbformat4.ipynb %} 14 | 15 | #Loading selected cells from a notebook nbformat = 4.0 16 | 17 | {% notebook test_nbformat4.ipynb cells[1:5] %} 18 | -------------------------------------------------------------------------------- /docs/www/pelican-plugins/liquid_tags/test_data/flickr.json: -------------------------------------------------------------------------------- 1 | {"photo":{"id":"18841055371","secret":"17ac287217","server":"5552","farm":6,"dateuploaded":"1434394882","isfavorite":0,"license":"4","safety_level":"0","rotation":0,"originalsecret":"ee4b63c8d8","originalformat":"jpg","owner":{"nsid":"8810721@N07","username":"marvinxsteadfast","realname":"","location":"","iconserver":"0","iconfarm":0,"path_alias":"marvinxsteadfast"},"title":{"_content":"fichte"},"description":{"_content":"Processed with VSCOcam with k1 preset"},"visibility":{"ispublic":1,"isfriend":0,"isfamily":0},"dates":{"posted":"1434394882","taken":"2015-06-13 12:51:14","takengranularity":"0","takenunknown":"0","lastupdate":"1434445581"},"views":"23","editability":{"cancomment":0,"canaddmeta":0},"publiceditability":{"cancomment":1,"canaddmeta":0},"usage":{"candownload":1,"canblog":0,"canprint":0,"canshare":1},"comments":{"_content":"0"},"notes":{"note":[]},"people":{"haspeople":0},"tags":{"tag":[]},"location":{"latitude":"52.418917","longitude":"10.785100","accuracy":"16","context":"0","neighbourhood":{"_content":"Stadtteil Wolfsburg","place_id":"WhlihUxTVLJhqUkmNQ","woeid":"26823353"},"locality":{"_content":"Wolfsburg","place_id":"E0zyhhBWUr1dyKs","woeid":"707678"},"county":{"_content":"Stadtkreis Wolfsburg","place_id":"3NbeUiNQUL9_BB.8dg","woeid":"12596975"},"region":{"_content":"Lower Saxony","place_id":"ul2d17NTUb4lkTA_","woeid":"2345486"},"country":{"_content":"Germany","place_id":"h7eZVDlTUb50Btij9Q","woeid":"23424829"},"place_id":"WhlihUxTVLJhqUkmNQ","woeid":"26823353"},"geoperms":{"ispublic":1,"iscontact":0,"isfriend":0,"isfamily":0},"urls":{"url":[{"type":"photopage","_content":"https:\/\/www.flickr.com\/photos\/marvinxsteadfast\/18841055371\/"}]},"media":"photo"},"stat":"ok"} -------------------------------------------------------------------------------- /docs/www/pelican-plugins/liquid_tags/test_data/giphy.json: -------------------------------------------------------------------------------- 1 | 2 | {"data":{"type":"gif","id":"aMSJFS6oFX0fC","url":"http:\/\/giphy.com\/gifs\/veronica-mars-aMSJFS6oFX0fC","bitly_gif_url":"http:\/\/gph.is\/1hcFOSo","bitly_url":"http:\/\/gph.is\/1hcFOSo","embed_url":"http:\/\/giphy.com\/embed\/aMSJFS6oFX0fC","username":"","source":"http:\/\/www.tumblr.com","rating":"pg","caption":"","content_url":"","import_datetime":"2014-02-21 04:43:11","trending_datetime":"1970-01-01 00:00:00","images":{"fixed_height":{"url":"http:\/\/media2.giphy.com\/media\/aMSJFS6oFX0fC\/200.gif","width":"350","height":"200","size":"296611","mp4":"http:\/\/media2.giphy.com\/media\/aMSJFS6oFX0fC\/200.mp4","mp4_size":"64850","webp":"http:\/\/media2.giphy.com\/media\/aMSJFS6oFX0fC\/200.webp","webp_size":"529942"},"fixed_height_still":{"url":"http:\/\/media2.giphy.com\/media\/aMSJFS6oFX0fC\/200_s.gif","width":"350","height":"200"},"fixed_height_downsampled":{"url":"http:\/\/media2.giphy.com\/media\/aMSJFS6oFX0fC\/200_d.gif","width":"350","height":"200","size":"243264","webp":"http:\/\/media2.giphy.com\/media\/aMSJFS6oFX0fC\/200_d.webp","webp_size":"138300"},"fixed_width":{"url":"http:\/\/media2.giphy.com\/media\/aMSJFS6oFX0fC\/200w.gif","width":"200","height":"114","size":"120246","mp4":"http:\/\/media2.giphy.com\/media\/aMSJFS6oFX0fC\/200w.mp4","mp4_size":"96166","webp":"http:\/\/media2.giphy.com\/media\/aMSJFS6oFX0fC\/200w.webp","webp_size":"210140"},"fixed_width_still":{"url":"http:\/\/media2.giphy.com\/media\/aMSJFS6oFX0fC\/200w_s.gif","width":"200","height":"114"},"fixed_width_downsampled":{"url":"http:\/\/media2.giphy.com\/media\/aMSJFS6oFX0fC\/200w_d.gif","width":"200","height":"114","size":"113909","webp":"http:\/\/media2.giphy.com\/media\/aMSJFS6oFX0fC\/200w_d.webp","webp_size":"55084"},"fixed_height_small":{"url":"http:\/\/media2.giphy.com\/media\/aMSJFS6oFX0fC\/100.gif","width":"175","height":"100","size":"296611","mp4":"http:\/\/media2.giphy.com\/media\/aMSJFS6oFX0fC\/100.mp4","mp4_size":"243931","webp":"http:\/\/media2.giphy.com\/media\/aMSJFS6oFX0fC\/100.webp","webp_size":"136098"},"fixed_height_small_still":{"url":"http:\/\/media2.giphy.com\/media\/aMSJFS6oFX0fC\/100_s.gif","width":"175","height":"100"},"fixed_width_small":{"url":"http:\/\/media2.giphy.com\/media\/aMSJFS6oFX0fC\/100w.gif","width":"100","height":"57","size":"120246","mp4":"http:\/\/media2.giphy.com\/media\/aMSJFS6oFX0fC\/100w.mp4","mp4_size":"101604","webp":"http:\/\/media2.giphy.com\/media\/aMSJFS6oFX0fC\/100w.webp","webp_size":"55480"},"fixed_width_small_still":{"url":"http:\/\/media2.giphy.com\/media\/aMSJFS6oFX0fC\/100w_s.gif","width":"100","height":"57"},"downsized":{"url":"http:\/\/media2.giphy.com\/media\/aMSJFS6oFX0fC\/giphy.gif","width":"245","height":"140","size":"487767"},"downsized_still":{"url":"http:\/\/media2.giphy.com\/media\/aMSJFS6oFX0fC\/giphy_s.gif","width":"245","height":"140"},"downsized_large":{"url":"http:\/\/media2.giphy.com\/media\/aMSJFS6oFX0fC\/giphy.gif","width":"245","height":"140","size":"487767"},"original":{"url":"http:\/\/media2.giphy.com\/media\/aMSJFS6oFX0fC\/giphy.gif","width":"245","height":"140","size":"487767","frames":"23","mp4":"http:\/\/media2.giphy.com\/media\/aMSJFS6oFX0fC\/giphy.mp4","mp4_size":"219528","webp":"http:\/\/media2.giphy.com\/media\/aMSJFS6oFX0fC\/giphy.webp","webp_size":"272262"},"original_still":{"url":"http:\/\/media2.giphy.com\/media\/aMSJFS6oFX0fC\/giphy_s.gif","width":"245","height":"140"}}},"meta":{"status":200,"msg":"OK"}} -------------------------------------------------------------------------------- /docs/www/pelican-plugins/liquid_tags/test_data/pelicanconf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- # 3 | from __future__ import unicode_literals 4 | 5 | AUTHOR = 'The Tester' 6 | SITENAME = 'Testing site' 7 | SITEURL = 'http://example.com/test' 8 | 9 | # to make the test suite portable 10 | TIMEZONE = 'UTC' 11 | PATH = 'content' 12 | 13 | READERS = {'html': None} 14 | 15 | # Generate only one feed 16 | FEED_ALL_ATOM = None 17 | CATEGORY_FEED_ATOM = None 18 | TRANSLATION_FEED_ATOM = None 19 | AUTHOR_FEED_ATOM = None 20 | AUTHOR_FEED_RSS = None 21 | 22 | # Disable unnecessary pages 23 | CATEGORY_SAVE_AS = '' 24 | TAG_SAVE_AS = '' 25 | AUTHOR_SAVE_AS = '' 26 | ARCHIVES_SAVE_AS = '' 27 | AUTHORS_SAVE_AS = '' 28 | CATEGORIES_SAVE_AS = '' 29 | TAGS_SAVE_AS = '' 30 | 31 | PLUGIN_PATHS = ['../../'] 32 | PLUGINS = ['liquid_tags.notebook'] 33 | 34 | NOTEBOOK_DIR = 'notebooks' 35 | -------------------------------------------------------------------------------- /docs/www/pelican-plugins/liquid_tags/test_data/pelicanhtml_2.tpl: -------------------------------------------------------------------------------- 1 | ../pelicanhtml_2.tpl -------------------------------------------------------------------------------- /docs/www/pelican-plugins/liquid_tags/test_data/pelicanhtml_3.tpl: -------------------------------------------------------------------------------- 1 | ../pelicanhtml_3.tpl -------------------------------------------------------------------------------- /docs/www/pelican-plugins/liquid_tags/test_flickr.py: -------------------------------------------------------------------------------- 1 | from . import flickr 2 | try: 3 | from unittest.mock import patch 4 | except ImportError: 5 | from mock import patch 6 | import os 7 | import pytest 8 | import re 9 | 10 | 11 | PLUGIN_DIR = os.path.dirname(__file__) 12 | TEST_DATA_DIR = os.path.join(PLUGIN_DIR, 'test_data') 13 | 14 | 15 | @pytest.mark.parametrize('input,expected', [ 16 | ('18873146680 large "test 1"', 17 | dict(photo_id='18873146680', 18 | size='large', 19 | alt='test 1')), 20 | ('18873146680 large \'test 1\'', 21 | dict(photo_id='18873146680', 22 | size='large', 23 | alt='test 1')), 24 | ('18873143536360 medium "test number two"', 25 | dict(photo_id='18873143536360', 26 | size='medium', 27 | alt='test number two')), 28 | ('18873143536360 small "test number 3"', 29 | dict(photo_id='18873143536360', 30 | size='small', 31 | alt='test number 3')), 32 | ('18873143536360 "test 4"', 33 | dict(photo_id='18873143536360', 34 | size=None, 35 | alt='test 4')), 36 | ('18873143536360', 37 | dict(photo_id='18873143536360', 38 | size=None, 39 | alt=None)), 40 | ('123456 small', 41 | dict(photo_id='123456', 42 | size='small', 43 | alt=None)) 44 | ]) 45 | def test_regex(input, expected): 46 | assert re.match(flickr.PARSE_SYNTAX, input).groupdict() == expected 47 | 48 | 49 | @pytest.mark.parametrize('input,expected', [ 50 | (['1', 'server1', '1', 'secret1', 'small'], 51 | 'https://farm1.staticflickr.com/server1/1_secret1_n.jpg'), 52 | (['2', 'server2', '2', 'secret2', 'medium'], 53 | 'https://farm2.staticflickr.com/server2/2_secret2_c.jpg'), 54 | (['3', 'server3', '3', 'secret3', 'large'], 55 | 'https://farm3.staticflickr.com/server3/3_secret3_b.jpg') 56 | ]) 57 | def test_source_url(input, expected): 58 | assert flickr.source_url( 59 | input[0], input[1], input[2], input[3], input[4]) == expected 60 | 61 | 62 | @patch('liquid_tags.flickr.urlopen') 63 | def test_generage_html(mock_urlopen): 64 | # mock the return to deliver the flickr.json file instead 65 | with open(TEST_DATA_DIR + '/flickr.json', 'rb') as f: 66 | mock_urlopen.return_value.read.return_value = f.read() 67 | 68 | attrs = dict( 69 | photo_id='1234567', 70 | size='large', 71 | alt='this is a test' 72 | ) 73 | 74 | expected = ('<a href="https://www.flickr.com/photos/' 75 | 'marvinxsteadfast/18841055371/">' 76 | '<img src="https://farm6.staticflickr.com/5552/1234567_' 77 | '17ac287217_b.jpg" alt="this is a test"></a>') 78 | 79 | assert flickr.generate_html(attrs, 'abcdef') == expected 80 | -------------------------------------------------------------------------------- /docs/www/pelican-plugins/liquid_tags/test_giphy.py: -------------------------------------------------------------------------------- 1 | from . import giphy 2 | try: 3 | from unittest.mock import patch 4 | except ImportError: 5 | from mock import patch 6 | import os 7 | import pytest 8 | 9 | 10 | PLUGIN_DIR = os.path.dirname(__file__) 11 | TEST_DATA_DIR = os.path.join(PLUGIN_DIR, 'test_data') 12 | 13 | 14 | @pytest.mark.parametrize('input,expected', [ 15 | (dict(gif_id='abc123'), 16 | ('<a href="http://giphy.com/gifs/veronica-mars-aMSJFS6oFX0fC">' 17 | '<img src="http://media2.giphy.com/media/' 18 | 'aMSJFS6oFX0fC/giphy.gif" alt="source: http://www.tumblr.com"></a>')), 19 | (dict(gif_id='abc123', alt='ive had some free time'), 20 | ('<a href="http://giphy.com/gifs/veronica-mars-aMSJFS6oFX0fC">' 21 | '<img src="http://media2.giphy.com/media/' 22 | 'aMSJFS6oFX0fC/giphy.gif" alt="ive had some free time"></a>')) 23 | ]) 24 | @patch('liquid_tags.giphy.urlopen') 25 | def test_create_html(mock_urlopen, input, expected): 26 | with open(TEST_DATA_DIR + '/giphy.json', 'rb') as f: 27 | mock_urlopen.return_value.read.return_value = f.read() 28 | 29 | assert giphy.create_html('test_api_key', input) == expected 30 | -------------------------------------------------------------------------------- /docs/www/pelican-plugins/liquid_tags/test_notebook.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | from pelican.tests.support import unittest 4 | 5 | from . import notebook 6 | 7 | 8 | class TestNotebookTagRegex(unittest.TestCase): 9 | 10 | def get_argdict(self, markup): 11 | 12 | match = notebook.FORMAT.search(markup) 13 | 14 | if match: 15 | argdict = match.groupdict() 16 | 17 | src = argdict['src'] 18 | start = argdict['start'] 19 | end = argdict['end'] 20 | language = argdict['language'] 21 | 22 | return src, start, end, language 23 | 24 | return None 25 | 26 | def test_basic_notebook_tag(self): 27 | markup = u'path/to/thing.ipynb' 28 | src, start, end, language = self.get_argdict(markup) 29 | 30 | self.assertEqual(src, u'path/to/thing.ipynb') 31 | self.assertIsNone(start) 32 | self.assertIsNone(end) 33 | self.assertIsNone(language) 34 | 35 | def test_basic_notebook_tag_insensitive_to_whitespace(self): 36 | markup = u' path/to/thing.ipynb ' 37 | src, start, end, language = self.get_argdict(markup) 38 | 39 | self.assertEqual(src, u'path/to/thing.ipynb') 40 | self.assertIsNone(start) 41 | self.assertIsNone(end) 42 | self.assertIsNone(language) 43 | 44 | def test_notebook_tag_with_cells(self): 45 | markup = u'path/to/thing.ipynb cells[1:5]' 46 | src, start, end, language = self.get_argdict(markup) 47 | 48 | self.assertEqual(src, u'path/to/thing.ipynb') 49 | self.assertEqual(start, u'1') 50 | self.assertEqual(end, u'5') 51 | self.assertIsNone(language) 52 | 53 | def test_notebook_tag_with_alphanumeric_language(self): 54 | markup = u'path/to/thing.ipynb language[python3]' 55 | src, start, end, language = self.get_argdict(markup) 56 | 57 | self.assertEqual(src, u'path/to/thing.ipynb') 58 | self.assertIsNone(start) 59 | self.assertIsNone(end) 60 | self.assertEqual(language, u'python3') 61 | 62 | def test_notebook_tag_with_symbol_in_name_language(self): 63 | for short_name in [u'c++', u'cpp-objdump', u'c++-objdumb', u'cxx-objdump']: 64 | markup = u'path/to/thing.ipynb language[{}]'.format(short_name) 65 | src, start, end, language = self.get_argdict(markup) 66 | 67 | self.assertEqual(src, u'path/to/thing.ipynb') 68 | self.assertIsNone(start) 69 | self.assertIsNone(end) 70 | self.assertEqual(language, short_name) 71 | 72 | def test_notebook_tag_with_language_and_cells(self): 73 | markup = u'path/to/thing.ipynb cells[1:5] language[julia]' 74 | src, start, end, language = self.get_argdict(markup) 75 | 76 | self.assertEqual(src, u'path/to/thing.ipynb') 77 | self.assertEqual(start, u'1') 78 | self.assertEqual(end, u'5') 79 | self.assertEqual(language, u'julia') 80 | 81 | def test_notebook_tag_with_language_and_cells_and_weird_spaces(self): 82 | markup = u' path/to/thing.ipynb cells[1:5] language[julia] ' 83 | src, start, end, language = self.get_argdict(markup) 84 | 85 | self.assertEqual(src, u'path/to/thing.ipynb') 86 | self.assertEqual(start, u'1') 87 | self.assertEqual(end, u'5') 88 | self.assertEqual(language, u'julia') 89 | 90 | 91 | if __name__ == '__main__': 92 | unittest.main() -------------------------------------------------------------------------------- /docs/www/pelican-plugins/liquid_tags/test_soundcloud.py: -------------------------------------------------------------------------------- 1 | from . import soundcloud 2 | import pytest 3 | 4 | 5 | @pytest.mark.parametrize('input,expected', [ 6 | ('https://soundcloud.com/forss/in-paradisum', 7 | dict(track_url='https://soundcloud.com/forss/in-paradisum')), 8 | ('http://soundcloud.com/forss/in-paradisum', 9 | dict(track_url='http://soundcloud.com/forss/in-paradisum')), 10 | ('https://soundcloud.com/toroymoi/real-love-ft-kool-ad', 11 | dict(track_url='https://soundcloud.com/toroymoi/real-love-ft-kool-ad')), 12 | ('https://soundcloud.com/capturedtracks/sets/wild-nothing-nocturne', 13 | dict(track_url=('https://soundcloud.com/capturedtracks/' 14 | 'sets/wild-nothing-nocturne'))) 15 | ]) 16 | def test_match_it(input, expected): 17 | assert soundcloud.match_it(input) == expected 18 | 19 | 20 | @pytest.mark.parametrize('input', [ 21 | 'http://foobar.com', 22 | 'foobar', 23 | 'https://google.com' 24 | ]) 25 | def test_match_it_exception(input): 26 | with pytest.raises(ValueError): 27 | soundcloud.match_it(input) 28 | -------------------------------------------------------------------------------- /docs/www/pelican-plugins/liquid_tags/tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | skipsdist = True 3 | minversion = 1.8 4 | envlist = 5 | py{27,34}-ipython2, 6 | py{27,34}-ipython3, 7 | 8 | [testenv] 9 | commands = py.test 10 | 11 | deps = 12 | pytest 13 | pytest-capturelog 14 | pelican 15 | markdown 16 | mock 17 | ipython2: ipython[notebook]>=2,<3 18 | ipython3: ipython[notebook] 19 | -------------------------------------------------------------------------------- /docs/www/pelican-plugins/liquid_tags/video.py: -------------------------------------------------------------------------------- 1 | """ 2 | Video Tag 3 | --------- 4 | This implements a Liquid-style video tag for Pelican, 5 | based on the octopress video tag [1]_ 6 | 7 | Syntax 8 | ------ 9 | {% video url/to/video [width height] [url/to/poster] %} 10 | 11 | Example 12 | ------- 13 | {% video http://site.com/video.mp4 720 480 http://site.com/poster-frame.jpg %} 14 | 15 | Output 16 | ------ 17 | <video width='720' height='480' preload='none' controls poster='http://site.com/poster-frame.jpg'> 18 | <source src='http://site.com/video.mp4' type='video/mp4; codecs=\"avc1.42E01E, mp4a.40.2\"'/> 19 | </video> 20 | 21 | [1] https://github.com/imathis/octopress/blob/master/plugins/video_tag.rb 22 | """ 23 | import os 24 | import re 25 | from .mdx_liquid_tags import LiquidTags 26 | 27 | SYNTAX = "{% video url/to/video [url/to/video] [url/to/video] [width height] [url/to/poster] %}" 28 | 29 | VIDEO = re.compile(r'(/\S+|https?:\S+)(\s+(/\S+|https?:\S+))?(\s+(/\S+|https?:\S+))?(\s+(\d+)\s(\d+))?(\s+(/\S+|https?:\S+))?') 30 | 31 | VID_TYPEDICT = {'.mp4':"type='video/mp4; codecs=\"avc1.42E01E, mp4a.40.2\"'", 32 | '.ogv':"type='video/ogg; codecs=theora, vorbis'", 33 | '.webm':"type='video/webm; codecs=vp8, vorbis'"} 34 | 35 | 36 | @LiquidTags.register('video') 37 | def video(preprocessor, tag, markup): 38 | videos = [] 39 | width = None 40 | height = None 41 | poster = None 42 | 43 | match = VIDEO.search(markup) 44 | if match: 45 | groups = match.groups() 46 | videos = [g for g in groups[0:6:2] if g] 47 | width = groups[6] 48 | height = groups[7] 49 | poster = groups[9] 50 | 51 | if any(videos): 52 | video_out = """ 53 | <div class="videobox"> 54 | <video width="{width}" height="{height}" preload="none" controls poster="{poster}"> 55 | """.format(width=width, height=height, poster=poster).strip() 56 | 57 | for vid in videos: 58 | base, ext = os.path.splitext(vid) 59 | if ext not in VID_TYPEDICT: 60 | raise ValueError("Unrecognized video extension: " 61 | "{0}".format(ext)) 62 | video_out += ("<source src='{0}' " 63 | "{1}>".format(vid, VID_TYPEDICT[ext])) 64 | video_out += "</video></div>" 65 | else: 66 | raise ValueError("Error processing input, " 67 | "expected syntax: {0}".format(SYNTAX)) 68 | 69 | return video_out 70 | 71 | 72 | #---------------------------------------------------------------------- 73 | # This import allows image tag to be a Pelican plugin 74 | from liquid_tags import register 75 | -------------------------------------------------------------------------------- /docs/www/pelican-plugins/liquid_tags/vimeo.py: -------------------------------------------------------------------------------- 1 | """ 2 | Vimeo Tag 3 | --------- 4 | This implements a Liquid-style vimeo tag for Pelican, 5 | based on the youtube tag which is in turn based on 6 | the jekyll / octopress youtube tag [1]_ 7 | 8 | Syntax 9 | ------ 10 | {% vimeo id [width height] %} 11 | 12 | Example 13 | ------- 14 | {% vimeo 10739054 640 480 %} 15 | 16 | Output 17 | ------ 18 | <div style="width:640px; height:480px;"> 19 | <iframe 20 | src="//player.vimeo.com/video/10739054?title=0&byline=0&portrait=0" 21 | width="640" height="480" frameborder="0" 22 | webkitallowfullscreen mozallowfullscreen allowfullscreen> 23 | </iframe> 24 | </div> 25 | 26 | [1] https://gist.github.com/jamieowen/2063748 27 | """ 28 | import re 29 | from .mdx_liquid_tags import LiquidTags 30 | 31 | SYNTAX = "{% vimeo id [width height] %}" 32 | 33 | VIMEO = re.compile(r'(\S+)(\s+(\d+)\s(\d+))?') 34 | 35 | 36 | @LiquidTags.register('vimeo') 37 | def vimeo(preprocessor, tag, markup): 38 | width = 640 39 | height = 390 40 | vimeo_id = None 41 | 42 | match = VIMEO.search(markup) 43 | if match: 44 | groups = match.groups() 45 | vimeo_id = groups[0] 46 | width = groups[2] or width 47 | height = groups[3] or height 48 | 49 | if vimeo_id: 50 | vimeo_out = """ 51 | <div class="videobox"> 52 | <iframe 53 | src="//player.vimeo.com/video/{vimeo_id}?title=0&byline=0&portrait=0" 54 | width="{width}" height="{height}" frameborder="0" 55 | webkitAllowFullScreen mozallowfullscreen allowFullScreen> 56 | </iframe> 57 | </div> 58 | """.format(width=width, height=height, vimeo_id=vimeo_id).strip() 59 | else: 60 | raise ValueError("Error processing input, " 61 | "expected syntax: {0}".format(SYNTAX)) 62 | 63 | return vimeo_out 64 | 65 | 66 | # --------------------------------------------------- 67 | # This import allows vimeo tag to be a Pelican plugin 68 | from liquid_tags import register # noqa 69 | -------------------------------------------------------------------------------- /docs/www/pelican-plugins/liquid_tags/youtube.py: -------------------------------------------------------------------------------- 1 | """ 2 | Youtube Tag 3 | --------- 4 | This implements a Liquid-style youtube tag for Pelican, 5 | based on the jekyll / octopress youtube tag [1]_ 6 | 7 | Syntax 8 | ------ 9 | {% youtube id [width height] %} 10 | 11 | Example 12 | ------- 13 | {% youtube dQw4w9WgXcQ 640 480 %} 14 | 15 | Output 16 | ------ 17 | <iframe 18 | width="640" height="480" src="https://www.youtube.com/embed/dQw4w9WgXcQ" 19 | frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen> 20 | </iframe> 21 | 22 | [1] https://gist.github.com/jamieowen/2063748 23 | """ 24 | import re 25 | from .mdx_liquid_tags import LiquidTags 26 | 27 | SYNTAX = "{% youtube id [width height] %}" 28 | 29 | YOUTUBE = re.compile(r'([\S]+)(\s+(\d+)\s(\d+))?') 30 | 31 | 32 | @LiquidTags.register('youtube') 33 | def youtube(preprocessor, tag, markup): 34 | width = 640 35 | height = 390 36 | youtube_id = None 37 | 38 | match = YOUTUBE.search(markup) 39 | if match: 40 | groups = match.groups() 41 | youtube_id = groups[0] 42 | width = groups[2] or width 43 | height = groups[3] or height 44 | 45 | if youtube_id: 46 | youtube_out = """ 47 | <div class="videobox"> 48 | <iframe width="{width}" height="{height}" 49 | src='https://www.youtube.com/embed/{youtube_id}' 50 | frameborder='0' webkitAllowFullScreen mozallowfullscreen 51 | allowFullScreen> 52 | </iframe> 53 | </div> 54 | """.format(width=width, height=height, youtube_id=youtube_id).strip() 55 | else: 56 | raise ValueError("Error processing input, " 57 | "expected syntax: {0}".format(SYNTAX)) 58 | 59 | return youtube_out 60 | 61 | 62 | # --------------------------------------------------- 63 | # This import allows image tag to be a Pelican plugin 64 | from liquid_tags import register # noqa 65 | -------------------------------------------------------------------------------- /docs/www/pelicanconf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- # 3 | from __future__ import unicode_literals 4 | 5 | AUTHOR = u'IPython development team and Enthought, Inc.' 6 | SITENAME = u'DistArray' 7 | SITEURL = '' 8 | 9 | PATH = 'content' 10 | 11 | TIMEZONE = 'America/Chicago' 12 | 13 | DEFAULT_LANG = u'en' 14 | 15 | # Feed generation is usually not desired when developing 16 | FEED_ALL_ATOM = None 17 | CATEGORY_FEED_ATOM = None 18 | TRANSLATION_FEED_ATOM = None 19 | 20 | MENUITEMS = ( 21 | ('HOME', '/'), 22 | ('FEATURES', '/pages/features.html'), 23 | ('RELEASE NOTES', '/category/release-notes.html'), 24 | ('TALKS', '/category/talks.html'), 25 | ('CONTACT', '/pages/contact.html'), 26 | ) 27 | 28 | 29 | LINKS = ( 30 | ('DistArray Docs', 'http://distarray.readthedocs.org/'), 31 | ('Distributed Array Protocol', 'http://distributed-array-protocol.readthedocs.org'), 32 | ('Mailing List', 'https://groups.google.com/forum/#!forum/distarray'), 33 | ('SciPy', 'http://www.scipy.org/'), 34 | ('IPython', 'http://ipython.org/'), 35 | ('Enthought', 'http://www.enthought.com/'), 36 | ) 37 | 38 | SOCIAL = ( 39 | ('github', 'https://github.com/enthought/distarray'), 40 | ('twitter', 'https://twitter.com/enthought'), 41 | ) 42 | 43 | DEFAULT_PAGINATION = False 44 | CACHE_CONTENT = False 45 | SLUGIFY_SOURCE = 'basename' 46 | PYGMENTS_STYLE = 'default' 47 | 48 | SITELOGO = 'images/distarray-logo.png' 49 | SITELOGO_SIZE = 230 50 | HIDE_SITENAME = True 51 | 52 | DISPLAY_CATEGORIES_ON_MENU = False 53 | DISPLAY_PAGES_ON_MENU = False 54 | DISPLAY_TAGS_ON_SIDEBAR = False 55 | 56 | # Uncomment following line if you want document-relative URLs when developing 57 | #RELATIVE_URLS = True 58 | 59 | # pelican-bootstrap3 settings 60 | THEME = "./pelican-bootstrap3/" 61 | BOOTSTRAP_THEME = "enthought_dark" 62 | SHOW_ARTICLE_AUTHOR = False 63 | DISPLAY_ARTICLE_INFO_ON_INDEX = False 64 | 65 | PLUGIN_PATHS = ['./pelican-plugins'] 66 | PLUGINS = ['liquid_tags.notebook'] 67 | -------------------------------------------------------------------------------- /docs/www/publishconf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- # 3 | from __future__ import unicode_literals 4 | 5 | # This file is only used if you use `make publish` or 6 | # explicitly specify it as your config file. 7 | 8 | import os 9 | import sys 10 | sys.path.append(os.curdir) 11 | from pelicanconf import * 12 | 13 | SITEURL = 'http://docs.enthought.com/distarray' 14 | RELATIVE_URLS = False 15 | 16 | MENUITEMS = [(name, SITEURL + url) for (name, url) in MENUITEMS] 17 | 18 | FEED_ALL_ATOM = 'feeds/all.atom.xml' 19 | CATEGORY_FEED_ATOM = 'feeds/%s.atom.xml' 20 | 21 | DELETE_OUTPUT_DIRECTORY = True 22 | 23 | # Following items are often useful when publishing 24 | 25 | #DISQUS_SITENAME = "" 26 | #GOOGLE_ANALYTICS = "" 27 | -------------------------------------------------------------------------------- /examples/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enthought/distarray/0e014e4d08e6745f5028a53132a424f909ca354e/examples/__init__.py -------------------------------------------------------------------------------- /examples/distarray_protocol/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enthought/distarray/0e014e4d08e6745f5028a53132a424f909ca354e/examples/distarray_protocol/__init__.py -------------------------------------------------------------------------------- /examples/distarray_protocol/images/README.txt: -------------------------------------------------------------------------------- 1 | This file exists so that git will create this folder. 2 | The array distribution plots are written here so we want to ensure that it exists. 3 | 4 | -------------------------------------------------------------------------------- /examples/gauss_elimination/img1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enthought/distarray/0e014e4d08e6745f5028a53132a424f909ca354e/examples/gauss_elimination/img1.png -------------------------------------------------------------------------------- /examples/julia_set/.gitignore: -------------------------------------------------------------------------------- 1 | kernel.c 2 | *.json 3 | -------------------------------------------------------------------------------- /examples/julia_set/README.md: -------------------------------------------------------------------------------- 1 | README: Julia Set 2 | =============== 3 | 4 | This example calculates some 5 | [Julia sets](https://en.wikipedia.org/wiki/Julia_set) using distarray and 6 | measures the performance. The code provides the user a choice of the kernel to 7 | use for computation. Unsurprisingly, the fastest kernel turns out to be the 8 | Cython kernel which must be compiled before we can perform any computation: 9 | 10 | `python setup.py build_ext --inplace` 11 | 12 | With the Cython kernel ready to go, we use the `benchmark_julia.py` script to 13 | generate our performance data, the usage of which is as follows: 14 | 15 | ``` 16 | usage: benchmark_julia.py [-h] [-r REPEAT_COUNT] [-o OUTPUT_FILENAME] 17 | [-k {fancy,numpy,cython}] [-s {strong,weak}] N [N ...] 18 | 19 | positional arguments: 20 | N resolutions of the Julia set to benchmark (NxN) 21 | 22 | optional arguments: 23 | -h, --help show this help message and exit 24 | -r REPEAT_COUNT, --repeat REPEAT_COUNT 25 | number of repetitions of each unique parameter set, 26 | default: 3 27 | -o OUTPUT_FILENAME, --output-filename OUTPUT_FILENAME 28 | filename to write the json data to. 29 | -k {fancy,numpy,cython}, --kernel {fancy,numpy,cython} 30 | kernel to use for computation. Options are 'fancy', 31 | 'numpy', or 'cython'. 32 | -s {strong,weak}, --scaling {strong,weak} 33 | Kind of scaling test. Options are 'strong' or 'weak' 34 | ``` 35 | 36 | This script can be invoked as follows: 37 | 38 | ``` 39 | mpiexec -np NPROC python benchmark_julia.py [-h] [-r REPEAT_COUNT] 40 | [-o OUTPUT_FILENAME] [-k {fancy,numpy,cython}] 41 | [-s {strong,weak}] N [N ...] 42 | ``` 43 | 44 | Where `NPROC` is the number of MPI processes to be used 45 | (`1` client + `N-1` workers). The results contained in the `OUTPUT_FILENAME` 46 | can be plotted using the `plot_results.py` script: 47 | 48 | ``` 49 | python plot_results.py OUTPUT_FILENAME 50 | ``` 51 | 52 | The `mpi_benchmark ` script can also be used to drive program execution. 53 | Here the number of MPI processes is hardcoded into the script. 54 | Command-line usage of the script is as follows: 55 | 56 | ``` 57 | usage: ./mpi_benchmark <reps> <output_filename> <kernel> <resolution> 58 | ``` 59 | -------------------------------------------------------------------------------- /examples/julia_set/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enthought/distarray/0e014e4d08e6745f5028a53132a424f909ca354e/examples/julia_set/__init__.py -------------------------------------------------------------------------------- /examples/julia_set/kernel.pyx: -------------------------------------------------------------------------------- 1 | # cython: boundscheck=False 2 | # cython: wraparound=False 3 | 4 | cimport cython 5 | import numpy as np 6 | 7 | def fill_complex_plane(arr, re_ax, im_ax, resolution): 8 | """Fill in points on the complex coordinate plane.""" 9 | # Drawing the coordinate plane directly like this is currently much 10 | # faster than trying to do it by indexing a distarray. 11 | # This may not be the most DistArray-thonic way to do this. 12 | 13 | cdef: 14 | float _re_ax0 = re_ax[0] 15 | float _im_ax0 = im_ax[0] 16 | float re_step = float(re_ax[1] - re_ax[0]) / resolution[0] 17 | float im_step = float(im_ax[1] - im_ax[0]) / resolution[1] 18 | unsigned int row_start, col_start, row_step, col_step, nrow, ncol, i, j, glb_i, glb_j 19 | float complex[:,::1] _arr = np.asarray(arr, dtype=np.complex64) 20 | 21 | s0, s1 = arr.distribution.global_slice 22 | row_start, row_step = s0.start, (s0.step or 1) 23 | d1 = arr.distribution[1] 24 | col_start, col_step = s1.start, (s1.step or 1) 25 | 26 | nrow = _arr.shape[0] 27 | ncol = _arr.shape[1] 28 | 29 | for i in range(nrow): 30 | glb_i = row_start + i * row_step 31 | for j in range(ncol): 32 | glb_j = col_start + j * col_step 33 | _arr[i, j].real = _re_ax0 + re_step * glb_i 34 | _arr[i, j].imag = _im_ax0 + im_step * glb_j 35 | 36 | 37 | cdef inline float cabs2(float complex z): 38 | return z.real * z.real + z.imag * z.imag 39 | 40 | 41 | def cython_julia_calc(_z, float complex c, 42 | float z_max, unsigned int n_max): 43 | 44 | cdef: 45 | float complex[:,::1] z = np.asarray(_z, dtype=np.complex64) 46 | float complex zt 47 | float z_max2 = z_max * z_max 48 | unsigned int nrow, ncol, i, j, count 49 | unsigned int[:,::1] counts = np.zeros_like(z, dtype=np.uint32) 50 | 51 | nrow = z.shape[0]; ncol = z.shape[1] 52 | for i in range(nrow): 53 | for j in range(ncol): 54 | zt = z[i,j] 55 | count = 0 56 | while cabs2(zt) < z_max2 and count < n_max: 57 | zt = zt * zt + c 58 | count += 1 59 | counts[i,j] = count 60 | 61 | return np.asarray(counts) 62 | -------------------------------------------------------------------------------- /examples/julia_set/mpi_benchmark: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Usage: mpi_benchmark <reps> <output_filename> <kernel> <resolution> 4 | 5 | mpiexec -n 13 python benchmark_julia.py -r$1 -o$2 --kernel=$3 $4 6 | -------------------------------------------------------------------------------- /examples/julia_set/setup.py: -------------------------------------------------------------------------------- 1 | from distutils.core import setup, Extension 2 | from Cython.Build import cythonize 3 | 4 | ext = Extension(name="kernel", sources=["kernel.pyx"]) 5 | 6 | setup(name="kernel", 7 | ext_modules=cythonize(ext)) 8 | -------------------------------------------------------------------------------- /examples/pi_montecarlo/README.rst: -------------------------------------------------------------------------------- 1 | Estimate pi using a Monte Carlo method 2 | ====================================== 3 | 4 | If we imagine a unit circle inscribed within a unit square, the ratio of the 5 | area of the circle to the area of the square is pi/4. So if a point is chosen 6 | at random within the square, it has a pi/4 probability of being inside the 7 | circle too. 8 | 9 | So we choose one N points in the square, count how many are in the circle and 10 | divide by N to give an estimation of pi/4. We then multiply by 4 to get pi. 11 | 12 | The convergence of this method is very slow O(n**-0.5). 13 | 14 | - ``pi_numpy.py`` uses pure numpy to estimate pi. 15 | 16 | - ``pi_ipython_parallel.py`` use IPython.parallel to estimate pi. 17 | 18 | - ``pi_distarray.py`` uses distarray to estimate pi. 19 | 20 | - ``benchmark.py`` benchmarks the methods. 21 | -------------------------------------------------------------------------------- /examples/pi_montecarlo/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enthought/distarray/0e014e4d08e6745f5028a53132a424f909ca354e/examples/pi_montecarlo/__init__.py -------------------------------------------------------------------------------- /examples/pi_montecarlo/benchmark.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # --------------------------------------------------------------------------- 3 | # Copyright (C) 2008-2014, IPython Development Team and Enthought, Inc. 4 | # Distributed under the terms of the BSD License. See COPYING.rst. 5 | # --------------------------------------------------------------------------- 6 | 7 | """ 8 | Benchmark all the scripts. 9 | """ 10 | 11 | import timeit 12 | 13 | from matplotlib import pyplot as plt 14 | 15 | import pi_numpy 16 | import pi_distarray 17 | import pi_ipython_parallel 18 | 19 | 20 | def bench(module, n_list): 21 | times = [] 22 | module_name = module.__name__ 23 | for n in n_list: 24 | t = timeit.timeit("{}.calc_pi({})".format(module_name, n), 25 | setup="from __main__ import {}".format(module_name), 26 | number=1) 27 | times.append(t) 28 | return times 29 | 30 | 31 | def main(n): 32 | # n is maximum order of magnitude for the number of iterations. 33 | n_list = [2**i for i in range(3, n)] 34 | 35 | # Do the benchmarking. 36 | print("Benchmarking IPython.parallel") 37 | ipython_parallel_times = bench(pi_ipython_parallel, n_list) 38 | pi_ipython_parallel.client.close() 39 | print("Benchmarking NumPy") 40 | numpy_times = bench(pi_numpy, n_list) 41 | print("Benchmarking distarray") 42 | distarray_times = bench(pi_distarray, n_list) 43 | 44 | # plot the data 45 | fig = plt.figure() 46 | ax = fig.add_subplot(111) 47 | ax.plot(n_list, distarray_times, lw=2, label='distarray') 48 | ax.plot(n_list, ipython_parallel_times, lw=2, label='IPython.parallel') 49 | ax.plot(n_list, numpy_times, lw=2, label='NumPy') 50 | 51 | # annotations 52 | ax.set_xscale('log') 53 | ax.set_yscale('log') 54 | ax.set_xlabel('number of iterations (n)') 55 | ax.set_ylabel('seconds (s)') 56 | ax.legend(loc='upper left') 57 | ax.set_title('Benchmark Monte Carlo Estimation of $\pi$') 58 | 59 | # Save to plot.png. 60 | plt.savefig('plot') 61 | 62 | 63 | if __name__ == '__main__': 64 | import argparse 65 | formatter = argparse.RawDescriptionHelpFormatter 66 | parser = argparse.ArgumentParser(description=__doc__, 67 | formatter_class=formatter) 68 | parser.add_argument("n", metavar="n", type=int, 69 | help=("the power of 2 for the maximum number of points benchmarked. i.e. N = 2**n where N is the number of points used.")) 70 | args = parser.parse_args() 71 | main(args.n) 72 | -------------------------------------------------------------------------------- /examples/pi_montecarlo/pi_distarray.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # --------------------------------------------------------------------------- 3 | # Copyright (C) 2008-2014, IPython Development Team and Enthought, Inc. 4 | # Distributed under the terms of the BSD License. See COPYING.rst. 5 | # --------------------------------------------------------------------------- 6 | 7 | """ 8 | Estimate pi using a Monte Carlo method with distarray. 9 | """ 10 | 11 | from __future__ import division, print_function 12 | 13 | from util import timer 14 | 15 | from distarray.globalapi import Context, Distribution, hypot 16 | from distarray.globalapi.random import Random 17 | 18 | 19 | context = Context() 20 | random = Random(context) 21 | 22 | 23 | @timer 24 | def calc_pi(n): 25 | """Estimate pi using distributed NumPy arrays.""" 26 | distribution = Distribution(context=context, shape=(n,)) 27 | x = random.rand(distribution) 28 | y = random.rand(distribution) 29 | r = hypot(x, y) 30 | mask = (r < 1) 31 | return 4 * mask.sum().toarray() / n 32 | 33 | 34 | def main(N): 35 | result, time = calc_pi(N) 36 | print('time : %3.4g\nresult: %.7f' % (time, result)) 37 | 38 | 39 | if __name__ == '__main__': 40 | import argparse 41 | formatter = argparse.RawDescriptionHelpFormatter 42 | parser = argparse.ArgumentParser(description=__doc__, 43 | formatter_class=formatter) 44 | parser.add_argument("npoints", metavar="N", type=int, 45 | help=("number of points to use in estimation")) 46 | args = parser.parse_args() 47 | main(args.npoints) 48 | -------------------------------------------------------------------------------- /examples/pi_montecarlo/pi_ipython_parallel.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # --------------------------------------------------------------------------- 3 | # Copyright (C) 2008-2014, IPython Development Team and Enthought, Inc. 4 | # Distributed under the terms of the BSD License. See COPYING.rst. 5 | # --------------------------------------------------------------------------- 6 | 7 | """ 8 | Calculate pi using a Monte Carlo method using IPython Parallel. 9 | """ 10 | 11 | from IPython.parallel import Client, interactive 12 | 13 | from util import timer 14 | 15 | client = Client() 16 | view = client[:] 17 | view.execute('import numpy') 18 | 19 | 20 | @interactive # this runs on the engins 21 | def calc_pi_on_engines(n): 22 | x = numpy.random.rand(n) 23 | y = numpy.random.rand(n) 24 | r = numpy.hypot(x, y) 25 | return 4. * (r < 1.).sum() / n 26 | 27 | 28 | @timer 29 | def calc_pi(n): 30 | """Estimate pi using IPython.parallel.""" 31 | n_engines = n/len(view) 32 | results = view.apply_sync(calc_pi_on_engines, n_engines) 33 | return float(sum(results))/len(results) 34 | 35 | 36 | def main(N): 37 | result, time = calc_pi(N) 38 | print('time : %3.4g\nresult: %.7f' % (time, result)) 39 | client.purge_everything() 40 | 41 | 42 | if __name__ == '__main__': 43 | import argparse 44 | formatter = argparse.RawDescriptionHelpFormatter 45 | parser = argparse.ArgumentParser(description=__doc__, 46 | formatter_class=formatter) 47 | parser.add_argument("npoints", metavar="N", type=int, 48 | help=("number of points to use in estimation")) 49 | args = parser.parse_args() 50 | main(args.npoints) 51 | -------------------------------------------------------------------------------- /examples/pi_montecarlo/pi_numpy.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # --------------------------------------------------------------------------- 3 | # Copyright (C) 2008-2014, IPython Development Team and Enthought, Inc. 4 | # Distributed under the terms of the BSD License. See COPYING.rst. 5 | # --------------------------------------------------------------------------- 6 | 7 | """ 8 | Calculate pi using a Monte Carlo method using pure NumPy. 9 | """ 10 | 11 | import numpy 12 | from numpy import random 13 | 14 | from util import timer 15 | 16 | 17 | @timer 18 | def calc_pi(n): 19 | """Estimate pi using pure NumPy.""" 20 | x = random.rand(n) 21 | y = random.rand(n) 22 | r = numpy.hypot(x, y) 23 | return 4 * float((r < 1.).sum()) / n 24 | 25 | 26 | def main(N): 27 | result, time = calc_pi(N) 28 | print('time : %3.4g\nresult: %.7f' % (time, result)) 29 | 30 | 31 | if __name__ == '__main__': 32 | import argparse 33 | formatter = argparse.RawDescriptionHelpFormatter 34 | parser = argparse.ArgumentParser(description=__doc__, 35 | formatter_class=formatter) 36 | parser.add_argument("npoints", metavar="N", type=int, 37 | help=("number of points to use in estimation")) 38 | args = parser.parse_args() 39 | main(args.npoints) 40 | -------------------------------------------------------------------------------- /examples/pi_montecarlo/util.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # --------------------------------------------------------------------------- 3 | # Copyright (C) 2008-2014, IPython Development Team and Enthought, Inc. 4 | # Distributed under the terms of the BSD License. See COPYING.rst. 5 | # --------------------------------------------------------------------------- 6 | 7 | from timeit import default_timer as clock 8 | from functools import wraps 9 | 10 | 11 | def timer(fn): 12 | @wraps(fn) 13 | def _timer(*args, **kwargs): 14 | start = clock() 15 | result = fn(*args, **kwargs) 16 | stop = clock() 17 | return (result, stop - start) 18 | return _timer 19 | -------------------------------------------------------------------------------- /examples/seismic_volume/README.rst: -------------------------------------------------------------------------------- 1 | Processing a Seismic Volume 2 | =========================== 3 | 4 | This example shows some processing using DistArray on a simulated seismic 5 | volume. The volume can be stored either as an HDF5 file, or as a set of .dnpy 6 | files. 7 | 8 | If you have an MPI-enabled HDF5 library, you can use that for loading and 9 | saving these files. Otherwise you can use our .dnpy flat file format with no 10 | external dependencies. By default the HDF5 file format is used, but you can 11 | pass ``--dnpy`` as a command line argument to both scripts to use the flat file 12 | format instead. 13 | 14 | create_volume.py 15 | ---------------- 16 | 17 | This script creates a simulated seismic volume. The internal structure of the 18 | volume includes two 'horizons', which are plane surfaces inside the volume. As 19 | one moves down in depth, approaching and then crossing the horizon, the data 20 | values increase with a Gaussian peak at the horizon and then settle down to a 21 | larger value than above the horizon. 22 | 23 | If you would like array dimensions other than the default, you can pass 24 | ``--size NX NY NZ`` as command line arguments to get a volume with shape (NX, 25 | NY, NZ). Other values in the script can also be modified to change the values 26 | in the volume array. 27 | 28 | The seismic volume is written either to a .hdf5 file named seismic.hdf5 or a 29 | set of .dnpy files named seismic_0.dnpy, seismic_1.dnpy, and so on. 30 | 31 | load_volume.py 32 | -------------- 33 | 34 | This script loads the volume and performs several processing steps on it. 35 | First, the seismic volume is loaded in parallel into a DistArray. The script 36 | then loops over all of the traces (z-slices constant in x and y) and calculates 37 | some statistics on each trace (i.e. min, max, average, and standard deviation). 38 | Next, the script applies a couple of filters on each trace. The first filter 39 | is a 3-point average, and the second filter is a 3-point maximum. Then, the 40 | script extracts three slices from the seismic volume on all three principal 41 | axes and creates a plot for each slice. The script also extracts slices and 42 | makes plots from the result of the 3-point average filter. Finally, the result 43 | of the 3-point average filter is written out to a .hdf5 file and to a set of 44 | .dnpy files. 45 | 46 | The script will also perform many of these operations using NumPy directly and 47 | check that it gets the same results as when operating on the distributed array. 48 | 49 | seismic_volume.ipynb 50 | -------------------- 51 | 52 | This is a simplified version of the above example as an IPython notebook. 53 | -------------------------------------------------------------------------------- /examples/seismic_volume/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enthought/distarray/0e014e4d08e6745f5028a53132a424f909ca354e/examples/seismic_volume/__init__.py -------------------------------------------------------------------------------- /quickstart/conda-readme.rst: -------------------------------------------------------------------------------- 1 | conda-quickstart 2 | ================ 3 | 4 | [OS X or Linux] 5 | 6 | Note: this script is currently *experimental*. 7 | 8 | The ``conda-quickstart`` script attempts to create a new conda environment that 9 | includes DistArray, its dependencies, and the dependencies required to build 10 | the DistArray docs. 11 | 12 | This script does *not* attempt to install parallel versions of hdf5 or h5py, 13 | which are optional dependencies. 14 | 15 | ``conda-quickstart`` is intended to be run from within this directory 16 | 17 | Depending on system hardware and the prior availability of dependencies, the 18 | script can take anywhere from less than a minute up to a few hours to run. If 19 | the installation is interrupted for any reason, delete the created conda 20 | environment (``conda env remove -n <env-name>``) and re-run the script. 21 | 22 | Prerequisites 23 | ------------- 24 | 25 | Prerequisites for using ``conda-quickstart`` are: 26 | 27 | - A working Anaconda or Miniconda installation 28 | 29 | Additionally, OSX users will need: 30 | 31 | - A working MPI distribution that provides the ``mpicc`` compiler wrapper 32 | - *OR* a working copy of HomeBrew or MacPorts to install MPI (MacPorts users will 33 | need 'sudo' privileges) 34 | 35 | Notes on OS X 36 | ------------- 37 | 38 | On OSX, ``conda-quickstart`` will install 39 | 40 | - Open MPI with MacPorts or Homebrew, if ``mpicc`` isn't found, 41 | - several Python dependencies using ``conda``, and finally 42 | - a couple of Python dependencies (those not installable with ``conda``) 43 | through ``pip``. 44 | 45 | Notes on Linux 46 | -------------- 47 | 48 | On Linux, ``conda-quickstart`` will install 49 | 50 | - Several Python dependencies using ``conda`` (including MPICH2 and mpi4py), 51 | and 52 | - a couple of Python dependencies (those not installable with ``conda``) 53 | through ``pip``. 54 | -------------------------------------------------------------------------------- /quickstart/enpkg-readme.rst: -------------------------------------------------------------------------------- 1 | enpkg-quickstart 2 | ================ 3 | 4 | [OS X only] 5 | 6 | Note: this script is currently *experimental*. 7 | 8 | The ``enpkg-quickstart`` script attempts to install DistArray, its 9 | dependencies, and the dependencies needed to build the DistArray docs. This 10 | script is intended to work with your Enthought Canopy installation. This 11 | script may update existing packages. 12 | 13 | This script does *not* attempt to install parallel versions of hdf5 or h5py, 14 | which are optional dependencies. 15 | 16 | ``enpkg-quickstart`` is intended to be run from within this directory. 17 | 18 | Depending on your system hardware and the prior availability of dependencies, 19 | the script can take anywhere from less than a minute up to a few hours to run. 20 | 21 | Prerequisites 22 | ------------- 23 | 24 | Prerequisites for using ``enpkg-quickstart`` are: 25 | 26 | - A working Canopy or EPD installation, and 27 | 28 | - A working MPI distribution that provides the ``mpicc`` compiler wrapper 29 | - *OR* a working copy of HomeBrew or MacPorts to install MPI (MacPorts users 30 | will need 'sudo' privileges) 31 | 32 | 33 | Notes 34 | ----- 35 | 36 | ``enpkg-quickstart`` will install 37 | 38 | - Open MPI with MacPorts or Homebrew, if ``mpicc`` isn't found, 39 | - several Python dependencies using ``enpkg``, and finally 40 | - a couple of Python dependencies (those not installable with enpkg) through 41 | ``pip``. 42 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # ----------------------------------------------------------------------------- 3 | # Copyright (C) 2008-2014, IPython Development Team and Enthought, Inc. 4 | # Distributed under the terms of the BSD License. See COPYING.rst. 5 | # ----------------------------------------------------------------------------- 6 | 7 | import os 8 | from setuptools import setup, find_packages 9 | from distarray.__version__ import __version__ 10 | 11 | # let our mocks work on ReadTheDocs 12 | on_rtd = os.environ.get('READTHEDOCS', None) == 'True' 13 | if on_rtd: 14 | install_requires = [] 15 | else: 16 | install_requires = [ 17 | 'ipyparallel', 18 | 'numpy', 19 | 'mpi4py' 20 | ] 21 | 22 | 23 | def parse_readme(filename='README.rst', sentinel="README"): 24 | """ 25 | Return file `filename` as a string. 26 | 27 | Skips lines until it finds a comment that contains `sentinel` text. This 28 | effectively strips off any badges or other undesirable content. 29 | """ 30 | with open(filename, 'r') as fp: 31 | lines = fp.readlines() 32 | for idx, line in enumerate(lines): 33 | if line.startswith('..') and sentinel in line: 34 | break 35 | return "".join(lines[idx+1:]) 36 | 37 | 38 | if __name__ == "__main__": 39 | 40 | metadata = { 41 | 'name': 'distarray', 42 | 'version': __version__, 43 | 'description': 'Distributed Memory Arrays for Python', 44 | 'keywords': 'parallel mpi distributed array', 45 | 'license': 'New BSD', 46 | 'author': 'IPython Development Team and Enthought, Inc.', 47 | 'maintainer': "DistArray Developers", 48 | 'maintainer_email': "distarray@googlegroups.com", 49 | 'url': 'https://github.com/enthought/distarray', 50 | 'packages': find_packages(), 51 | 'install_requires': install_requires, 52 | 'long_description': parse_readme(), 53 | 'platforms': ["Linux", "Mac OS-X"], 54 | 'entry_points': {'console_scripts': ['dacluster = ' 55 | 'distarray.apps.dacluster:main']}, 56 | 'classifiers': [c.strip() for c in """\ 57 | Development Status :: 3 - Alpha 58 | Intended Audience :: Developers 59 | Intended Audience :: Science/Research 60 | License :: OSI Approved :: BSD License 61 | Operating System :: MacOS 62 | Operating System :: OS Independent 63 | Operating System :: POSIX 64 | Operating System :: Unix 65 | Programming Language :: Python 66 | Topic :: Scientific/Engineering 67 | Topic :: Software Development 68 | Topic :: Software Development :: Libraries 69 | """.splitlines() if len(c.strip()) > 0], 70 | } 71 | 72 | setup(**metadata) 73 | -------------------------------------------------------------------------------- /utils/git-hooks/install-hooks.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | DOTGIT=`git rev-parse --git-dir` 4 | TOPLEVEL=`git rev-parse --show-toplevel` 5 | TO=${DOTGIT}/hooks 6 | FROM=${TOPLEVEL}/utils/git-hooks 7 | 8 | ln -s ${FROM}/pre-commit ${TO}/pre-commit 9 | -------------------------------------------------------------------------------- /utils/git-hooks/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | git diff --cached | flake8 --diff 4 | -------------------------------------------------------------------------------- /utils/iopubwatcher.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | """ 3 | A script for watching all traffic on the IOPub channel (stdout/stderr/pyerr) of 4 | engines. 5 | 6 | This connects to the default cluster, or you can pass the path to your 7 | ipcontroller-client.json 8 | 9 | Try running this script, and then running a few jobs that print (and call 10 | sys.stdout.flush), and you will see the print statements as they arrive, 11 | notably not waiting for the results to finish. 12 | 13 | You can use the zeromq SUBSCRIBE mechanism to only receive information from 14 | specific engines, and easily filter by message type. 15 | 16 | Authors 17 | ------- 18 | * MinRK 19 | """ 20 | 21 | import sys 22 | import json 23 | import zmq 24 | 25 | from IPython.kernel.zmq.session import Session 26 | from IPython.utils.py3compat import str_to_bytes 27 | from IPython.utils.path import get_security_file 28 | 29 | 30 | def main(connection_file): 31 | """watch iopub channel, and print messages""" 32 | 33 | ctx = zmq.Context.instance() 34 | 35 | with open(connection_file) as f: 36 | cfg = json.loads(f.read()) 37 | 38 | reg_url = cfg['interface'] 39 | iopub_port = cfg['iopub'] 40 | iopub_url = "%s:%s" % (reg_url, iopub_port) 41 | 42 | session = Session(key=str_to_bytes(cfg['key'])) 43 | sub = ctx.socket(zmq.SUB) 44 | 45 | # This will subscribe to all messages: 46 | sub.setsockopt(zmq.SUBSCRIBE, b'') 47 | # replace with b'' with b'engine.1.stdout' to subscribe only to engine 1's 48 | # stdout 0MQ subscriptions are simple 'foo*' matches, so 'engine.1.' 49 | # subscribes to everything from engine 1, but there is no way to subscribe 50 | # to just stdout from everyone. multiple calls to subscribe will add 51 | # subscriptions, e.g. to subscribe to engine 1's stderr and engine 2's 52 | # stdout: sub.setsockopt(zmq.SUBSCRIBE, b'engine.1.stderr') 53 | # sub.setsockopt(zmq.SUBSCRIBE, b'engine.2.stdout') 54 | sub.connect(iopub_url) 55 | while True: 56 | try: 57 | idents, msg = session.recv(sub, mode=0) 58 | except KeyboardInterrupt: 59 | return 60 | # ident always length 1 here 61 | topic = idents[0] 62 | if msg['msg_type'] == 'stream': 63 | # stdout/stderr 64 | # stream names are in msg['content']['name'], if you want to handle 65 | # them differently 66 | print("%s: %s" % (topic, msg['content']['data'])) 67 | elif msg['msg_type'] == 'pyerr': 68 | # Python traceback 69 | c = msg['content'] 70 | print(topic + b':') 71 | for line in c['traceback']: 72 | # indent lines 73 | print(' ' + line) 74 | 75 | if __name__ == '__main__': 76 | if len(sys.argv) > 1: 77 | cf = sys.argv[1] 78 | else: 79 | # This gets the security file for the default profile: 80 | cf = get_security_file('ipcontroller-client.json') 81 | main(cf) 82 | -------------------------------------------------------------------------------- /utils/test_h5py.py: -------------------------------------------------------------------------------- 1 | """ 2 | Simple test of a parallel build of h5py (from h5py's documentation). 3 | 4 | http://h5py.readthedocs.org/en/latest/mpi.html#using-parallel-hdf5-from-h5py 5 | 6 | If you've built h5py properly against a parallel build of hdf5, you should be 7 | able to run this code with:: 8 | 9 | $ mpiexec -n 4 python test_h5py.py 10 | 11 | and then check the output with `h5dump`:: 12 | 13 | $ h5dump parallel_test.hdf5 14 | HDF5 "parallel_test.hdf5" { 15 | GROUP "/" { 16 | DATASET "test" { 17 | DATATYPE H5T_STD_I32LE 18 | DATASPACE SIMPLE { ( 4 ) / ( 4 ) } 19 | DATA { 20 | (0): 0, 1, 2, 3 21 | } 22 | } 23 | } 24 | } 25 | """ 26 | 27 | from mpi4py import MPI 28 | import h5py 29 | 30 | rank = MPI.COMM_WORLD.rank # The process ID (integer 0-3 for 4-process run) 31 | 32 | f = h5py.File('parallel_test.hdf5', 'w', driver='mpio', comm=MPI.COMM_WORLD) 33 | 34 | dset = f.create_dataset('test', (4,), dtype='i') 35 | dset[rank] = rank 36 | 37 | f.close() 38 | --------------------------------------------------------------------------------