96 Commits

Author SHA1 Message Date
Documenter.jl c88a265718 build based on 8b9029c 2025-09-24 05:38:05 +00:00
Documenter.jl d71de31d77 build based on 62fcf5a 2025-09-15 15:34:20 +00:00
Documenter.jl 755669d4ef build based on 788d7f3 2025-09-08 10:08:36 +00:00
Documenter.jl e80f59fe3f build based on 42a4855 2025-09-05 13:22:07 +00:00
Documenter.jl 738d34a2ec build based on e7b6ba8 2025-09-04 14:27:26 +00:00
Documenter.jl 2c03eb8f46 build based on 57c8db5 2025-08-27 09:46:20 +00:00
Documenter.jl 4be9a0d169 build based on 072476e 2024-10-07 12:14:58 +00:00
Documenter.jl 208fed1dac build based on 20c92dc 2024-10-01 05:36:40 +00:00
Documenter.jl 1f3b2a4d2e build based on 024429b 2024-09-30 15:25:16 +00:00
Documenter.jl f58acbcaab build based on 5835451 2024-09-27 11:32:35 +00:00
Documenter.jl b375668399 build based on e4eea0d 2024-09-26 09:16:35 +00:00
Documenter.jl 078c658310 build based on 08cfd87 2024-09-25 12:32:53 +00:00
Documenter.jl f4d810b431 build based on 42003ed 2024-09-24 08:11:06 +00:00
Documenter.jl af2b7c5a0d build based on b5efc3d 2024-09-23 14:37:12 +00:00
Documenter.jl 468c8dd0ca build based on c6c9aa9 2024-09-23 12:01:25 +00:00
Documenter.jl 038a80eea6 build based on 38cbd36 2024-09-23 11:58:33 +00:00
Documenter.jl cfa709cd76 build based on ea454e1 2024-09-23 05:44:55 +00:00
Documenter.jl a313337414 build based on 66e6d85 2024-09-19 15:48:09 +00:00
Documenter.jl b936e766a4 build based on 7b588a9 2024-09-19 10:21:45 +00:00
Documenter.jl cc164bc530 build based on d3ca2b4 2024-09-19 08:50:16 +00:00
Documenter.jl 7817ee9c51 build based on e146513 2024-09-16 20:06:22 +00:00
Documenter.jl 107886ceb5 build based on e775dcf 2024-09-16 20:00:00 +00:00
Documenter.jl 4960e99bea build based on 370be8a 2024-09-15 06:17:58 +00:00
Documenter.jl f936777d1e build based on b7db8f1 2024-09-14 18:31:42 +00:00
Documenter.jl 470effb661 build based on 662e07d 2024-09-12 16:06:37 +00:00
Documenter.jl b03843a902 build based on 0039ea8 2024-09-12 12:32:15 +00:00
Documenter.jl 21f1789b28 build based on 1d6a3b6 2024-09-12 09:27:51 +00:00
Documenter.jl cafb7d0b46 build based on 1e46702 2024-09-12 05:30:30 +00:00
Documenter.jl f23cd2ee39 build based on cd63aed 2024-09-11 08:58:17 +00:00
Documenter.jl 37e14fedd6 build based on c7cba5f 2024-09-09 15:08:53 +00:00
Documenter.jl b50b7e8e19 build based on 60a6d02 2024-09-02 11:57:10 +00:00
Documenter.jl fd35c3641c build based on 5bb44f3 2024-08-27 08:33:33 +00:00
Documenter.jl bba38eb351 build based on 5e44a19 2024-08-27 07:47:13 +00:00
Documenter.jl dad32dba25 build based on 567534f 2024-08-26 11:01:09 +00:00
Documenter.jl 4d93e76dbf build based on 4e6b769 2024-08-22 08:36:07 +00:00
Documenter.jl e8001495c2 build based on 4f0746e 2024-08-20 13:33:00 +00:00
Documenter.jl cd80d19161 build based on 250c61b 2024-08-20 12:05:57 +00:00
Documenter.jl b69d0e7340 build based on e6474b1 2024-08-19 14:07:02 +00:00
Documenter.jl 96c390a5bf build based on bf45227 2023-10-16 12:03:43 +00:00
Documenter.jl d51f515e99 build based on 785e785 2023-10-02 09:01:53 +00:00
Documenter.jl 5a2321bd19 build based on f820a72 2023-10-02 08:36:56 +00:00
Documenter.jl 576f3414b8 build based on 26afa1d 2023-09-29 08:09:15 +00:00
Documenter.jl 9c3ee53aaf build based on c3f6c5a 2023-09-22 15:35:39 +00:00
Documenter.jl d746051e7f build based on 50fb289 2023-09-20 07:14:21 +00:00
Documenter.jl 7e71122643 build based on 6cf3b87 2023-09-19 17:13:14 +00:00
Documenter.jl 28aca6a314 build based on 118f7f8 2023-09-19 16:34:14 +00:00
Documenter.jl 6e1d31d5b1 build based on 0b81f39 2023-09-18 15:44:19 +00:00
Documenter.jl e6b766b2df build based on 441a15f 2023-09-18 14:13:35 +00:00
Documenter.jl 1846400890 build based on 6ce67fd 2023-09-15 16:27:09 +00:00
Documenter.jl 546e65a4d5 build based on 87684b2 2023-09-15 13:42:37 +00:00
Documenter.jl 3871cef500 build based on 0e7cdd0 2023-09-08 16:25:04 +00:00
Documenter.jl 8049e7168a build based on 9a7ce52 2023-09-08 16:04:01 +00:00
Documenter.jl 05d25f5bff build based on a5f1ac6 2023-09-08 14:43:02 +00:00
Documenter.jl 508ca1e8f0 build based on fd3349e 2023-09-08 08:27:04 +00:00
Documenter.jl dd3d6ab76f build based on aa7b3c2 2023-09-07 10:58:15 +00:00
Documenter.jl face1ca615 build based on 665c853 2023-09-05 15:07:59 +00:00
Documenter.jl 355180f81b build based on abd74c8 2023-08-30 10:26:25 +00:00
Documenter.jl 5810ca1bc5 build based on cabefa5 2023-08-29 10:10:13 +00:00
Documenter.jl 7243b01821 build based on ed7bcf8 2023-08-29 09:24:14 +00:00
Documenter.jl 678644c8f7 build based on 98ee1a2 2023-08-25 20:50:18 +00:00
Documenter.jl fc774a323e build based on 4a6041a 2023-08-25 20:23:54 +00:00
Documenter.jl 04cdb8d8ac build based on a4f014c 2023-08-25 18:46:17 +00:00
Documenter.jl e600b8884b build based on 9f0ca20 2023-08-25 16:59:47 +00:00
Documenter.jl b3a49cdee5 build based on f7674fe 2023-08-25 16:05:51 +00:00
Documenter.jl 16d2e9eda2 build based on 2b8b471 2023-08-25 13:39:31 +00:00
Documenter.jl 306403eb3f build based on 44520fb 2023-08-25 13:30:51 +00:00
Documenter.jl 473acb182f build based on 1f375dd 2023-08-25 13:20:11 +00:00
Documenter.jl edccb6452f build based on b3f45fc 2023-08-24 14:59:14 +00:00
Documenter.jl 5d8121e88a build based on d8f8564 2023-08-23 07:04:20 +00:00
Documenter.jl 8ca3f4964d build based on 904d4ca 2023-08-22 10:48:43 +00:00
Documenter.jl a1d4d41254 build based on 5c03b6c 2023-08-21 14:09:34 +00:00
Documenter.jl afc5d2112a build based on b8728d6 2023-08-21 10:01:57 +00:00
Documenter.jl d9054bef63 build based on 5a7d33d 2023-08-18 14:42:17 +00:00
Documenter.jl 986f5d721e build based on 9372448 2023-08-18 08:10:28 +00:00
Documenter.jl c5fe119d23 build based on 6c681ef 2023-08-17 13:10:04 +00:00
Documenter.jl d6d7e8baa6 build based on fc54959 2023-08-17 12:55:29 +00:00
Documenter.jl 71ed2a606f build based on 4a2ca28 2023-08-17 11:55:25 +00:00
Documenter.jl bf66c6aa8a build based on 03a3d62 2023-08-16 09:04:56 +00:00
Documenter.jl a1942f1ac1 build based on 9991211 2023-08-15 12:51:40 +00:00
Documenter.jl de797c432a build based on d954714 2023-08-15 09:50:27 +00:00
Documenter.jl f325dd1252 build based on 9a3c8db 2023-08-15 09:46:51 +00:00
Documenter.jl 2d14fc943d build based on b82b2d4 2023-08-15 08:03:59 +00:00
Documenter.jl 28923f533f build based on e7417b1 2023-08-14 16:53:10 +00:00
Documenter.jl ee83a685f3 build based on 14b4706 2023-08-14 14:12:37 +00:00
Documenter.jl 0d9e975ab4 build based on d2bad0d 2023-08-14 13:38:09 +00:00
Documenter.jl 01956eb702 build based on ebdeef8 2023-08-14 11:09:21 +00:00
Documenter.jl fa482315fe build based on 5d0c156 2023-08-14 09:50:46 +00:00
Documenter.jl c264ad5ad4 build based on 7f0f40f 2023-08-11 13:46:07 +00:00
Documenter.jl c2696341cf build based on e6e68e8 2023-08-10 17:15:02 +00:00
Documenter.jl 537e941508 build based on 973c76f 2023-08-10 13:21:29 +00:00
Documenter.jl f610f8491b build based on 963cbd9 2023-08-10 12:30:23 +00:00
Documenter.jl f23da15359 build based on f3cb03b 2023-08-10 10:53:15 +00:00
Documenter.jl 2408efcf9f build based on 780c982 2023-08-10 09:50:33 +00:00
Documenter.jl 3f2f8e38ac build based on 2c76ded 2023-08-07 16:13:47 +00:00
Documenter.jl e1be41f09b build based on 65e88df 2023-07-31 13:16:55 +00:00
Documenter.jl bbcc6e2dd2 Initial empty commit for docs 2023-07-31 13:16:54 +00:00
122 changed files with 159836 additions and 187540 deletions
-64
View File
@@ -1,64 +0,0 @@
name: CI
on:
push:
branches:
- main
tags: ['*']
pull_request:
concurrency:
# Skip intermediate builds: always.
# Cancel intermediate builds: only if it is a pull request build.
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}
jobs:
test:
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
version:
- '1.9'
os:
- ubuntu-latest
arch:
- x64
steps:
- uses: actions/checkout@v3
- uses: julia-actions/setup-julia@v1
with:
version: ${{ matrix.version }}
arch: ${{ matrix.arch }}
- uses: julia-actions/cache@v1
- uses: julia-actions/julia-buildpkg@v1
- uses: julia-actions/julia-runtest@v1
docs:
name: Documentation
runs-on: ubuntu-latest
permissions:
contents: write
statuses: write
steps:
- uses: actions/checkout@v3
- uses: julia-actions/setup-julia@v1
with:
version: '1'
- name: Set up Python
uses: actions/setup-python@v4.7.0
with:
python-version: '3.9'
- name: Install nbconvert
run: |
python -m pip install jupyter nbconvert
- name: Configure doc environment
run: |
julia --project=docs/ -e '
using Pkg
Pkg.develop(PackageSpec(path=pwd()))
Pkg.instantiate()'
- uses: julia-actions/julia-buildpkg@v1
- uses: julia-actions/julia-docdeploy@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-8
View File
@@ -1,8 +0,0 @@
*.swp
Manifest.toml
.ipynb_checkpoints/
.vscode/
docs/src/notebooks/
docs/src/notebook-html/
*.code-workspace
*.DS_Store
-395
View File
@@ -1,395 +0,0 @@
Attribution 4.0 International
=======================================================================
Creative Commons Corporation ("Creative Commons") is not a law firm and
does not provide legal services or legal advice. Distribution of
Creative Commons public licenses does not create a lawyer-client or
other relationship. Creative Commons makes its licenses and related
information available on an "as-is" basis. Creative Commons gives no
warranties regarding its licenses, any material licensed under their
terms and conditions, or any related information. Creative Commons
disclaims all liability for damages resulting from their use to the
fullest extent possible.
Using Creative Commons Public Licenses
Creative Commons public licenses provide a standard set of terms and
conditions that creators and other rights holders may use to share
original works of authorship and other material subject to copyright
and certain other rights specified in the public license below. The
following considerations are for informational purposes only, are not
exhaustive, and do not form part of our licenses.
Considerations for licensors: Our public licenses are
intended for use by those authorized to give the public
permission to use material in ways otherwise restricted by
copyright and certain other rights. Our licenses are
irrevocable. Licensors should read and understand the terms
and conditions of the license they choose before applying it.
Licensors should also secure all rights necessary before
applying our licenses so that the public can reuse the
material as expected. Licensors should clearly mark any
material not subject to the license. This includes other CC-
licensed material, or material used under an exception or
limitation to copyright. More considerations for licensors:
wiki.creativecommons.org/Considerations_for_licensors
Considerations for the public: By using one of our public
licenses, a licensor grants the public permission to use the
licensed material under specified terms and conditions. If
the licensor's permission is not necessary for any reason--for
example, because of any applicable exception or limitation to
copyright--then that use is not regulated by the license. Our
licenses grant only permissions under copyright and certain
other rights that a licensor has authority to grant. Use of
the licensed material may still be restricted for other
reasons, including because others have copyright or other
rights in the material. A licensor may make special requests,
such as asking that all changes be marked or described.
Although not required by our licenses, you are encouraged to
respect those requests where reasonable. More considerations
for the public:
wiki.creativecommons.org/Considerations_for_licensees
=======================================================================
Creative Commons Attribution 4.0 International Public License
By exercising the Licensed Rights (defined below), You accept and agree
to be bound by the terms and conditions of this Creative Commons
Attribution 4.0 International Public License ("Public License"). To the
extent this Public License may be interpreted as a contract, You are
granted the Licensed Rights in consideration of Your acceptance of
these terms and conditions, and the Licensor grants You such rights in
consideration of benefits the Licensor receives from making the
Licensed Material available under these terms and conditions.
Section 1 -- Definitions.
a. Adapted Material means material subject to Copyright and Similar
Rights that is derived from or based upon the Licensed Material
and in which the Licensed Material is translated, altered,
arranged, transformed, or otherwise modified in a manner requiring
permission under the Copyright and Similar Rights held by the
Licensor. For purposes of this Public License, where the Licensed
Material is a musical work, performance, or sound recording,
Adapted Material is always produced where the Licensed Material is
synched in timed relation with a moving image.
b. Adapter's License means the license You apply to Your Copyright
and Similar Rights in Your contributions to Adapted Material in
accordance with the terms and conditions of this Public License.
c. Copyright and Similar Rights means copyright and/or similar rights
closely related to copyright including, without limitation,
performance, broadcast, sound recording, and Sui Generis Database
Rights, without regard to how the rights are labeled or
categorized. For purposes of this Public License, the rights
specified in Section 2(b)(1)-(2) are not Copyright and Similar
Rights.
d. Effective Technological Measures means those measures that, in the
absence of proper authority, may not be circumvented under laws
fulfilling obligations under Article 11 of the WIPO Copyright
Treaty adopted on December 20, 1996, and/or similar international
agreements.
e. Exceptions and Limitations means fair use, fair dealing, and/or
any other exception or limitation to Copyright and Similar Rights
that applies to Your use of the Licensed Material.
f. Licensed Material means the artistic or literary work, database,
or other material to which the Licensor applied this Public
License.
g. Licensed Rights means the rights granted to You subject to the
terms and conditions of this Public License, which are limited to
all Copyright and Similar Rights that apply to Your use of the
Licensed Material and that the Licensor has authority to license.
h. Licensor means the individual(s) or entity(ies) granting rights
under this Public License.
i. Share means to provide material to the public by any means or
process that requires permission under the Licensed Rights, such
as reproduction, public display, public performance, distribution,
dissemination, communication, or importation, and to make material
available to the public including in ways that members of the
public may access the material from a place and at a time
individually chosen by them.
j. Sui Generis Database Rights means rights other than copyright
resulting from Directive 96/9/EC of the European Parliament and of
the Council of 11 March 1996 on the legal protection of databases,
as amended and/or succeeded, as well as other essentially
equivalent rights anywhere in the world.
k. You means the individual or entity exercising the Licensed Rights
under this Public License. Your has a corresponding meaning.
Section 2 -- Scope.
a. License grant.
1. Subject to the terms and conditions of this Public License,
the Licensor hereby grants You a worldwide, royalty-free,
non-sublicensable, non-exclusive, irrevocable license to
exercise the Licensed Rights in the Licensed Material to:
a. reproduce and Share the Licensed Material, in whole or
in part; and
b. produce, reproduce, and Share Adapted Material.
2. Exceptions and Limitations. For the avoidance of doubt, where
Exceptions and Limitations apply to Your use, this Public
License does not apply, and You do not need to comply with
its terms and conditions.
3. Term. The term of this Public License is specified in Section
6(a).
4. Media and formats; technical modifications allowed. The
Licensor authorizes You to exercise the Licensed Rights in
all media and formats whether now known or hereafter created,
and to make technical modifications necessary to do so. The
Licensor waives and/or agrees not to assert any right or
authority to forbid You from making technical modifications
necessary to exercise the Licensed Rights, including
technical modifications necessary to circumvent Effective
Technological Measures. For purposes of this Public License,
simply making modifications authorized by this Section 2(a)
(4) never produces Adapted Material.
5. Downstream recipients.
a. Offer from the Licensor -- Licensed Material. Every
recipient of the Licensed Material automatically
receives an offer from the Licensor to exercise the
Licensed Rights under the terms and conditions of this
Public License.
b. No downstream restrictions. You may not offer or impose
any additional or different terms or conditions on, or
apply any Effective Technological Measures to, the
Licensed Material if doing so restricts exercise of the
Licensed Rights by any recipient of the Licensed
Material.
6. No endorsement. Nothing in this Public License constitutes or
may be construed as permission to assert or imply that You
are, or that Your use of the Licensed Material is, connected
with, or sponsored, endorsed, or granted official status by,
the Licensor or others designated to receive attribution as
provided in Section 3(a)(1)(A)(i).
b. Other rights.
1. Moral rights, such as the right of integrity, are not
licensed under this Public License, nor are publicity,
privacy, and/or other similar personality rights; however, to
the extent possible, the Licensor waives and/or agrees not to
assert any such rights held by the Licensor to the limited
extent necessary to allow You to exercise the Licensed
Rights, but not otherwise.
2. Patent and trademark rights are not licensed under this
Public License.
3. To the extent possible, the Licensor waives any right to
collect royalties from You for the exercise of the Licensed
Rights, whether directly or through a collecting society
under any voluntary or waivable statutory or compulsory
licensing scheme. In all other cases the Licensor expressly
reserves any right to collect such royalties.
Section 3 -- License Conditions.
Your exercise of the Licensed Rights is expressly made subject to the
following conditions.
a. Attribution.
1. If You Share the Licensed Material (including in modified
form), You must:
a. retain the following if it is supplied by the Licensor
with the Licensed Material:
i. identification of the creator(s) of the Licensed
Material and any others designated to receive
attribution, in any reasonable manner requested by
the Licensor (including by pseudonym if
designated);
ii. a copyright notice;
iii. a notice that refers to this Public License;
iv. a notice that refers to the disclaimer of
warranties;
v. a URI or hyperlink to the Licensed Material to the
extent reasonably practicable;
b. indicate if You modified the Licensed Material and
retain an indication of any previous modifications; and
c. indicate the Licensed Material is licensed under this
Public License, and include the text of, or the URI or
hyperlink to, this Public License.
2. You may satisfy the conditions in Section 3(a)(1) in any
reasonable manner based on the medium, means, and context in
which You Share the Licensed Material. For example, it may be
reasonable to satisfy the conditions by providing a URI or
hyperlink to a resource that includes the required
information.
3. If requested by the Licensor, You must remove any of the
information required by Section 3(a)(1)(A) to the extent
reasonably practicable.
4. If You Share Adapted Material You produce, the Adapter's
License You apply must not prevent recipients of the Adapted
Material from complying with this Public License.
Section 4 -- Sui Generis Database Rights.
Where the Licensed Rights include Sui Generis Database Rights that
apply to Your use of the Licensed Material:
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
to extract, reuse, reproduce, and Share all or a substantial
portion of the contents of the database;
b. if You include all or a substantial portion of the database
contents in a database in which You have Sui Generis Database
Rights, then the database in which You have Sui Generis Database
Rights (but not its individual contents) is Adapted Material; and
c. You must comply with the conditions in Section 3(a) if You Share
all or a substantial portion of the contents of the database.
For the avoidance of doubt, this Section 4 supplements and does not
replace Your obligations under this Public License where the Licensed
Rights include other Copyright and Similar Rights.
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
c. The disclaimer of warranties and limitation of liability provided
above shall be interpreted in a manner that, to the extent
possible, most closely approximates an absolute disclaimer and
waiver of all liability.
Section 6 -- Term and Termination.
a. This Public License applies for the term of the Copyright and
Similar Rights licensed here. However, if You fail to comply with
this Public License, then Your rights under this Public License
terminate automatically.
b. Where Your right to use the Licensed Material has terminated under
Section 6(a), it reinstates:
1. automatically as of the date the violation is cured, provided
it is cured within 30 days of Your discovery of the
violation; or
2. upon express reinstatement by the Licensor.
For the avoidance of doubt, this Section 6(b) does not affect any
right the Licensor may have to seek remedies for Your violations
of this Public License.
c. For the avoidance of doubt, the Licensor may also offer the
Licensed Material under separate terms or conditions or stop
distributing the Licensed Material at any time; however, doing so
will not terminate this Public License.
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
License.
Section 7 -- Other Terms and Conditions.
a. The Licensor shall not be bound by any additional or different
terms or conditions communicated by You unless expressly agreed.
b. Any arrangements, understandings, or agreements regarding the
Licensed Material not stated herein are separate from and
independent of the terms and conditions of this Public License.
Section 8 -- Interpretation.
a. For the avoidance of doubt, this Public License does not, and
shall not be interpreted to, reduce, limit, restrict, or impose
conditions on any use of the Licensed Material that could lawfully
be made without permission under this Public License.
b. To the extent possible, if any provision of this Public License is
deemed unenforceable, it shall be automatically reformed to the
minimum extent necessary to make it enforceable. If the provision
cannot be reformed, it shall be severed from this Public License
without affecting the enforceability of the remaining terms and
conditions.
c. No term or condition of this Public License will be waived and no
failure to comply consented to unless expressly agreed to by the
Licensor.
d. Nothing in this Public License constitutes or may be interpreted
as a limitation upon, or waiver of, any privileges and immunities
that apply to the Licensor or You, including from the legal
processes of any jurisdiction or authority.
=======================================================================
Creative Commons is not a party to its public
licenses. Notwithstanding, Creative Commons may elect to apply one of
its public licenses to material it publishes and in those instances
will be considered the “Licensor.” The text of the Creative Commons
public licenses is dedicated to the public domain under the CC0 Public
Domain Dedication. Except for the limited purpose of indicating that
material is shared under a Creative Commons public license or as
otherwise permitted by the Creative Commons policies published at
creativecommons.org/policies, Creative Commons does not authorize the
use of the trademark "Creative Commons" or any other trademark or logo
of Creative Commons without its prior written consent including,
without limitation, in connection with any unauthorized modifications
to any of its public licenses or any other arrangements,
understandings, or agreements concerning use of licensed material. For
the avoidance of doubt, this paragraph does not form part of the
public licenses.
Creative Commons may be contacted at creativecommons.org.
-8
View File
@@ -1,8 +0,0 @@
name = "XM_40017"
uuid = "97f213cd-d64a-481d-bc9d-afa871b8c535"
authors = ["Francesc Verdugo <f.verdugo.rojano@vu.nl>"]
version = "0.1.0"
[deps]
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
Glob = "c27321d9-0574-5035-807b-f59d2c89b15c"
-6
View File
@@ -1,6 +0,0 @@
# XM_40017
Jupyter notebook scripts for the course Programming Large-Scale Parallel Systems (XM_40017) at Vrije Universiteit Amsterdam.
- [**Go to webpage**](https://fverdugo.github.io/XM_40017/dev)
NB: The `notebooks` folder contains material under construction. The material that is ready for study is the one accessible from the website. The material will be added incrementally to the website as the course advances.
+1
View File
@@ -0,0 +1 @@
{"documenter":{"julia_version":"1.11.7","generation_timestamp":"2025-09-24T05:37:55","documenter_version":"1.14.1"}}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 96 KiB

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+84
View File
@@ -0,0 +1,84 @@
// Small function to quickly swap out themes. Gets put into the <head> tag..
function set_theme_from_local_storage() {
// Initialize the theme to null, which means default
var theme = null;
// If the browser supports the localstorage and is not disabled then try to get the
// documenter theme
if (window.localStorage != null) {
// Get the user-picked theme from localStorage. May be `null`, which means the default
// theme.
theme = window.localStorage.getItem("documenter-theme");
}
// Check if the users preference is for dark color scheme
var darkPreference =
window.matchMedia("(prefers-color-scheme: dark)").matches === true;
// Initialize a few variables for the loop:
//
// - active: will contain the index of the theme that should be active. Note that there
// is no guarantee that localStorage contains sane values. If `active` stays `null`
// we either could not find the theme or it is the default (primary) theme anyway.
// Either way, we then need to stick to the primary theme.
//
// - disabled: style sheets that should be disabled (i.e. all the theme style sheets
// that are not the currently active theme)
var active = null;
var disabled = [];
var primaryLightTheme = null;
var primaryDarkTheme = null;
for (var i = 0; i < document.styleSheets.length; i++) {
var ss = document.styleSheets[i];
// The <link> tag of each style sheet is expected to have a data-theme-name attribute
// which must contain the name of the theme. The names in localStorage much match this.
var themename = ss.ownerNode.getAttribute("data-theme-name");
// attribute not set => non-theme stylesheet => ignore
if (themename === null) continue;
// To distinguish the default (primary) theme, it needs to have the data-theme-primary
// attribute set.
if (ss.ownerNode.getAttribute("data-theme-primary") !== null) {
primaryLightTheme = themename;
}
// Check if the theme is primary dark theme so that we could store its name in darkTheme
if (ss.ownerNode.getAttribute("data-theme-primary-dark") !== null) {
primaryDarkTheme = themename;
}
// If we find a matching theme (and it's not the default), we'll set active to non-null
if (themename === theme) active = i;
// Store the style sheets of inactive themes so that we could disable them
if (themename !== theme) disabled.push(ss);
}
var activeTheme = null;
if (active !== null) {
// If we did find an active theme, we'll (1) add the theme--$(theme) class to <html>
document.getElementsByTagName("html")[0].className = "theme--" + theme;
activeTheme = theme;
} else {
// If we did _not_ find an active theme, then we need to fall back to the primary theme
// which can either be dark or light, depending on the user's OS preference.
var activeTheme = darkPreference ? primaryDarkTheme : primaryLightTheme;
// In case it somehow happens that the relevant primary theme was not found in the
// preceding loop, we abort without doing anything.
if (activeTheme === null) {
console.error("Unable to determine primary theme.");
return;
}
// When switching to the primary light theme, then we must not have a class name
// for the <html> tag. That's only for non-primary or the primary dark theme.
if (darkPreference) {
document.getElementsByTagName("html")[0].className =
"theme--" + activeTheme;
} else {
document.getElementsByTagName("html")[0].className = "";
}
}
for (var i = 0; i < document.styleSheets.length; i++) {
var ss = document.styleSheets[i];
// The <link> tag of each style sheet is expected to have a data-theme-name attribute
// which must contain the name of the theme. The names in localStorage much match this.
var themename = ss.ownerNode.getAttribute("data-theme-name");
// attribute not set => non-theme stylesheet => ignore
if (themename === null) continue;
// we'll disable all the stylesheets, except for the active one
ss.disabled = !(themename == activeTheme);
}
}
set_theme_from_local_storage();
+68
View File
@@ -0,0 +1,68 @@
function maybeAddWarning() {
// DOCUMENTER_NEWEST is defined in versions.js, DOCUMENTER_CURRENT_VERSION and DOCUMENTER_STABLE
// in siteinfo.js. DOCUMENTER_IS_DEV_VERSION is optional and defined in siteinfo.js.
// If the required variables are undefined something went horribly wrong, so we abort.
if (
window.DOCUMENTER_NEWEST === undefined ||
window.DOCUMENTER_CURRENT_VERSION === undefined ||
window.DOCUMENTER_STABLE === undefined
) {
return;
}
// Current version is not a version number, so we can't tell if it's the newest version. Abort.
if (!/v(\d+\.)*\d+/.test(window.DOCUMENTER_CURRENT_VERSION)) {
return;
}
// Current version is newest version, so no need to add a warning.
if (window.DOCUMENTER_NEWEST === window.DOCUMENTER_CURRENT_VERSION) {
return;
}
// Add a noindex meta tag (unless one exists) so that search engines don't index this version of the docs.
if (document.body.querySelector('meta[name="robots"]') === null) {
const meta = document.createElement("meta");
meta.name = "robots";
meta.content = "noindex";
document.getElementsByTagName("head")[0].appendChild(meta);
}
const div = document.createElement("div");
// Base class is added by default
div.classList.add("warning-overlay-base");
const closer = document.createElement("button");
closer.classList.add("outdated-warning-closer", "delete");
closer.addEventListener("click", function () {
document.body.removeChild(div);
});
const href = window.documenterBaseURL + "/../" + window.DOCUMENTER_STABLE;
// Determine if this is a development version or an older release
let warningMessage = "";
if (window.DOCUMENTER_IS_DEV_VERSION === true) {
div.classList.add("dev-warning-overlay");
warningMessage =
"This documentation is for the <strong>development version</strong> and may contain unstable or unreleased features.<br>";
} else {
div.classList.add("outdated-warning-overlay");
warningMessage =
"This documentation is for an <strong>older version</strong> that may be missing recent changes.<br>";
}
warningMessage +=
'<a href="' +
href +
'">Click here to go to the documentation for the latest stable release.</a>';
div.innerHTML = warningMessage;
div.appendChild(closer);
document.body.appendChild(div);
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", maybeAddWarning);
} else {
maybeAddWarning();
}
File diff suppressed because one or more lines are too long
+5
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
BIN
View File
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2
View File
@@ -0,0 +1,2 @@
var DOCUMENTER_CURRENT_VERSION = "dev";
var DOCUMENTER_IS_DEV_VERSION = true;
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-8
View File
@@ -1,8 +0,0 @@
build/
site/
src/notebook-output/
src/notebooks/
Manifest.toml
src/*.ipynb
src/*/index.html
src/*.md
-4
View File
@@ -1,4 +0,0 @@
[deps]
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
Glob = "c27321d9-0574-5035-807b-f59d2c89b15c"
XM_40017 = "97f213cd-d64a-481d-bc9d-afa871b8c535"
-139
View File
@@ -1,139 +0,0 @@
using XM_40017
using Documenter
using Glob
const md_nb_template = """
```@meta
EditURL = "https://github.com/fverdugo/XM_40017/blob/main/notebooks/SCRIPT_NAME.ipynb"
```
```@raw html
<div class="admonition is-success">
<header class="admonition-header">Tip</header>
<div class="admonition-body">
<ul>
<li>
Download this notebook and run it locally on your machine [highly recommended]. Click <a href="https://www.francescverdugo.com/XM_40017/dev/SCRIPT_NAME.ipynb" download>here</a>.
</li>
</ul>
</div>
</div>
```
```@raw html
<iframe id="notebook" src="../SCRIPT_NAME_src/" style="width:100%"></iframe>
<script>
document.addEventListener('DOMContentLoaded', function(){
var myIframe = document.getElementById("notebook");
iFrameResize({log:true}, myIframe);
});
</script>
```
"""
function convert_embedded_img_to_base64(notebook_path)
doc = open(io->read(io, String), notebook_path)
# Regex matching: extract filename and base64 code
regex = r"attachments\\\":\s*\{\s*\\\"(?<filename>.*).png\\\":\s*\{\s*\\\"image/png\\\":\s*\\\"(?<base64code>.*)\\\""
res = eachmatch(regex, doc)
matches = collect(res)
# Replace img src with base64 code
for m in matches
filename = m[:filename]
base64 = m[:base64code]
doc = replace(doc, "attachment:$filename.png" => "data:image/png;base64,$base64")
end
filename = splitpath(notebook_path)[end]
open("docs/src/$filename","w") do f
write(f, doc)
end
end
# Write markdown file that includes notebook html
function create_md_nb_file( filename )
global md_nb_template;
content = replace(md_nb_template, "SCRIPT_NAME" => filename)
md_path = joinpath(@__DIR__, "src", filename * ".md" )
open(md_path, "w") do md_file
write(md_file, content)
end
return md_path
end
# Convert to html using nbconvert
function convert_notebook_to_html(notebook_path; output_name,output_dir, theme = "light")
command_jup = "jupyter"
command_nbc = "nbconvert"
output_format = "--to=html"
theme = "--theme=$theme"
output = "--output=$output_name"
output_dir = "--output-dir=$output_dir"
infile = notebook_path
run(`$command_jup $command_nbc $output_format $output $output_dir $theme $infile`)
end
# Modify html contents
function modify_notebook_html( html_filepath )
content = open( html_filepath, "r" ) do html_file
read( html_file, String )
end
# Resize iframes using IframeResizer
content = replace(content,
r"(<script\b[^>]*>[\s\S]*?<\/script>\K)" =>
s"\1\n\t<script src='../assets/iframeResizer.contentWindow.min.js'></script>\n";
count = 1
)
open( html_filepath, "w" ) do html_file
write( html_file, content )
end
return nothing
end
# Loop over notebooks and generate html and markdown
repo_root = joinpath(@__DIR__,"..") |> normpath
notebook_files = glob("*.ipynb", joinpath(repo_root,"notebooks/"))
for filepath in notebook_files
#continue
convert_embedded_img_to_base64(filepath)
filename_with_ext = splitpath(filepath)[end]
filename = splitext(filename_with_ext)[1]
pth = mkpath(joinpath(repo_root,"docs","src",filename*"_src"))
create_md_nb_file(filename)
convert_notebook_to_html("docs/src/$filename_with_ext", output_dir=pth, output_name = "index")
modify_notebook_html("docs/src/$(filename)_src/index.html")
end
makedocs(;
modules=[XM_40017],
authors="Francesc Verdugo <f.verdugo.rojano@vu.nl>",
repo="https://github.com/fverdugo/XM_40017/blob/{commit}{path}#{line}",
sitename="XM_40017",
format=Documenter.HTML(;
assets = ["assets/favicon.ico", "assets/iframeResizer.min.js", "assets/custom.css"],
prettyurls=get(ENV, "CI", "false") == "true",
canonical="https://fverdugo.github.io/XM_40017",
edit_link="main",),
pages=["Home" => "index.md","Getting started"=>"getting_started_with_julia.md",
"Notebooks"=>[
"Julia Basics" => "julia_basics.md",
"Asynchronous programming in Julia" => "julia_async.md",
"Distributed computing in Julia" => "julia_distributed.md",
#"Distributed computing with MPI" => "mpi_tutorial.md",
"Matrix-matrix multiplication"=>"matrix_matrix.md",
"MPI (point-to-point)" => "julia_mpi.md",
"MPI (collectives)" => "mpi_collectives.md",
"Jacobi method" => "jacobi_method.md",
"All pairs of shortest paths" => "asp.md",
"Gaussian elimination" => "LEQ.md",
"Traveling salesperson problem" => "tsp.md",
#"Partial differential equations" => "pdes.md",
],
"Solutions" => "solutions_for_all_notebooks.md",
],
)
deploydocs(;
repo="github.com/fverdugo/XM_40017",
devbranch="main",
)
-435
View File
@@ -1,435 +0,0 @@
# Getting started
## Introduction
The programming of this course will be done using the [Julia programming language](https://julialang.org). Thus, we start by explaining how to get up and running with Julia. After studying this page, you will be able to:
- Use the Julia REPL,
- Run serial and parallel code,
- Install and manage Julia packages.
## Why Julia?
Courses related with high-performance computing (HPC) often use languages such as C, C++, or Fortran. We use Julia instead to make the course accessible to a wider set of students, including the ones that have no experience with
C/C++ or Fortran, but are willing to learn parallel programming. Julia is a relatively new programming language specifically designed for scientific computing. It combines a high-level syntax close to interpreted languages like Python with the performance of compiled languages like C, C++, or Fortran. Thus, Julia will allow us to write efficient parallel algorithms with a syntax that is convenient in a teaching setting. In addition, Julia provides easy access to different programming models to write distributed algorithms, which will be useful to learn and experiment with them.
!!! tip
You can run the code [in this link](https://github.com/JuliaAcademy/JuliaTutorials/blob/724e15a350d150a9773afe51a3830709dbed422f/introductory-tutorials/intro-to-julia/09.%20Julia%20is%20fast.ipynb) to learn how Julia compares to other languages (C and Python) in terms of performance.
## Installing Julia
This is a tutorial-like page. Follow these steps before you continue reading the document.
- Download and install Julia from [julialang.org](https://julialang.org);
- Follow the specific instructions for your operating system: [Windows](https://julialang.org/downloads/platform/#windows), [MacOS](https://julialang.org/downloads/platform/#macos), or [Linux](https://julialang.org/downloads/platform/#linux_and_freebsd)
- Download and install [VSCode and its Julia extension](https://www.julia-vscode.org/docs/dev/gettingstarted/);
## The Julia REPL
### Starting Julia
There are several ways of opening Julia depending on your operating system and your IDE, but it is usually as simple as launching the Julia app. With VSCode, open a folder (File > Open Folder). Then, press `Ctrl`+`Shift`+`P` to open the command bar, and execute `Julia: Start REPL`. If this does not work, make sure you have the Julia extension for VSCode installed. Independently of the method you use, opening Julia results in a window with some text ending with:
```
julia>
```
You have just opened the Julia *read-evaluate-print loop*, or simply the Julia *REPL*. Congrats! You will spend most of time using the REPL, when working in Julia. The REPL is a console waiting for user input. Just as in other consoles, the string of text right before the input area (`julia>` in the case) is called the *command prompt* or simply the *prompt*.
### Basic usage
The usage of the REPL is as follows:
- You write some input
- press enter
- you get the output
For instance, try this
```julia
julia> 1 + 1
```
A "Hello world" example looks like this in Julia
```julia
julia> println("Hello, world!")
```
Try to run it in the REPL.
### Help mode
Curious about what the function `println` does? Enter into *help* mode to look into the documentation. This is done by typing a question mark (`?`) into the input field:
```julia
julia> ?
```
After typing `?`, the command prompt changes to `help?>`. It means we are in help mode. Now, we can type a function name to see its documentation.
```julia
help?> println
```
### Package and shell modes
The REPL comes with two more modes, namely *package* and *shell* modes. To enter package mode type
```julia
julia> ]
```
Package mode is used to install and manage packages. We are going to discuss the package mode in greater detail later. To return back to normal mode press the backspace key several times.
To enter shell mode type semicolon (`;`)
```julia
julia> ;
```
The prompt should have changed to `shell>` indicating that we are in shell mode. Now you can type commands that you would normally do on your system command line. For instance,
```julia
shell> ls
```
will display the contents of the current folder in Mac or Linux. Using shell mode in Windows is not straightforward, and thus not recommended for beginners.
## Running Julia code
### Running more complex code
Real-world Julia programs are not typed in the REPL in practice. They are written in one or more files and *included* in the REPL. To try this, create a new file called `hello.jl`, write the code of the "Hello world" example above, and save it. If you are using VSCode, you can create the file using File > New File > Julia File. Once the file is saved with the name `hello.jl`, execute it as follows
```julia
julia> include("hello.jl")
```
!!! warning
Make sure that the file `"hello.jl"` is located in the current working directory of your Julia session. You can query the current directory with function `pwd()`. You can change to another directory with function `cd()` if needed. Also, make sure that the file extension is `.jl`.
The recommended way of running Julia code is using the REPL as we did. But it is also possible to run code directly from the system command line. To this end, open a terminal and call Julia followed by the path to the file containing the code you want to execute.
```
$ julia hello.jl
```
The previous line assumes that you have Julia properly installed in the system and that it's usable from the terminal. In UNIX systems (Linux and Mac), the Julia binary needs to be in one of the directories listed in the `PATH` environment variable. To check that Julia is properly installed, you can use
```
$ julia --version
```
If this runs without error and you see a version number, you are good to go!
You can also run julia code from the terminal using the `-e` flag:
```
$ julia -e 'println("Hello, world!")'
```
!!! note
In this tutorial, when a code snipped starts with `$`, it should be run in the terminal. Otherwise, the code is to be run in the Julia REPL.
!!! tip
Avoid calling Julia code from the terminal, use the Julia REPL instead!
Each time you call Julia from the terminal, you start a fresh Julia session and Julia will need to compile your code from scratch.
This can be time consuming for large projects.
In contrast, if you execute code in the REPL, Julia will compile code incrementally, which is much faster.
Running code in a cluster (like in DAS-5 for the Julia assignment) is among the few situations you need to run Julia code
from the terminal. Visit this link ([Julia workflow tips](https://docs.julialang.org/en/v1/manual/workflow-tips/))
from the official Julia documentation for further information about how to develop Julia code effectivelly.
### Running parallel code
Since we are in a parallel computing course, let's run a parallel "Hello world" example in Julia. Open a Julia REPL and write
```julia
julia> using Distributed
julia> @everywhere println("Hello, world! I am proc $(myid()) from $(nprocs())")
```
Here, we are using the `Distributed` package, which is part of the Julia standard library that provides distributed memory parallel support. The code prints the process id and the number of processes in the current Julia session.
You will probably only see output from 1 process. We need to add more processes to run the example in parallel. This is done with the `addprocs` function.
```julia
julia> addprocs(3)
```
We have added 3 new processes. Plus the old one, we have 4 processes. Run the code again.
```julia
julia> @everywhere println("Hello, world! I am proc $(myid()) from $(nprocs())")
```
Now, you should see output from 4 processes.
It is possible to specify the number of processes when starting Julia from the terminal with the `-p` argument (useful, e.g., when running in a cluster). If you launch Julia from the terminal as
```
$ julia -p 3
```
and then run
```julia
julia> @everywhere println("Hello, world! I am proc $(myid()) from $(nprocs())")
```
You should get output from 4 processes as before.
### Installing packages
One of the most useful features of Julia is its package manager. It allows one to install Julia packages in a straightforward and platform independent way. To illustrate this, let us consider the following parallel "Hello world" example. This example uses the Message Passing Interface (MPI). We will learn more about MPI later in the course.
Copy the following block of code into a new file named `"hello_mpi.jl"`
```julia
# file hello_mpi.jl
using MPI
MPI.Init()
comm = MPI.COMM_WORLD
rank = MPI.Comm_rank(comm)
nranks = MPI.Comm_size(comm)
println("Hello world, I am rank $rank of $nranks")
```
As you can see from this example, one can access MPI from Julia in a clean way, without type annotations and other complexities of C/C++ code.
Now, run the file from the REPL
```julia
julia> include("hello_mpi.jl")
```
It probably didn't work, right? Read the error message and note that the MPI package needs to be installed to run this code.
To install a package, we need to enter *package* mode. Remember that we entered into help mode by typing `?`. Package mode is activated by typing `]` :
```julia
julia> ]
```
At this point, the prompt should have changed to `(@v1.11) pkg>` indicating that we are in package mode. The text between the parentheses indicates which is the active *project*, i.e., where packages are going to be installed. In this case, we are working with the global project associated with our Julia installation (which is Julia 1.11 in this example, but it can be another version in your case).
To install the MPI package, type
```julia
(@v1.11) pkg> add MPI
```
Congrats, you have installed MPI!
!!! note
Many Julia package names end with `.jl`. This is just a way of signaling that a package is written in Julia. When using such packages, the `.jl` needs to be omitted. In this case, we have installed the `MPI.jl` package even though we have only typed `MPI` in the REPL.
!!! note
The package you have installed is the Julia interface to MPI, called `MPI.jl`. Note that it is not an MPI library by itself. It is just a thin wrapper between MPI and Julia. To use this interface, you need an actual MPI library installed in your system such as OpenMPI or MPICH. Julia downloads and installs an MPI library for you, but it is also possible to use an MPI library already available in your system. This is useful, e.g., when running on HPC clusters. See the [documentation](https://juliaparallel.org/MPI.jl/stable/configuration/) of `MPI.jl` for further details.
To check that the package was installed properly, exit package mode by pressing the backspace key several times, and run it again
```julia
julia> include("hello_mpi.jl")
```
Now, it should work, but you probably get output from a single MPI rank only.
### Running MPI code
To run MPI applications in parallel, you need a launcher like `mpiexec`. MPI codes written in Julia are not an exception to this rule. From the system terminal, you can run
```
$ mpiexec -np 4 julia hello_mpi.jl
```
But it will probably not work since the version of `mpiexec` needs to match with the MPI version we are using from Julia. Don't worry if you could not make it work! A more elegant way to run MPI code is from the Julia REPL directly, by using these commands:
```julia
julia> using MPI
julia> run(`$(mpiexec()) -np 4 julia hello_mpi.jl`);
```
Now, you should see output from 4 ranks.
## Package manager
### Installing packages locally
We have installed the `MPI` package globally and it will be available in all Julia sessions. However, in some situations, we want to work with different versions of the same package or to install packages in an isolated way to avoid potential conflicts with other packages. This can be done by using local projects.
A project is simply a folder in your file system. To use a particular folder as your project, you need to *activate* it. This is done by entering package mode and using the `activate` command followed by the path to the folder you want to activate.
```julia
(@v1.11) pkg> activate .
```
The previous command will activate the current working directory. Note that the dot `.` is indeed the path to the current folder.
The prompt has changed to `(lessons) pkg>` indicating that we are in the project within the `lessons` folder. The particular folder name can be different in your case.
!!! tip
You can activate a project directly when opening Julia from the terminal using the `--project` flag. The command `$ julia --project=.` will open Julia and activate a project in the current directory. You can also achieve the same effect by setting the environment variable `JULIA_PROJECT` with the path of the folder you want to activate.
!!! note
The active project folder and the current working directory are two independent concepts! For instance, `(@v1.11) pkg> activate folderB` and then `julia> cd("folderA")`, will activate the project in `folderB` and change the current working directory to `folderA`.
At this point all package-related operations will be local to the new project. For instance, install the `DataFrames` package.
```julia
(lessons) pkg> add DataFrames
```
Use the package to check that it is installed
```julia
julia> using DataFrames
julia> DataFrame(a=[1,2],b=[3,4])
```
Now, we can return to the global project to check that `DataFrames` has not been installed there. To return to the global environment, use `activate` without a folder name.
```julia
(lessons) pkg> activate
```
The prompt is again `(@v1.11) pkg>`
Now, try to use `DataFrames`.
```julia
julia> using DataFrames
julia> DataFrame(a=[1,2],b=[3,4])
```
You should get an error or a warning unless you already had `DataFrames` installed globally.
### Project and Manifest files
The information about a project is stored in two files `Project.toml` and `Manifest.toml`.
- `Project.toml` contains the packages explicitly installed (the direct dependencies)
- `Manifest.toml` contains direct and indirect dependencies along with the concrete version of each package.
In other words, `Project.toml` contains the packages relevant for the user, whereas `Manifest.toml` is the detailed snapshot of all dependencies. The `Manifest.toml` can be used to reproduce the same environment in another machine.
You can see the path to the current `Project.toml` file by using the `status` operator (or `st` in its short form) while in package mode
```julia
(@v1.11) pkg> status
```
The information about the `Manifest.toml` can be inspected by passing the `-m` flag.
```julia
(@v1.11) pkg> status -m
```
### Installing packages from a project file
Project files can be used to install lists of packages defined by others. E.g., to install all the dependencies of a Julia application.
Assume that a colleague has sent to you a `Project.toml` file with this content:
```
[deps]
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195"
```
Copy the contents of previous code block into a file called `Project.toml` and place it in an empty folder named `newproject`. It is important that the file is named `Project.toml`. You can create a new folder from the REPL with
```julia
julia> mkdir("newproject")
```
To install all the packages registered in this file you need to activate the folder containing your `Project.toml` file
```julia
(@v1.11) pkg> activate newproject
```
and then *instantiating* it
```julia
(newproject) pkg> instantiate
```
The instantiate command will download and install all listed packages and their dependencies in just one click.
### Getting help in package mode
You can get help about a particular package operator by writing `help` in front of it
```julia
(@v1.11) pkg> help activate
```
You can get an overview of all package commands by typing `help` alone
```julia
(@v1.11) pkg> help
```
### Package operations in Julia code
In some situations it is required to use package commands in Julia code, e.g., to automatize installation and deployment of Julia applications. This can be done using the `Pkg` package. For instance
```julia
julia> using Pkg
julia> Pkg.status()
```
is equivalent to calling `status` in package mode.
```julia
(@v1.11) pkg> status
```
### Creating you own package
In many situations, it is useful to create your own package, for instance, when working with a large code base, when you want to reduce compilation latency using [`Revise.jl`](https://github.com/timholy/Revise.jl),
or if you want to eventually [register your package](https://github.com/JuliaRegistries/Registrator.jl) and share it with others.
The simplest way of generating a package (called `MyPackage`) is as follows. Open Julia, go to package mode, and type
```julia
(@v1.11) pkg> generate MyPackage
```
This will crate a minimal package consisting of a new folder `MyPackage` with two files:
* `MyPackage/Project.toml`: Project file defining the direct dependencies of your package.
* `MyPackage/src/MyPackage.jl`: Main source file of your package. You can split your code in several files if needed, and include them in the package main file using function `include`.
!!! tip
This approach only generates a very minimal package. To create a more sophisticated package skeleton (including unit testing, code coverage, readme file, licence, etc.) use
[`PkgTemplates.jl`](https://github.com/JuliaCI/PkgTemplates.jl) or [`BestieTemplate.jl`](https://github.com/JuliaBesties/BestieTemplate.jl). The later one is developed in Amsterdam at the
[Netherlands eScience Center](https://www.esciencecenter.nl/).
You can add dependencies to the package by activating the `MyPackage` folder in package mode and adding new dependencies as always:
```julia
(@v1.11) pkg> activate MyPackage
(MyPackage) pkg> add MPI
```
This will add MPI to your package dependencies.
### Using your own package
To use your package you first need to add it to a package environment of your choice. This is done by changing to package mode and typing `develop ` followed by the path to the folder containing the package. For instance:
```julia
(@v1.11) pkg> develop MyPackage
```
!!! note
You do not need to "develop" your package if you activated the package folder `MyPackage`.
Now, we can go back to standard Julia mode and use it as any other package:
```julia
using MyPackage
MyPackage.greet()
```
Here, we just called the example function defined in `MyPackage/src/MyPackage.jl`.
## Conclusion
We have learned the basics of how to work with Julia, including how to run serial and parallel code, and how to manage, create, and use Julia packages.
This knowledge will allow you to follow the course effectively!
If you want to further dig into the topics we have covered here, you can take a look at the following links:
- [Julia Manual](https://docs.julialang.org/en/v1/manual/getting-started/)
- [Package manager](https://pkgdocs.julialang.org/v1/getting-started/)
-57
View File
@@ -1,57 +0,0 @@
```@meta
CurrentModule = XM_40017
```
# Programming Large-Scale Parallel Systems (XM_40017)
Welcome to the interactive lecture notes of the [Programming Large-Scale Parallel Systems course](https://studiegids.vu.nl/EN/courses/2023-2024/XM_40017#/) at [VU Amsterdam](https://vu.nl)!
## What
This page contains part of the course material of the Programming Large-Scale Parallel Systems course at VU Amsterdam.
We provide several lecture notes in jupyter notebook format, which will help you to learn how to design, analyze, and program parallel algorithms on multi-node computing systems.
Further information about the course is found in the study guide
([click here](https://studiegids.vu.nl/en/vakken/2025-2026/XM_40017#/)) and our Canvas page (for registered students).
!!! note
Material will be added incrementally to the website as the course advances.
!!! warning
This page will eventually contain only a part of the course material. The rest will be available on Canvas. In particular, **the material in this public webpage does not fully cover all topics in the final exam**.
## How to use this page
You have two main ways of studying the notebooks:
- Download the notebooks and run them locally on your computer (recommended). At each notebook page you will find a green box with links to download the notebook.
- You also have the static version of the notebooks displayed in this webpage for quick reference.
## How to run the notebooks locally
To run a notebook locally follow these steps:
- Install Julia (if not done already). More information in [Getting started](@ref).
- Download the notebook.
- Launch Julia. More information in [Getting started](@ref).
- Execute these commands in the Julia command line:
```
julia> using Pkg
julia> Pkg.add("IJulia")
julia> using IJulia
julia> notebook()
```
- These commands will open a jupyter in your web browser. Navigate in jupyter to the notebook file you have downloaded and open it.
## Authors
This material is created by [Francesc Verdugo](https://github.com/fverdugo/) with the help of [Gelieza Kötterheinrich](https://www.linkedin.com/in/gelieza-k/). Part of the notebooks are based on the course slides by [Henri Bal](https://www.vuhpdc.net/henri-bal/).
## License
All material on this page that is original to this course may be used under a [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) license.
## Acknowledgment
This page was created with the support of the Faculty of Science of [Vrije Universiteit Amsterdam](https://vu.nl) in the framework of the project "Interactive lecture notes and exercises for the Programming Large-Scale Parallel Systems course" funded by the "Innovation budget BETA 2023 Studievoorschotmiddelen (SVM) towards Activated Blended Learning".
-445
View File
@@ -1,445 +0,0 @@
# Solutions
## Julia Basics
### Exercise 1
```julia
function ex1(a)
j = 1
m = a[j]
for (i,ai) in enumerate(a)
if m < ai
m = ai
j = i
end
end
(m,j)
end
```
### Exercise 2
```julia
ex2(f,g) = x -> f(x) + g(x)
```
### Exercise 3
```julia
n = 1000
x = LinRange(-1.7,0.7,n)
y = LinRange(-1.2,1.2,n)
values = zeros(n,n)
for j in 1:n
for i in 1:n
values[i,j] = surprise(x[i],y[j])
end
end
using GLMakie
heatmap(x,y,values)
```
## Asynchronous programming in Julia
## Distributed computing in Julia
### Exercise 1
```julia
f = () -> Channel{Int}(1)
worker_ids = workers()
chnls = [ RemoteChannel(f,w) for w in worker_ids ]
@sync for (iw,w) in enumerate(worker_ids)
@spawnat w begin
chnl_snd = chnls[iw]
if iw == 1
chnl_rcv = chnls[end]
msg = 2
println("msg = $msg")
put!(chnl_snd,msg)
msg = take!(chnl_rcv)
println("msg = $msg")
else
chnl_rcv = chnls[iw-1]
msg = take!(chnl_rcv)
msg += 1
println("msg = $msg")
put!(chnl_snd,msg)
end
end
end
```
This is another possible solution that does not use remote channels.
```julia
@everywhere function work(msg,iw,worker_ids)
println("msg = $msg")
if iw < length(worker_ids)
inext = iw+1
next = worker_ids[iw+1]
@fetchfrom next work(msg+1,inext,worker_ids)
else
@fetchfrom worker_ids[1] println("msg = $msg")
end
return nothing
end
msg = 2
iw = 1
worker_ids = workers()
@fetchfrom worker_ids[iw] work(msg,iw,worker_ids)
```
## Matrix-matrix multiplication
### Exercise 1
```julia
function matmul_dist_3!(C,A,B)
m = size(C,1)
n = size(C,2)
l = size(A,2)
@assert size(A,1) == m
@assert size(B,2) == n
@assert size(B,1) == l
@assert mod(m,nworkers()) == 0
nrows_w = div(m,nworkers())
@sync for (iw,w) in enumerate(workers())
lb = 1 + (iw-1)*nrows_w
ub = iw*nrows_w
A_w = A[lb:ub,:]
ftr = @spawnat w begin
C_w = similar(A_w)
matmul_seq!(C_w,A_w,B)
C_w
end
@async C[lb:ub,:] = fetch(ftr)
end
C
end
@everywhere function matmul_seq!(C,A,B)
m = size(C,1)
n = size(C,2)
l = size(A,2)
@assert size(A,1) == m
@assert size(B,2) == n
@assert size(B,1) == l
z = zero(eltype(C))
for j in 1:n
for i in 1:m
Cij = z
for k in 1:l
@inbounds Cij = Cij + A[i,k]*B[k,j]
end
C[i,j] = Cij
end
end
C
end
```
## MPI (Point-to-point)
### Exercise 1
```julia
function matmul_mpi_3!(C,A,B)
comm = MPI.COMM_WORLD
rank = MPI.Comm_rank(comm)
P = MPI.Comm_size(comm)
if rank == 0
N = size(A,1)
myB = B
for dest in 1:(P-1)
MPI.Send(B,comm;dest)
end
else
source = 0
status = MPI.Probe(comm,MPI.Status;source)
count = MPI.Get_count(status,eltype(B))
N = Int(sqrt(count))
myB = zeros(N,N)
MPI.Recv!(myB,comm;source)
end
L = div(N,P)
myA = zeros(L,N)
if rank == 0
lb = L*rank+1
ub = L*(rank+1)
myA[:,:] = view(A,lb:ub,:)
for dest in 1:(P-1)
lb = L*dest+1
ub = L*(dest+1)
MPI.Send(view(A,lb:ub,:),comm;dest)
end
else
source = 0
MPI.Recv!(myA,comm;source)
end
myC = myA*myB
if rank == 0
lb = L*rank+1
ub = L*(rank+1)
C[lb:ub,:] = myC
for source in 1:(P-1)
lb = L*source+1
ub = L*(source+1)
MPI.Recv!(view(C,lb:ub,:),comm;source)
end
else
dest = 0
MPI.Send(myC,comm;dest)
end
C
end
```
### Exercise 2
```julia
using MPI
MPI.Init()
comm = MPI.COMM_WORLD
rank = MPI.Comm_rank(comm)
nranks = MPI.Comm_size(comm)
buffer = Ref(0)
if rank == 0
msg = 2
buffer[] = msg
println("msg = $(buffer[])")
MPI.Send(buffer,comm;dest=rank+1,tag=0)
MPI.Recv!(buffer,comm;source=nranks-1,tag=0)
println("msg = $(buffer[])")
else
dest = if (rank != nranks-1)
rank+1
else
0
end
MPI.Recv!(buffer,comm;source=rank-1,tag=0)
buffer[] += 1
println("msg = $(buffer[])")
MPI.Send(buffer,comm;dest,tag=0)
end
```
## MPI (collectives)
### Exercise 1
```julia
function matmul_mpi_3!(C,A,B)
comm = MPI.COMM_WORLD
rank = MPI.Comm_rank(comm)
P = MPI.Comm_size(comm)
root = 0
if rank == root
N = size(A,1)
Nref = Ref(N)
else
Nref = Ref(0)
end
MPI.Bcast!(Nref,comm;root)
N = Nref[]
if rank == root
myB = B
else
myB = zeros(N,N)
end
MPI.Bcast!(myB,comm;root)
L = div(N,P)
# Tricky part
# Julia works "col major"
myAt = zeros(N,L)
At = collect(transpose(A))
MPI.Scatter!(At,myAt,comm;root)
myCt = transpose(myB)*myAt
Ct = similar(C)
MPI.Gather!(myCt,Ct,comm;root)
C .= transpose(Ct)
C
end
```
This other solution uses a column partition instead of a row partition.
It is more natural to work with column partitions in Julia if possible since matrices are
in "col major" format. Note that we do not need all the auxiliary transposes anymore.
```julia
function matmul_mpi_3!(C,A,B)
comm = MPI.COMM_WORLD
rank = MPI.Comm_rank(comm)
P = MPI.Comm_size(comm)
root = 0
if rank == root
N = size(A,1)
Nref = Ref(N)
else
Nref = Ref(0)
end
MPI.Bcast!(Nref,comm;root)
N = Nref[]
if rank == root
myA = A
else
myA = zeros(N,N)
end
MPI.Bcast!(myA,comm;root)
L = div(N,P)
myB = zeros(N,L)
MPI.Scatter!(B,myB,comm;root)
myC = myA*myB
MPI.Gather!(myC,C,comm;root)
C
end
```
## Jacobi method
### Exercise 1
```julia
function jacobi_mpi(n,niters)
u, u_new = init(n,comm)
load = length(u)-2
rank = MPI.Comm_rank(comm)
nranks = MPI.Comm_size(comm)
nreqs = 2*((rank != 0) + (rank != (nranks-1)))
reqs = MPI.MultiRequest(nreqs)
for t in 1:niters
ireq = 0
if rank != 0
neig_rank = rank-1
u_snd = view(u,2:2)
u_rcv = view(u,1:1)
dest = neig_rank
source = neig_rank
ireq += 1
MPI.Isend(u_snd,comm,reqs[ireq];dest)
ireq += 1
MPI.Irecv!(u_rcv,comm,reqs[ireq];source)
end
if rank != (nranks-1)
neig_rank = rank+1
u_snd = view(u,(load+1):(load+1))
u_rcv = view(u,(load+2):(load+2))
dest = neig_rank
source = neig_rank
ireq += 1
MPI.Isend(u_snd,comm,reqs[ireq];dest)
ireq += 1
MPI.Irecv!(u_rcv,comm,reqs[ireq];source)
end
# Upload interior cells
for i in 3:load
u_new[i] = 0.5*(u[i-1]+u[i+1])
end
# Wait for the communications to finish
MPI.Waitall(reqs)
# Update boundaries
for i in (2,load+1)
u_new[i] = 0.5*(u[i-1]+u[i+1])
end
u, u_new = u_new, u
end
return u
end
```
### Exercise 2
```julia
function jacobi_mpi(n,niters,tol,comm) # new tol arg
u, u_new = init(n,comm)
load = length(u)-2
rank = MPI.Comm_rank(comm)
nranks = MPI.Comm_size(comm)
nreqs = 2*((rank != 0) + (rank != (nranks-1)))
reqs = MPI.MultiRequest(nreqs)
for t in 1:niters
ireq = 0
if rank != 0
neig_rank = rank-1
u_snd = view(u,2:2)
u_rcv = view(u,1:1)
dest = neig_rank
source = neig_rank
ireq += 1
MPI.Isend(u_snd,comm,reqs[ireq];dest)
ireq += 1
MPI.Irecv!(u_rcv,comm,reqs[ireq];source)
end
if rank != (nranks-1)
neig_rank = rank+1
u_snd = view(u,(load+1):(load+1))
u_rcv = view(u,(load+2):(load+2))
dest = neig_rank
source = neig_rank
ireq += 1
MPI.Isend(u_snd,comm,reqs[ireq];dest)
ireq += 1
MPI.Irecv!(u_rcv,comm,reqs[ireq];source)
end
MPI.Waitall(reqs)
# Compute the max diff in the current
# rank while doing the local update
mydiff = 0.0
for i in 2:load+1
u_new[i] = 0.5*(u[i-1]+u[i+1])
diff_i = abs(u_new[i] - u[i])
mydiff = max(mydiff,diff_i)
end
# Now we need to find the global diff
diff_ref = Ref(mydiff)
MPI.Allreduce!(diff_ref,max,comm)
diff = diff_ref[]
# If global diff below tol, stop!
if diff < tol
return u_new
end
u, u_new = u_new, u
end
return u
end
```
## All pairs of shortest paths
### Exercise 1
```julia
function floyd_iterations!(myC,comm)
L = size(myC,1)
N = size(myC,2)
rank = MPI.Comm_rank(comm)
P = MPI.Comm_size(comm)
lb = L*rank+1
ub = L*(rank+1)
C_k = similar(myC,N)
for k in 1:N
if (lb<=k) && (k<=ub)
# If I have the row, fill in the buffer
myk = (k-lb)+1
C_k[:] = view(myC,myk,:)
end
# We need to find out the owner of row k.
# Easy since N is a multiple of P
root = div(k-1,L)
MPI.Bcast!(C_k,comm;root)
# Now, we have the data dependencies and
# we can do the updates locally
for j in 1:N
for i in 1:L
myC[i,j] = min(myC[i,j],myC[i,k]+C_k[j])
end
end
end
myC
end
```
+2
View File
@@ -0,0 +1,2 @@
<!--This file is automatically generated by Documenter.jl-->
<meta http-equiv="refresh" content="0; url=./dev/"/>
File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 391 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

-510
View File
@@ -1,510 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="204.66751mm"
height="113.93094mm"
viewBox="0 0 204.66752 113.93094"
version="1.1"
id="svg8"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
sodipodi:docname="fig_matmul_1.svg"
inkscape:export-filename="/home/francesc/repos/XM_40017/notebooks/figures/fig_matmul_1.png"
inkscape:export-xdpi="200"
inkscape:export-ydpi="200">
<defs
id="defs2">
<rect
x="-43.32487"
y="75.601889"
width="55.095874"
height="26.65206"
id="rect937" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1130" />
<rect
x="18.228422"
y="221.26402"
width="178.94536"
height="38.954247"
id="rect1059" />
<rect
x="81.231514"
y="-71.233147"
width="71.468948"
height="19.676786"
id="rect1433-5" />
<rect
x="81.231514"
y="-71.233147"
width="71.468948"
height="19.676786"
id="rect1007" />
<rect
x="81.231514"
y="-71.233147"
width="71.468948"
height="19.676786"
id="rect1668" />
<rect
x="81.231514"
y="-71.233147"
width="71.468948"
height="19.676786"
id="rect1010" />
<rect
x="81.231514"
y="-71.233147"
width="71.468948"
height="19.676786"
id="rect1676" />
<rect
x="81.231514"
y="-71.233147"
width="71.468948"
height="19.676786"
id="rect1013" />
<rect
x="18.228422"
y="221.26402"
width="178.94536"
height="38.954247"
id="rect1059-9" />
<rect
x="18.228422"
y="221.26402"
width="178.94536"
height="38.954247"
id="rect1076" />
<rect
x="18.228422"
y="221.26402"
width="178.94536"
height="38.954247"
id="rect1116" />
<rect
x="18.228422"
y="221.26402"
width="178.94536"
height="38.954247"
id="rect1126" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1130-2" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1143" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1176" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1184" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1190" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1190-0" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1201" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1190-3" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect946" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect980" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect988" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect980-7" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect999" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1033" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1190-36" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect952" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1015" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1025" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1015-5" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1036" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1190-36-6" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1078" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1122" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1124" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1124-1" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1167" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1203" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.49497475"
inkscape:cx="728.49816"
inkscape:cy="266.45551"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
inkscape:document-rotation="0"
showgrid="false"
inkscape:window-width="1543"
inkscape:window-height="870"
inkscape:window-x="2658"
inkscape:window-y="162"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
showguides="false"
inkscape:snap-global="false" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-8.4171906,-107.52556)">
<path
style="fill:none;stroke:#000000;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 128.5853,166.79665 36.70974,0"
id="path1168"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 57.87148,195.69174 48.77915,-29.89763"
id="path1168-3"
sodipodi:nodetypes="cc" />
<g
id="g1148"
transform="translate(-30.394694,270.52777)">
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79375;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 129.89807,-136.23112 12.99038,7.5 17.32051,-10 -12.99038,-7.5 z"
id="path1063" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79375;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 142.88845,-128.73112 v 39.999996 l 17.32051,-10 v -39.999996"
id="path1065"
sodipodi:nodetypes="cccc" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79375;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 129.89807,-136.23112 v 39.999996 l 12.99038,7.5"
id="path1067"
sodipodi:nodetypes="ccc" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 147.21857,-126.23112 v 15 l 4.33013,-2.5 v -15 l -4.33013,2.5"
id="path1069" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 145.48652,-96.231123 v 1.999999 l 12.99038,-7.499996 v -2 z"
id="path1071" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 145.48652,-100.23111 v 2.000003 l 12.99038,-7.500013 v -2 z"
id="path1073" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 145.48652,-104.23111 v 2 l 12.99038,-7.50001 v -2 z"
id="path1075" />
</g>
<g
id="g1157"
transform="translate(-9.7126443,270.52775)">
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79375;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 169.05642,-136.23112 12.99038,7.5 17.32051,-10 -12.99038,-7.5 z"
id="path1086" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79375;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 182.0468,-128.73112 v 39.999996 l 17.32051,-10 v -39.999996"
id="path1088"
sodipodi:nodetypes="cccc" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79375;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 169.05642,-136.23112 v 39.999996 l 12.99038,7.5"
id="path1090"
sodipodi:nodetypes="ccc" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 186.37692,-126.23112 v 15 l 4.33013,-2.5 v -15 l -4.33013,2.5"
id="path1092" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 184.64487,-96.231123 v 1.999999 l 12.99038,-7.499996 v -2 z"
id="path1094" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 184.64487,-100.23111 v 2.000003 l 12.99038,-7.500013 v -2 z"
id="path1096" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 184.64487,-104.23111 v 2 l 12.99038,-7.50001 v -2 z"
id="path1098" />
</g>
<g
id="g1148-3"
transform="translate(-100.60542,297.42286)">
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79375;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 129.89807,-136.23112 12.99038,7.5 17.32051,-10 -12.99038,-7.5 z"
id="path1063-6" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79375;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 142.88845,-128.73112 v 39.999996 l 17.32051,-10 v -39.999996"
id="path1065-7"
sodipodi:nodetypes="cccc" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79375;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 129.89807,-136.23112 v 39.999996 l 12.99038,7.5"
id="path1067-5"
sodipodi:nodetypes="ccc" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 147.21857,-126.23112 v 15 l 4.33013,-2.5 v -15 l -4.33013,2.5"
id="path1069-3" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 145.48652,-96.231123 v 1.999999 l 12.99038,-7.499996 v -2 z"
id="path1071-5" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 145.48652,-100.23111 v 2.000003 l 12.99038,-7.500013 v -2 z"
id="path1073-6" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 145.48652,-104.23111 v 2 l 12.99038,-7.50001 v -2 z"
id="path1075-2" />
</g>
<text
xml:space="preserve"
id="text1128"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;line-height:1.25;font-family:Hack;-inkscape-font-specification:Hack;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1130);"
transform="matrix(1.870078,0,0,1.870078,-12.48415,127.92857)"><tspan
x="24.056641"
y="46.895068"
id="tspan73"><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Hack;-inkscape-font-specification:Hack"
id="tspan71">proc 1</tspan></tspan></text>
<text
xml:space="preserve"
id="text1128-7"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;line-height:1.25;font-family:Hack;-inkscape-font-specification:Hack;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1130-2);"
transform="matrix(1.870078,0,0,1.870078,58.900914,33.172896)"><tspan
x="24.056641"
y="46.895068"
id="tspan78"><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Hack;-inkscape-font-specification:Hack"
id="tspan76">proc 2</tspan></tspan></text>
<text
xml:space="preserve"
id="text1182"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;line-height:1.25;font-family:Hack;-inkscape-font-specification:Hack;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1184);"
transform="matrix(1.870078,0,0,1.870078,120.13204,33.172896)"><tspan
x="24.056641"
y="46.895068"
id="tspan83"><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Hack;-inkscape-font-specification:Hack"
id="tspan81">proc 3</tspan></tspan></text>
<text
xml:space="preserve"
id="text935"
style="font-family:Hack;font-size:3.175px;line-height:1.25;letter-spacing:0px;word-spacing:0px;-inkscape-font-specification:'Hack Italic';font-style:italic;white-space:pre;shape-inside:url(#rect937);" />
<rect
style="fill:#ff0000;fill-opacity:0.21383099;stroke:#ff0000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
id="rect941"
width="24.735849"
height="19.344206"
x="14.552141"
y="118.7655" />
<text
y="28.370567"
x="-19.855066"
xml:space="preserve"
id="text1188-7-3"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:5.93749762px;line-height:1.25;font-family:Hack;-inkscape-font-specification:'Hack Bold';letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1190-36);stroke-width:1.87007797"><tspan
style="stroke-width:1.87007797"
x="25.13273"
y="116.068"
id="tspan91-6"><tspan
style="stroke-width:1.87007797"
id="tspan89-7">A</tspan></tspan></text>
<rect
style="fill:#0000ff;fill-opacity:0.21383099;stroke:#0000ff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
id="rect991"
width="24.464821"
height="12.890343"
x="-143.27554"
y="43.231026"
transform="rotate(-90)" />
<text
y="28.370567"
x="1.784595"
xml:space="preserve"
id="text1013-5"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:5.93749762px;line-height:1.25;font-family:Hack;-inkscape-font-specification:'Hack Bold';letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1015);stroke-width:1.87007797"><tspan
style="stroke-width:1.87007797"
x="46.772388"
y="116.068"
id="tspan97-3"><tspan
style="stroke-width:1.87007797"
id="tspan95-5">B</tspan></tspan></text>
<rect
style="fill:#008000;fill-opacity:0.21383099;stroke:#008000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
id="rect1017"
width="12.825157"
height="19.552177"
x="60.516609"
y="118.8185" />
<text
y="28.370567"
x="20.839518"
xml:space="preserve"
id="text1023-6"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:5.93749762px;line-height:1.25;font-family:Hack;-inkscape-font-specification:'Hack Bold';letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1025);stroke-width:1.87007797"><tspan
style="stroke-width:1.87007797"
x="65.827309"
y="116.068"
id="tspan103-2"><tspan
style="stroke-width:1.87007797"
id="tspan101-9">C</tspan></tspan></text>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

-611
View File
@@ -1,611 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="204.66751mm"
height="113.93094mm"
viewBox="0 0 204.66752 113.93094"
version="1.1"
id="svg8"
inkscape:version="1.0.2 (1.0.2+r75+1)"
sodipodi:docname="fig_matmul_dist.svg"
inkscape:export-filename="/home/fverdugo/Code/jl/PLSPS/lectures/fig_matmul_2.png"
inkscape:export-xdpi="200"
inkscape:export-ydpi="200">
<defs
id="defs2">
<rect
x="-43.32487"
y="75.601889"
width="55.095874"
height="26.65206"
id="rect937" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1130" />
<rect
x="18.228422"
y="221.26402"
width="178.94536"
height="38.954247"
id="rect1059" />
<rect
x="81.231514"
y="-71.233147"
width="71.468948"
height="19.676786"
id="rect1433-5" />
<rect
x="81.231514"
y="-71.233147"
width="71.468948"
height="19.676786"
id="rect1007" />
<rect
x="81.231514"
y="-71.233147"
width="71.468948"
height="19.676786"
id="rect1668" />
<rect
x="81.231514"
y="-71.233147"
width="71.468948"
height="19.676786"
id="rect1010" />
<rect
x="81.231514"
y="-71.233147"
width="71.468948"
height="19.676786"
id="rect1676" />
<rect
x="81.231514"
y="-71.233147"
width="71.468948"
height="19.676786"
id="rect1013" />
<rect
x="18.228422"
y="221.26402"
width="178.94536"
height="38.954247"
id="rect1059-9" />
<rect
x="18.228422"
y="221.26402"
width="178.94536"
height="38.954247"
id="rect1076" />
<rect
x="18.228422"
y="221.26402"
width="178.94536"
height="38.954247"
id="rect1116" />
<rect
x="18.228422"
y="221.26402"
width="178.94536"
height="38.954247"
id="rect1126" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1130-2" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1143" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1176" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1184" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1190" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1190-0" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1201" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1190-3" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect946" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect980" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect988" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect980-7" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect999" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1033" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1190-36" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect952" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1015" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1025" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1015-5" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1036" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1190-36-6" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1078" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1122" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1124" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1124-1" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1167" />
<rect
x="24.057535"
y="44.08559"
width="96.728912"
height="20.299622"
id="rect1203" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.7"
inkscape:cx="116.13187"
inkscape:cy="283.51733"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
inkscape:document-rotation="0"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1025"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
showguides="false"
inkscape:snap-global="false" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-8.4171906,-107.52556)">
<path
style="fill:none;stroke:#000000;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 128.5853,166.79665 36.70974,0"
id="path1168"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 57.87148,195.69174 48.77915,-29.89763"
id="path1168-3"
sodipodi:nodetypes="cc" />
<g
id="g1148"
transform="translate(-30.394694,270.52777)">
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79375;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 129.89807,-136.23112 12.99038,7.5 17.32051,-10 -12.99038,-7.5 z"
id="path1063" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79375;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 142.88845,-128.73112 v 39.999996 l 17.32051,-10 v -39.999996"
id="path1065"
sodipodi:nodetypes="cccc" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79375;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 129.89807,-136.23112 v 39.999996 l 12.99038,7.5"
id="path1067"
sodipodi:nodetypes="ccc" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 147.21857,-126.23112 v 15 l 4.33013,-2.5 v -15 l -4.33013,2.5"
id="path1069" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 145.48652,-96.231123 v 1.999999 l 12.99038,-7.499996 v -2 z"
id="path1071" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 145.48652,-100.23111 v 2.000003 l 12.99038,-7.500013 v -2 z"
id="path1073" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 145.48652,-104.23111 v 2 l 12.99038,-7.50001 v -2 z"
id="path1075" />
</g>
<g
id="g1157"
transform="translate(-9.7126443,270.52775)">
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79375;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 169.05642,-136.23112 12.99038,7.5 17.32051,-10 -12.99038,-7.5 z"
id="path1086" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79375;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 182.0468,-128.73112 v 39.999996 l 17.32051,-10 v -39.999996"
id="path1088"
sodipodi:nodetypes="cccc" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79375;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 169.05642,-136.23112 v 39.999996 l 12.99038,7.5"
id="path1090"
sodipodi:nodetypes="ccc" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 186.37692,-126.23112 v 15 l 4.33013,-2.5 v -15 l -4.33013,2.5"
id="path1092" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 184.64487,-96.231123 v 1.999999 l 12.99038,-7.499996 v -2 z"
id="path1094" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 184.64487,-100.23111 v 2.000003 l 12.99038,-7.500013 v -2 z"
id="path1096" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 184.64487,-104.23111 v 2 l 12.99038,-7.50001 v -2 z"
id="path1098" />
</g>
<g
id="g1148-3"
transform="translate(-100.60542,297.42286)">
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79375;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 129.89807,-136.23112 12.99038,7.5 17.32051,-10 -12.99038,-7.5 z"
id="path1063-6" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79375;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 142.88845,-128.73112 v 39.999996 l 17.32051,-10 v -39.999996"
id="path1065-7"
sodipodi:nodetypes="cccc" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79375;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 129.89807,-136.23112 v 39.999996 l 12.99038,7.5"
id="path1067-5"
sodipodi:nodetypes="ccc" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 147.21857,-126.23112 v 15 l 4.33013,-2.5 v -15 l -4.33013,2.5"
id="path1069-3" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 145.48652,-96.231123 v 1.999999 l 12.99038,-7.499996 v -2 z"
id="path1071-5" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 145.48652,-100.23111 v 2.000003 l 12.99038,-7.500013 v -2 z"
id="path1073-6" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 145.48652,-104.23111 v 2 l 12.99038,-7.50001 v -2 z"
id="path1075-2" />
</g>
<text
xml:space="preserve"
id="text1128"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;line-height:1.25;font-family:Hack;-inkscape-font-specification:Hack;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1130);"
transform="matrix(1.870078,0,0,1.870078,-12.48415,127.92857)"><tspan
x="24.056641"
y="46.895068"><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Hack;-inkscape-font-specification:Hack">proc 1</tspan></tspan></text>
<text
xml:space="preserve"
id="text1128-7"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;line-height:1.25;font-family:Hack;-inkscape-font-specification:Hack;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1130-2);"
transform="matrix(1.870078,0,0,1.870078,58.900914,33.172896)"><tspan
x="24.056641"
y="46.895068"><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Hack;-inkscape-font-specification:Hack">proc 2</tspan></tspan></text>
<text
xml:space="preserve"
id="text1182"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;line-height:1.25;font-family:Hack;-inkscape-font-specification:Hack;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1184);"
transform="matrix(1.870078,0,0,1.870078,120.13204,33.172896)"><tspan
x="24.056641"
y="46.895068"><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Hack;-inkscape-font-specification:Hack">proc 3</tspan></tspan></text>
<rect
style="fill:none;stroke:#cccccc;stroke-width:1.465;stroke-linecap:round;stroke-linejoin:round"
id="rect1266"
width="203.20251"
height="112.46594"
x="9.1496906"
y="108.25806" />
<text
xml:space="preserve"
id="text935"
style="font-family:Hack;font-size:3.175px;line-height:1.25;letter-spacing:0px;word-spacing:0px;-inkscape-font-specification:'Hack Italic';font-style:italic;white-space:pre;shape-inside:url(#rect937);" />
<rect
style="fill:#ff0000;fill-opacity:0.213831;stroke:#ff0000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
id="rect941"
width="24.735849"
height="19.344206"
x="16.550077"
y="119.69792" />
<text
xml:space="preserve"
id="text1188-7"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.175px;line-height:1.25;font-family:Hack;-inkscape-font-specification:'Hack Bold';letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1190-36);"
transform="matrix(1.870078,0,0,1.870078,-17.85713,29.302991)"><tspan
x="24.056641"
y="46.895068"><tspan>A</tspan></tspan></text>
<rect
style="fill:#0000ff;fill-opacity:0.213831;stroke:#0000ff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
id="rect991"
width="24.464819"
height="12.890343"
x="-144.20796"
y="45.228962"
transform="rotate(-90)" />
<text
xml:space="preserve"
id="text1013"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.175px;line-height:1.25;font-family:Hack;-inkscape-font-specification:'Hack Bold';letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1015);"
transform="matrix(1.870078,0,0,1.870078,3.7825311,29.302991)"><tspan
x="24.056641"
y="46.895068"><tspan>B</tspan></tspan></text>
<rect
style="fill:#008000;fill-opacity:0.213831;stroke:#008000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
id="rect1017"
width="12.825157"
height="19.552177"
x="62.514542"
y="119.75092" />
<text
xml:space="preserve"
id="text1023"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.175px;line-height:1.25;font-family:Hack;-inkscape-font-specification:'Hack Bold';letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1025);"
transform="matrix(1.870078,0,0,1.870078,22.837454,29.302991)"><tspan
x="24.056641"
y="46.895068"><tspan>C</tspan></tspan></text>
<rect
style="fill:#0000ff;fill-opacity:0.213831;stroke:#0000ff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
id="rect991-3"
width="24.464819"
height="12.890343"
x="-85.056168"
y="191.22739"
transform="rotate(-90)" />
<text
xml:space="preserve"
id="text1013-5"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.175px;line-height:1.25;font-family:Hack;-inkscape-font-specification:'Hack Bold';letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1015-5);"
transform="matrix(1.870078,0,0,1.870078,152.52129,-29.84879)"><tspan
x="24.056641"
y="46.895068"><tspan>B</tspan></tspan></text>
<rect
style="fill:#ff0000;fill-opacity:0.213831;stroke:#ff0000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
id="rect1067"
width="24.735849"
height="9.3721132"
x="162.76842"
y="60.860783" />
<text
xml:space="preserve"
id="text1188-7-2"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.175px;line-height:1.25;font-family:Hack;-inkscape-font-specification:'Hack Bold';letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1190-36-6);"
transform="matrix(1.870078,0,0,1.870078,120.75285,-28.827227)"><tspan
x="24.056641"
y="46.895068"><tspan>Aw</tspan></tspan></text>
<rect
style="fill:#0000ff;fill-opacity:0.213831;stroke:#0000ff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
id="rect1106"
width="24.464819"
height="12.890343"
x="-85.056168"
y="253.19373"
transform="rotate(-90)" />
<text
xml:space="preserve"
id="text1112"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.175px;line-height:1.25;font-family:Hack;-inkscape-font-specification:'Hack Bold';letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1122);"
transform="matrix(1.870078,0,0,1.870078,213.4482,-29.84879)"><tspan
x="24.056641"
y="46.895068"><tspan>B</tspan></tspan></text>
<rect
style="fill:#ff0000;fill-opacity:0.213831;stroke:#ff0000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
id="rect1114"
width="24.735849"
height="9.3721132"
x="224.73477"
y="75.112381" />
<text
xml:space="preserve"
id="text1120"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.175px;line-height:1.25;font-family:Hack;-inkscape-font-specification:'Hack Bold';letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1124);"
transform="matrix(1.870078,0,0,1.870078,182.7192,-14.575627)"><tspan
x="24.056641"
y="46.895068"><tspan>Aw</tspan></tspan></text>
<path
style="fill:#ff0000;stroke:#ff0000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 19.799029,88.923994 H 44.014785"
id="path1130" />
<g
id="g1388"
transform="translate(-169.22149,-62.931698)">
<rect
style="fill:#008000;fill-opacity:0.213831;stroke:#008000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect1156"
width="12.989205"
height="9.5581169"
x="276.90524"
y="259.22504" />
<text
xml:space="preserve"
id="text1120-2"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.175px;line-height:1.25;font-family:Hack;-inkscape-font-specification:'Hack Bold';letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1124-1);"
transform="matrix(1.870078,0,0,1.870078,234.00099,168.68114)"><tspan
x="24.056641"
y="46.895068"><tspan>Cw</tspan></tspan></text>
<rect
style="fill:#008000;fill-opacity:0.213831;stroke:#008000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect1195"
width="12.989205"
height="9.5581169"
x="341.09048"
y="259.22714" />
<text
xml:space="preserve"
id="text1201"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.175px;line-height:1.25;font-family:Hack;-inkscape-font-specification:'Hack Bold';letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1203);"
transform="matrix(1.870078,0,0,1.870078,298.18621,168.68323)"><tspan
x="24.056641"
y="46.895068"><tspan>Cw</tspan></tspan></text>
<path
style="fill:none;stroke:#008000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 231.91804,192.10089 h 12.32514"
id="path1205" />
<g
id="g1230"
transform="translate(169.31458,62.926738)">
<path
style="fill:none;stroke:#999999;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 178.3128,201.16751 68.641596,134.34821 m 0.07376,-10.33845 45.578434,77.50543"
id="path1132"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;stroke:#999999;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 69.508478,137.0957 -1.464614,-3.49633 3.390536,0.8633"
id="path1134" />
<path
style="fill:none;stroke:#999999;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 68.562733,127.19194 -0.369006,-3.7727 2.985461,1.82431"
id="path1134-9" />
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Some files were not shown because too many files have changed in this diff Show More