From 63b44f7400e560f94f5315925af54c5eb9e8f344 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Jan 2022 20:11:28 +0000 Subject: [PATCH 1/9] Bump ipython from 6.1 to 7.16.3 Bumps [ipython](https://github.com/ipython/ipython) from 6.1 to 7.16.3. - [Release notes](https://github.com/ipython/ipython/releases) - [Commits](https://github.com/ipython/ipython/compare/6.1.0...7.16.3) --- updated-dependencies: - dependency-name: ipython dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 3013b0a..946c1e9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,4 +4,4 @@ matplotlib==2.2.4 cython cffi numexpr -ipython==6.1 +ipython==7.16.3 From 4917e08047d49bfa3e7835b71276a2a3ac6bc855 Mon Sep 17 00:00:00 2001 From: Jussi Enkovaara Date: Thu, 17 Mar 2022 11:32:51 +0200 Subject: [PATCH 2/9] Split NumPy slides --- docs/{01-numpy.md => 01-numpy-basics.md} | 0 docs/02-numpy-tools.md | 104 +++++++++++++ docs/03-numpy-advanced.md | 184 +++++++++++++++++++++++ 3 files changed, 288 insertions(+) rename docs/{01-numpy.md => 01-numpy-basics.md} (100%) create mode 100644 docs/02-numpy-tools.md create mode 100644 docs/03-numpy-advanced.md diff --git a/docs/01-numpy.md b/docs/01-numpy-basics.md similarity index 100% rename from docs/01-numpy.md rename to docs/01-numpy-basics.md diff --git a/docs/02-numpy-tools.md b/docs/02-numpy-tools.md new file mode 100644 index 0000000..0f331fe --- /dev/null +++ b/docs/02-numpy-tools.md @@ -0,0 +1,104 @@ +--- +title: Numpy tools +lang: en +--- + + +# Numpy tools + +- NumPy contains ready to use tools for many common tasks +- I/O +- Random numbers +- Polynomials +- Linear algebra + + +# I/O with Numpy + +- Numpy provides functions for reading data from file and for writing data + into the files +- Simple text files + - `numpy.loadtxt` + - `numpy.savetxt` + - Data in regular column layout + - Can deal with comments and different column delimiters + + +# Random numbers + +- The module `numpy.random` provides several functions for constructing + random arrays + - `random`: uniform random numbers + - `normal`: normal distribution + - `choice`: random sample from given array + - ... + +```python +>>> import numpy.random as rnd +>>> rnd.random((2,2)) +array([[ 0.02909142, 0.90848 ], + [ 0.9471314 , 0.31424393]]) + +>>> rnd.choice(numpy.arange(4), 10) +array([0, 1, 1, 2, 1, 1, 2, 0, 2, 3]) +``` + + +# Polynomials + +- Polynomial is defined by an array of coefficients p + $p(x, N) = p[0] x^{N-1} + p[1] x^{N-2} + ... + p[N-1]$ +- For example: + - Least square fitting: `numpy.polyfit` + - Evaluating polynomials: `numpy.polyval` + - Roots of polynomial: `numpy.roots` + +```python +>>> x = numpy.linspace(-4, 4, 7) +>>> y = x**2 + rnd.random(x.shape) +>>> +>>> p = numpy.polyfit(x, y, 2) +>>> p +array([ 0.96869003, -0.01157275, 0.69352514]) +``` + + +# Linear algebra + +- Numpy can calculate matrix and vector products efficiently: `dot`, + `vdot`, ... +- Eigenproblems: `linalg.eig`, `linalg.eigvals`, ... +- Linear systems and matrix inversion: `linalg.solve`, `linalg.inv` + +```python +>>> A = numpy.array(((2, 1), (1, 3))) +>>> B = numpy.array(((-2, 4.2), (4.2, 6))) +>>> C = numpy.dot(A, B) +>>> +>>> b = numpy.array((1, 2)) +>>> numpy.linalg.solve(C, b) # solve C x = b +array([ 0.04453441, 0.06882591]) +``` + + +# Linear algebra + +- Normally, NumPy utilises high performance libraries in linear algebra + operations +- Example: matrix multiplication C = A * B matrix dimension 1000 + - pure python: 522.30 s + - naive C: 1.50 s + - numpy.dot: 0.04 s + - library call from C: 0.04 s + + + +# Summary + +- NumPy contains many useful tools for numerical computing +- [Scipy](https://scipy.org/) includes even wider set of utilities for + scientific computing +- Further useful packages + - Visualization: [matplotlib](https://matplotlib.org/), + [Mayavi](https://docs.enthought.com/mayavi/mayavi/) + - Data analysis: [pandas](https://pandas.pydata.org/) diff --git a/docs/03-numpy-advanced.md b/docs/03-numpy-advanced.md new file mode 100644 index 0000000..d6d643f --- /dev/null +++ b/docs/03-numpy-advanced.md @@ -0,0 +1,184 @@ +--- +title: Advanced concepts in NumPy +lang: en +--- + + +# Anatomy of NumPy array + +- **ndarray** type is made of + - one dimensional contiguous block of memory (raw data) + - indexing scheme: how to locate an element + - data type descriptor: how to interpret an element + +![](img/ndarray-in-memory.svg){.center width=50%} + + +# NumPy indexing + +- There are many possible ways of arranging items of N-dimensional + array in a 1-dimensional block +- NumPy uses **striding** where N-dimensional index ($n_0, n_1, ..., n_{N-1}$) + corresponds to offset from the beginning of 1-dimensional block + +$$ +offset = \sum_{k=0}^{N-1} s_k n_k, s_k \text{ is stride in dimension k} +$$ + + +![](img/ndarray-in-memory-offset.svg){.center width=50%} + +# ndarray attributes + +`a = numpy.array(...)` + : `a.flags` + : various information about memory layout + + `a.strides` + : bytes to step in each dimension when traversing + + `a.itemsize` + : size of one array element in bytes + + `a.data` + : Python buffer object pointing to start of arrays data + + `a.__array_interface__` + : Python internal interface + + +# Advanced indexing + +- Numpy arrays can be indexed also with other arrays (integer or + boolean) + +```python +>>> x = numpy.arange(10,1,-1) +>>> x +array([10, 9, 8, 7, 6, 5, 4, 3, 2]) + +>>> x[numpy.array([3, 3, 1, 8])] +array([7, 7, 9, 2]) +``` + +- Boolean "mask" arrays + +```python +>>> m = x > 7 +>>> m +array([ True, True, True, False, False, ... + +>>> x[m] +array([10, 9, 8]) +``` + +- Advanced indexing creates copies of arrays + + +# Vectorized operations + +- `for` loops in Python are slow +- Use "vectorized" operations when possible +- Example: difference + - for loop is ~80 times slower! + +
+```python +# brute force using a for loop +arr = numpy.arange(1000) +dif = numpy.zeros(999, int) +for i in range(1, len(arr)): + dif[i-1] = arr[i] - arr[i-1] + +# vectorized operation +arr = numpy.arange(1000) +dif = arr[1:] - arr[:-1] +``` +
+ +
+![](img/vectorised-difference.svg){.center width=90%} +
+ +# Broadcasting + +- If array shapes are different, the smaller array may be broadcasted + into a larger shape + +```python +>>> from numpy import array +>>> a = array([[1,2],[3,4],[5,6]], float) +>>> a +array([[ 1., 2.], + [ 3., 4.], + [ 5., 6.]]) + +>>> b = array([[7,11]], float) +>>> b +array([[ 7., 11.]]) + +>>> a * b +array([[ 7., 22.], + [ 21., 44.], + [ 35., 66.]]) +``` + + +# Broadcasting + +- Example: calculate distances from a given point + +```python +# array containing 3d coordinates for 100 points +points = numpy.random.random((100, 3)) +origin = numpy.array((1.0, 2.2, -2.2)) +dists = (points - origin)**2 +dists = numpy.sqrt(numpy.sum(dists, axis=1)) + +# find the most distant point +i = numpy.argmax(dists) +print(points[i]) +``` + + +# Temporary arrays + +- In complex expressions, NumPy stores intermediate values in + temporary arrays +- Memory consumption can be higher than expected + +```{.python emphasize=5:5-5:11,5:15-5:21} +a = numpy.random.random((1024, 1024, 50)) +b = numpy.random.random((1024, 1024, 50)) + +# two temporary arrays will be created +c = 2.0 * a - 4.5 * b + +# three temporary arrays will be created due to unnecessary parenthesis +c = (2.0 * a - 4.5 * b) + 1.1 * (numpy.sin(a) + numpy.cos(b)) +``` + + +# Temporary arrays + +- Broadcasting approaches can lead also to hidden temporary arrays +- Example: pairwise distance of **M** points in 3 dimensions + - Input data is M x 3 array + - Output is M x M array containing the distance between points i + and j + - There is a temporary 1000 x 1000 x 3 array + +```{.python emphasize=2:17-2:44} +X = numpy.random.random((1000, 3)) +D = numpy.sqrt(((X[:, numpy.newaxis, :] - X) ** 2).sum(axis=-1)) +``` + + + +# Summary + +- NumPy arrays consist internally of contiguous data block and strides + to describe dimensions and shape +- Vectorization improves performance +- Arrays can be broadcasted into same shapes +- Expression evaluation can lead into temporary arrays From 831fb725b64212dbb07efa58d69fa7f7457bf0e7 Mon Sep 17 00:00:00 2001 From: Jussi Enkovaara Date: Thu, 17 Mar 2022 11:34:47 +0200 Subject: [PATCH 3/9] Split content part 2 --- docs/01-numpy-basics.md | 286 ---------------------------------------- 1 file changed, 286 deletions(-) diff --git a/docs/01-numpy-basics.md b/docs/01-numpy-basics.md index 89c0c3b..56772aa 100644 --- a/docs/01-numpy-basics.md +++ b/docs/01-numpy-basics.md @@ -283,294 +283,8 @@ TypeError: only length-1 arrays can be converted to Python scalars ``` -# Numpy tools { .section } - - -# I/O with Numpy - -- Numpy provides functions for reading data from file and for writing data - into the files -- Simple text files - - `numpy.loadtxt` - - `numpy.savetxt` - - Data in regular column layout - - Can deal with comments and different column delimiters - - -# Random numbers - -- The module `numpy.random` provides several functions for constructing - random arrays - - `random`: uniform random numbers - - `normal`: normal distribution - - `choice`: random sample from given array - - ... - -```python ->>> import numpy.random as rnd ->>> rnd.random((2,2)) -array([[ 0.02909142, 0.90848 ], - [ 0.9471314 , 0.31424393]]) - ->>> rnd.choice(numpy.arange(4), 10) -array([0, 1, 1, 2, 1, 1, 2, 0, 2, 3]) -``` - - -# Polynomials - -- Polynomial is defined by an array of coefficients p - $p(x, N) = p[0] x^{N-1} + p[1] x^{N-2} + ... + p[N-1]$ -- For example: - - Least square fitting: `numpy.polyfit` - - Evaluating polynomials: `numpy.polyval` - - Roots of polynomial: `numpy.roots` - -```python ->>> x = numpy.linspace(-4, 4, 7) ->>> y = x**2 + rnd.random(x.shape) ->>> ->>> p = numpy.polyfit(x, y, 2) ->>> p -array([ 0.96869003, -0.01157275, 0.69352514]) -``` - - -# Linear algebra - -- Numpy can calculate matrix and vector products efficiently: `dot`, - `vdot`, ... -- Eigenproblems: `linalg.eig`, `linalg.eigvals`, ... -- Linear systems and matrix inversion: `linalg.solve`, `linalg.inv` - -```python ->>> A = numpy.array(((2, 1), (1, 3))) ->>> B = numpy.array(((-2, 4.2), (4.2, 6))) ->>> C = numpy.dot(A, B) ->>> ->>> b = numpy.array((1, 2)) ->>> numpy.linalg.solve(C, b) # solve C x = b -array([ 0.04453441, 0.06882591]) -``` - - -# Linear algebra - -- Normally, NumPy utilises high performance libraries in linear algebra - operations -- Example: matrix multiplication C = A * B matrix dimension 1000 - - pure python: 522.30 s - - naive C: 1.50 s - - numpy.dot: 0.04 s - - library call from C: 0.04 s - - -# Numpy advanced topics { .section } - - -# Anatomy of NumPy array - -- **ndarray** type is made of - - one dimensional contiguous block of memory (raw data) - - indexing scheme: how to locate an element - - data type descriptor: how to interpret an element - -![](img/ndarray-in-memory.svg){.center width=50%} - - -# NumPy indexing - -- There are many possible ways of arranging items of N-dimensional - array in a 1-dimensional block -- NumPy uses **striding** where N-dimensional index ($n_0, n_1, ..., n_{N-1}$) - corresponds to offset from the beginning of 1-dimensional block - -$$ -offset = \sum_{k=0}^{N-1} s_k n_k, s_k \text{ is stride in dimension k} -$$ - - -![](img/ndarray-in-memory-offset.svg){.center width=50%} - -# ndarray attributes - -`a = numpy.array(...)` - : `a.flags` - : various information about memory layout - - `a.strides` - : bytes to step in each dimension when traversing - - `a.itemsize` - : size of one array element in bytes - - `a.data` - : Python buffer object pointing to start of arrays data - - `a.__array_interface__` - : Python internal interface - - -# Advanced indexing - -- Numpy arrays can be indexed also with other arrays (integer or - boolean) - -```python ->>> x = numpy.arange(10,1,-1) ->>> x -array([10, 9, 8, 7, 6, 5, 4, 3, 2]) - ->>> x[numpy.array([3, 3, 1, 8])] -array([7, 7, 9, 2]) -``` - -- Boolean "mask" arrays - -```python ->>> m = x > 7 ->>> m -array([ True, True, True, False, False, ... - ->>> x[m] -array([10, 9, 8]) -``` - -- Advanced indexing creates copies of arrays - - -# Vectorized operations - -- `for` loops in Python are slow -- Use "vectorized" operations when possible -- Example: difference - - for loop is ~80 times slower! - -
-```python -# brute force using a for loop -arr = numpy.arange(1000) -dif = numpy.zeros(999, int) -for i in range(1, len(arr)): - dif[i-1] = arr[i] - arr[i-1] - -# vectorized operation -arr = numpy.arange(1000) -dif = arr[1:] - arr[:-1] -``` -
- -
-![](img/vectorised-difference.svg){.center width=90%} -
- -# Broadcasting - -- If array shapes are different, the smaller array may be broadcasted - into a larger shape - -```python ->>> from numpy import array ->>> a = array([[1,2],[3,4],[5,6]], float) ->>> a -array([[ 1., 2.], - [ 3., 4.], - [ 5., 6.]]) - ->>> b = array([[7,11]], float) ->>> b -array([[ 7., 11.]]) - ->>> a * b -array([[ 7., 22.], - [ 21., 44.], - [ 35., 66.]]) -``` - - -# Broadcasting - -- Example: calculate distances from a given point - -```python -# array containing 3d coordinates for 100 points -points = numpy.random.random((100, 3)) -origin = numpy.array((1.0, 2.2, -2.2)) -dists = (points - origin)**2 -dists = numpy.sqrt(numpy.sum(dists, axis=1)) - -# find the most distant point -i = numpy.argmax(dists) -print(points[i]) -``` - - -# Temporary arrays - -- In complex expressions, NumPy stores intermediate values in - temporary arrays -- Memory consumption can be higher than expected - -```{.python emphasize=5:5-5:11,5:15-5:21} -a = numpy.random.random((1024, 1024, 50)) -b = numpy.random.random((1024, 1024, 50)) - -# two temporary arrays will be created -c = 2.0 * a - 4.5 * b - -# three temporary arrays will be created due to unnecessary parenthesis -c = (2.0 * a - 4.5 * b) + 1.1 * (numpy.sin(a) + numpy.cos(b)) -``` - - -# Temporary arrays - -- Broadcasting approaches can lead also to hidden temporary arrays -- Example: pairwise distance of **M** points in 3 dimensions - - Input data is M x 3 array - - Output is M x M array containing the distance between points i - and j - - There is a temporary 1000 x 1000 x 3 array - -```{.python emphasize=2:17-2:44} -X = numpy.random.random((1000, 3)) -D = numpy.sqrt(((X[:, numpy.newaxis, :] - X) ** 2).sum(axis=-1)) -``` - - -# Numexpr - -- Evaluation of complex expressions with one operation at a time can lead - also into suboptimal performance - - Effectively, one carries out multiple *for* loops in the NumPy - C-code - -- Numexpr package provides fast evaluation of array expressions - -```python -import numexpr as ne -x = numpy.random.random((1000000, 1)) -y = numpy.random.random((1000000, 1)) -poly = ne.evaluate("((.25*x + .75)*x - 1.5)*x - 2") -``` - - -# Numexpr - -- By default, numexpr tries to use multiple threads -- Number of threads can be queried and set with - `ne.set_num_threads(nthreads)` -- Supported operators and functions: - +,-,\*,/,\*\*, sin, cos, tan, exp, log, sqrt -- Speedups in comparison to NumPy are typically between 0.95 and 4 -- Works best on arrays that do not fit in CPU cache - - # Summary - Numpy provides a static array data structure - Multidimensional arrays - Fast mathematical operations for arrays -- Tools for linear algebra and random numbers -- Arrays can be broadcasted into same shapes -- Expression evaluation can lead into temporary arrays From 6d367a1f09c86bc36d08ace727d90e078fa4a87e Mon Sep 17 00:00:00 2001 From: Jussi Enkovaara Date: Thu, 17 Mar 2022 11:37:15 +0200 Subject: [PATCH 4/9] Split content part 3 --- docs/{02-performance-analysis.md => 04-performance-analysis.md} | 0 docs/{03-cython.md => 05-cython.md} | 0 docs/{04-multiprocessing.md => 06-multiprocessing.md} | 0 docs/{05-mpi4py.md => 07-mpi4py.md} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename docs/{02-performance-analysis.md => 04-performance-analysis.md} (100%) rename docs/{03-cython.md => 05-cython.md} (100%) rename docs/{04-multiprocessing.md => 06-multiprocessing.md} (100%) rename docs/{05-mpi4py.md => 07-mpi4py.md} (100%) diff --git a/docs/02-performance-analysis.md b/docs/04-performance-analysis.md similarity index 100% rename from docs/02-performance-analysis.md rename to docs/04-performance-analysis.md diff --git a/docs/03-cython.md b/docs/05-cython.md similarity index 100% rename from docs/03-cython.md rename to docs/05-cython.md diff --git a/docs/04-multiprocessing.md b/docs/06-multiprocessing.md similarity index 100% rename from docs/04-multiprocessing.md rename to docs/06-multiprocessing.md diff --git a/docs/05-mpi4py.md b/docs/07-mpi4py.md similarity index 100% rename from docs/05-mpi4py.md rename to docs/07-mpi4py.md From 42bc0a9689564be860a73a8c140b4c861c8766a9 Mon Sep 17 00:00:00 2001 From: Jussi Enkovaara Date: Thu, 17 Mar 2022 11:38:41 +0200 Subject: [PATCH 5/9] Add .gitignore --- .gitignore | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bcd1520 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +*~ +*.html +*.pptx +*.pdf +*.swp +*.o +*.mod From 62a0bb973f86dc85f84adce5733e28425bd43fed Mon Sep 17 00:00:00 2001 From: Jussi Enkovaara Date: Mon, 21 Mar 2022 13:03:56 +0200 Subject: [PATCH 6/9] Equation images --- numpy/finite-difference/README.md | 2 +- numpy/img/finite-difference.png | Bin 0 -> 1337 bytes numpy/img/rieman-sum1.png | Bin 0 -> 1591 bytes numpy/img/rieman-sum2.png | Bin 0 -> 1409 bytes numpy/integration/README.md | 4 ++-- 5 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 numpy/img/finite-difference.png create mode 100644 numpy/img/rieman-sum1.png create mode 100644 numpy/img/rieman-sum2.png diff --git a/numpy/finite-difference/README.md b/numpy/finite-difference/README.md index 792f139..777ab47 100644 --- a/numpy/finite-difference/README.md +++ b/numpy/finite-difference/README.md @@ -9,7 +9,7 @@ as: f'(x_i) = \frac{f(x_i + \Delta x)- f(x_i - \Delta x)}{2 \Delta x} ---> -![img](https://quicklatex.com/cache3/0a/ql_d10c99a114e66c7ed0535e0aeb041d0a_l3.png) +![img](../img/finite-difference.png) Construct 1D Numpy array containing the values of xi in the interval [0,π/2] with spacing Δx=0.1. Evaluate numerically the derivative of **sin** in this diff --git a/numpy/img/finite-difference.png b/numpy/img/finite-difference.png new file mode 100644 index 0000000000000000000000000000000000000000..62e3a316a14ae31a5b670b64f25a8c95eb943eb3 GIT binary patch literal 1337 zcmZ`(doE)Be1TT!VgM4c0IV}DfzLE&T|4@nKxpL zs26?x8B)qb4x~J8wR3UG(W%xx4674+KgaMgiEVWX&Y$9Ko0=;Q2K^?VCy-)>^~AKIhB7tCH?5Qr^j=LE z!Oc^~B7K05yjvq;%a@_*KckMtHDmNtVD!qS2cZLvuhjEf0vskzGo0)#c)AfShiuOE zIOLGp6Pj_tJ6+X>cxH+c7xAFYL8U?;R(>>B>T4aAbONg8i@@SUW9y4qH_5bs=t zSSv>&cW*j+7+kWls~`*{a97-uk3TTFkZ)LSr?u^ZuNwOpn{10V{74Z=1SxK&lD7gWJy37-di9;VJ`$ME!V!7_J_Pe`msz+cEs=VNcV0L;zW%dZlck3_W&n z$i%u9#dJT}9a8s$Mc^p)b##Th`0!#x5lN$9*?TOx%BK}yrg3ABT4jlmDDHR7%-1sA zToK|uVnyAIP4@DR!uc;5#hq^UPu4`?$Lm&w;Gb6jlc=%^R|S)g!} zzlOi+I{IHYk2otLJ)_CBipD$m}4FtOQK-sXdBxzS2nfXZ0wWm0wyTj~=|=RJR$k$Pk%O%JV7O6`NLFVwx1~^qiBLw$gT6u%?jbLiOhI51OSJ{;Y_gRCO9)MGXfEB o1(gw&K*VA*uPajj6NrjoMT92*e_(yMX#)xX8pVzL@Owt)zrm?lr2qf` literal 0 HcmV?d00001 diff --git a/numpy/img/rieman-sum1.png b/numpy/img/rieman-sum1.png new file mode 100644 index 0000000000000000000000000000000000000000..ab919d125d5d75ad7cde33b109d2821aa6e268b4 GIT binary patch literal 1591 zcmZ`(Ydq5n82-mZt6ZC0hG7hi&6L_`+1PAC_>HA<8^exr-IPnYllv`lKdU&ZlS??= zhuEpf{d7@LQevUfj9i+|`glH^56}Dj-skdrzrERRu8upwT3`SGc2X%09#R%dp`ieh z&JeCfo|Hf#1Q!AT+$`MwBS22N!vZNDE&vd33;@aL0I)8Vl7#@kK?A^?KLFq=0AP1y z%{_NpsUgES?C1de%qkq{l5X1~Dc&&vpveD)EoFNYwWXpwo9aT6pOJ;A*}ySLm8sH$ zKd24_TIk!)Rj)V`*1Iwft=0ptufg2pJ3I(i75y7iyLBR6owzn!oZu3U>!jS67G>6o z)tRu3)GPvB)W^QC2jM9)UsCn%XalBGw_Lnc&y_CaKY#F7<;s^Ct-7^uw+34#!@EXR zhFf-unk0Go=ia5YnRz}8vzH|8=Tt+RkjjflM^8}}wCtm+;`X?-n{J2jBCBd}>qK$% zk#29@@5R`H8=B*po5s3LdzD0j7P!-reL=U*L!xi5MEEWQ@|Mx5BWX}A``$^UN;F|5 zEr~O}x^eIOEpUzK-Y&B`a#yHly`&Y+=R0T^1V|inAS3A-7y`FD-c;6u;k!UxyByR!y%6EUN&T?AjYbyRU2#F;r=G*&?nZtP?VoPD zE{vO%9Yib1aI!i@v#-c9c_wfv89lHrkAD9d<-77@GHZc`58r)Qs;S5YA*y~ zbMAEzlf4+aR&&XH@RIUbo=mv;v=>>Hia+cd6(pnx${{i7KEnv8=0`g8y|sUHy+cjicEbW*BGdQvp$28iX5s9uTZ1G(P&u>|M%h!>dauc z;fof~lBuR3IBXI!lZDO+?e2ous?3+Yv|a;Wa#6KB_mjYyi(wkL}= zh|X{MvWPX@P&=43w0q4OqaO1(U_G0Vef1#vGzTl}FCI%ntWB48Y|NK|P2&8zZu4tW z3g6#dr&kf*eqT4h_YGL3JXvFJ>_?UrueM@Ai2)nMI2BhbG z%07f;-XcuHWAfwF!n|i}?%}*Gsl^}p&oa2RUEX>p#ZCjw&E~?SSC$i`2ZGAh&9O^Y z@f2IM?Rn^`-Bf>aH0>BEkdxY0e_L_fDW)jP*Dsm8v|s-SkT`{6evC3>D{Z>_8_kf% zg2guR#B3G8{5aj-OHNnJx&7#aS3*LBx`}a?Ap!Q#6;E=2D}0KcP^&oZGd}Y5Xr5`W zyi7ssu408^kF^^hEZ5VarmNaejD;*TTX5s>)nNk8UXbi?2ZDo$Jq*-Ed`>;4G>pf^J j4vqdnzzY6TI294Z3Xc2#LOwKwEiC|4lB+{A(LeQHvRcMd literal 0 HcmV?d00001 diff --git a/numpy/img/rieman-sum2.png b/numpy/img/rieman-sum2.png new file mode 100644 index 0000000000000000000000000000000000000000..eb070788b8755f791e226073e7141725c5c19c15 GIT binary patch literal 1409 zcmZ`(S6CBf6#db#L3TlqO&CHn3=Y(<6Sg#ZAeSd5i306a&zSV{oG z?WXjSAnt%rEbJ`+sLv8U!1Hps3K8RM4?wgg0P)EH>~p2~1pva~04(_cfVvBSY;a+# z6Pmj?LcrNtfy30S{?}Y47>w}<1K?QKkK(zldrW~V^3$;P*8FovWu$?KDYCbld(Z}J zW#Q^OJ$rvOd>J8fU3rTH5bAIR?N?H+@$f;N-A)7RHi$V$Hc$VosozRDVjufma%LV|6<9kkb!Jg^z34UcxR|a) zqhID+iI!mDr2ME~V}#en-GpSh>7GQpcBGe==kJI`-7x)I3JwQ)XB{+dr;sGQ3s|^Z z2qWF?qa%gb;e33eR}<~`*31}8wa%Q}gLa=3QnjODO$EN^2);Tj`OKzu$2*-X1R<`?ac?~#hb#Mrlo?}2WqOg zUyYl)_R6W4d=T>tvi~KKfz%hx_e^imVn#|Iu}n!jBayF|5EOUCV$L@tEQs<8oAqXG zs$O#EE;Hv^i*1ovO8i*8-_;x_q-wL0NtY|FMjQ6A-Cu+~b%81)PD|L8_&ACPVaKa| zHsYit#bPk%YabxrHAemTwA6KkRF~a~m2?J_rjY&usT=W7sHS4UM@HTWMoW0y^!9I# zcPjSElEcH#M62EoGXDMBqpuoU;B(&4b`dFwrG3tEn{q+;=OBQ6ikdXEvE6dxn$eTMr?~WC6XCKpOCdE zG5#_NQd4OrvqU?2VBl)&OxqkqIz{ecV3+u^m>}HRS$bJF{?}fjZneAHJz7zN4Pmn{ z045sZgL|Vm^!WDup;X9N&*9)s8OgtrKE9GN&x7vYt>WwV&Fkl*zBkW_H~lJ$DPQL_ zW~k2H;x!bBi8YBPw7(=g9G*bmF}zZiUDu)A#e9$CuZ+M;;d>91)^G6$IW9b=zJdjk%SQCKyIAOYZg7PmPqOr#2U@PAxcyIE56k z2Vwbj+LbSinrhMO`4Z(Z^cib}KmC)3B*$sMW53xUbW29S=FZXveSOQ6(nZ!uI_USK z;McIz>=3q0^=bJV78_PcE8^?d$!1wmR|MB<9V%YT;_VBo$Tg0+2M8bl=ODy`k zMzhTqP8IV~nZ6*iLLsE6GQsnW%*^ikyz~ysmeGJWo-IhIJ=`8SGz*A4yQCgEvh z6fu;{9l!u?U;u*~!VL6X4d5s^9Hnod3;&r5&_xZ3{|N*Hk*HVb{~xe#7kbDI0Ic-| Ks~St6#D4+ZUvPB* literal 0 HcmV?d00001 diff --git a/numpy/integration/README.md b/numpy/integration/README.md index de2993e..857f76e 100644 --- a/numpy/integration/README.md +++ b/numpy/integration/README.md @@ -7,7 +7,7 @@ sum S = \int_a^b f(x) dx = \sum_{i=1}^n f(x'_i) \Delta x ---> -![img](https://quicklatex.com/cache3/e2/ql_30419670e67bc2b3d039e8a9d8653de2_l3.png) +![img](../img/rieman-sum1.png) with @@ -15,7 +15,7 @@ with x'_i = (x_i + x_{i-1}) / 2; x_0 = a, x_n = b ---> -![img](https://quicklatex.com/cache3/09/ql_f124fd5c831e873c6abd41160fae2d09_l3.png) +![img](../img/rieman-sum2.png) Calculate the integral in the interval [0,π/2] and investigate how much the Riemann sum of **sin** differs from 1.0. Avoid `for` loops. Investigate also From 006c9a74bd6f05a8c17b09052f735b0bd1ef9914 Mon Sep 17 00:00:00 2001 From: Jussi Enkovaara Date: Mon, 21 Mar 2022 13:16:55 +0200 Subject: [PATCH 7/9] More equations as figures --- numpy/broadcast-rotation/README.md | 2 +- numpy/heat-equation/README.md | 8 ++++---- numpy/img/heat-equation.png | Bin 0 -> 942 bytes numpy/img/heat-stability.png | Bin 0 -> 1221 bytes numpy/img/heat-time-propagation.png | Bin 0 -> 1400 bytes numpy/img/nabla.png | Bin 0 -> 2772 bytes numpy/img/rotation-matrix.png | Bin 0 -> 1676 bytes 7 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 numpy/img/heat-equation.png create mode 100644 numpy/img/heat-stability.png create mode 100644 numpy/img/heat-time-propagation.png create mode 100644 numpy/img/nabla.png create mode 100644 numpy/img/rotation-matrix.png diff --git a/numpy/broadcast-rotation/README.md b/numpy/broadcast-rotation/README.md index 03aac56..c043e6e 100644 --- a/numpy/broadcast-rotation/README.md +++ b/numpy/broadcast-rotation/README.md @@ -11,7 +11,7 @@ R = \end{pmatrix} ---> -![img](http://quicklatex.com/cache3/9c/ql_ee4015bef241c06a5119104118f9a19c_l3.png) +![img](../img/rotation-matrix.png) where θ is the angle of rotation (in radians). Start from the x-y coordinates in the file points_circle.dat and rotate them by 90°. Utilize broadcasting for diff --git a/numpy/heat-equation/README.md b/numpy/heat-equation/README.md index 5f14513..96b30be 100644 --- a/numpy/heat-equation/README.md +++ b/numpy/heat-equation/README.md @@ -5,7 +5,7 @@ Heat (or diffusion) equation is -![img](https://quicklatex.com/cache3/d2/ql_b3f6b8bdc3a8862c73c5a97862afb9d2_l3.png) +![img](../img/heat-equation.png) where **u(x, y, t)** is the temperature field that varies in space and time, and α is thermal diffusivity constant. The two dimensional Laplacian can be @@ -17,7 +17,7 @@ discretized with finite differences as &+ \frac{u(i,j-1)-2u(i,j)+u(i,j+1)}{(\Delta y)^2} \end{align*} --> -![img](https://quicklatex.com/cache3/2d/ql_59f49ed64dbbe76704e0679b8ad7c22d_l3.png) +![img](../img/nabla.png) Given an initial condition (u(t=0) = u0) one can follow the time dependence of the temperature field with explicit time evolution method: @@ -25,14 +25,14 @@ the temperature field with explicit time evolution method: -![img](https://quicklatex.com/cache3/9e/ql_9eb7ce5f3d5eccd6cfc1ff5638bf199e_l3.png) +![img](../img/heat-time-propagation.png) Note: Algorithm is stable only when -![img](https://quicklatex.com/cache3/d1/ql_0e7107049c9183d11dbb1e81174280d1_l3.png) +![img](../img/heat-stability.png) Implement two dimensional heat equation with NumPy using the initial temperature field in the file [bottle.dat](bottle.dat) (the file consists of a diff --git a/numpy/img/heat-equation.png b/numpy/img/heat-equation.png new file mode 100644 index 0000000000000000000000000000000000000000..2cae86bdf0705f6b2ade7d0f2dd21759e8795b42 GIT binary patch literal 942 zcmeAS@N?(olHy`uVBq!ia0vp^p+GFo!2%>NNn{1`6_P!I zd>I(3)EF2VS{N990fib~Fff!FFfhDIU|_JC0n}eGXIG#NP=YDR+ueoXe|!I#{XiaP zfk$L90|Va?5N4dJ%_j{MWH0gbb!C6XEGojo`RGNl8&FfRr;B5V$MLh%ZWrD*5O6(T z6~nNI&#C;t5!nN>3X{2*N*Sh3NVHnu&2g9UuA@`AL#aTZY>wT5)9pi>gNyodS!xS2$_q~i0y0)v*IEYuQ;l707F8h;Ol95lQwKW_L zND_6L6F*_+PWhuJ(x!zfE)2`Oy6Daeu_YJz68(1}b70nCi_fhw^Q&f0ijntQ z|2<@HQ1`dEkGD&t;(9`jQ#Z_&{mCv_S7thG)7@n%fg(0DoxIjQ5M!IY@Z*%aW0Sun zw+Ao#ul`B#!N(RmK8YfkzNP{}9sdK9t{2%h)C z{k+>nxtRg(58l>DeC~RGOy%#TsDlC`vrbq%UA_zVb3<@6id1 z4)dMb91+jCRq}{)ue^7sKz|rV@vfXw*}J=2ZT=WMo*jQ8^HO7=h}J6Qy>8)l(%V-q z4i;YYwN(0SkWlS}kWG5_XH$5V9GEjh@9S}u&jy|I`q@oyx5WhM{Jd!}M_}<=S$~Cf zyB%-ZcV^E$9)BdeH`l$d%ixNn?fR?5I|Ytz(SPFMxpZ~7a{HqlmrXqmAHTe2pMkz= z&WalwAE|2_)fL*`^S7xy)06(~L(QTj_B%nZYuT?}6xHFp|FbK-_)AW=nP+>-uS3^< z-CB_l_~Csx&pc6Z(`u^z1AM2(2 zyzX*&B=FBT=dHRtWq;1vs>0`m)!hTQy=%(P0}8r;MJEr1#rJYD@<);T3K0RT||gHiwh literal 0 HcmV?d00001 diff --git a/numpy/img/heat-stability.png b/numpy/img/heat-stability.png new file mode 100644 index 0000000000000000000000000000000000000000..9a418e2515ad5bcc70ad8ec83852dc5d2165aca2 GIT binary patch literal 1221 zcmeAS@N?(olHy`uVBq!ia0vp^-9RkQ!2%>}pMO&XQY`6?zK#qG8~eHcB(ehe3dtTp zz6=aiY77hwEes65fICD#?XB&vL z+NTCJq%|=vi{?n5oIC&BjI(aCWebe|>0J8D?tkjoG1oxT z`^UaN)Hxq*^8Hh-W8a%Y)$`t5=6u~WZ_cD$|D_$K)|O1DTybrw@H6Hs(_+(B8eHBg z=j&oFdN%05C9dR4F^e=VY?)!VQ*B$b!?Dgjy^Y&`O#Oc_E%VOq9hbZha@u~Aes#Lz zQ{bV9kW3q8ckL^SwrQMpd^y$TdiMQ$KW1okUy@lqrT*aw{|UwnZQ(EO=kl^@Juh|m zH*dyyPXGCpD_mpvs_x5g)B47{c&Uu^+eN<8EWJyWo<9jn=QUO1w`8xMrkVdrPuG&S zD6-|+zUYNrNo6xt->+u8d8*&EZ4#69wi~5W8kQZqR5ew#{CZ~EO7>r_dlI&BUCt3Y z8#O1^#^=3(PgD3}nW%^>E45A@ja!qlxA4!60|6H=2IejoY@4QKmdGROGc4T|K{aGq&*Q}%Ujg@94*C7@()HiniI%Zm0bZGq0F*EBj{p*PhUsGIwu1cx3VE zPmI+uHNB^pT=^w<(RW>H)Ui`WaTyz#Zmkuv4RMv$?w0WKn$_}cuX8NtYqkI9 zS{z(GH(Ky}_@8AI)(V}Xc)2HfOU2~-%h$D(O#Ytms(o#L21{d8R?fZISGM)9yxLwC z{HJyAw&2*C*L?3aYYN?XsXnc&`jKALhKN($Th2b~c3g8nGvtcl<+__^dOqp-yic3f zak0&1vDCIdXOoPsuh3q-%X5mRXXDQPz*U*gi)O{G`(#|Vf7hm^vs-2ciO#5&Si0ba z`J}%`*#4jWR0|bvF=2i7ENY#R&B^XdHSEhfKD2I^%vrvRDd(k{3p!sW$_k9>a2SE{O$(K6$bh=gi?-=vxP?ejhtEZhHT ztxjy#s$WXLjH*=P8c~v*pPQSSSHcjKnwOGVl$xTDRH+bHnwgyKlNgd3p$C*!@Vu}M zs9F`IIwi3r)hf9t6-Y4{85kMq8W`&u8HN}cSQ(mG8JK7rSXvnv#FuN>p=ij>PsvQH W#H~S3YeExH1B0ilpUXO@geCwV;u!M) literal 0 HcmV?d00001 diff --git a/numpy/img/heat-time-propagation.png b/numpy/img/heat-time-propagation.png new file mode 100644 index 0000000000000000000000000000000000000000..ec2e024c20a48c671e9e68a54291584be524d488 GIT binary patch literal 1400 zcmZ`(Z9LNn9RKGridKl5hb=DtIBq7%s?F149_DGyt_?EQl^1f)rwIs7xej3S7HQmr@5Ldk88W8a{BljKd7n18M40 z0c1LNMO9*^wGX1P`WQF4i|WgJ8`WMk^>n;*xZE1L8mAZ1&!6*Z26Ov4PEU06$V4aT z%Sddo7EfHcY)O)3D2zbE1{=DLhW=I%ce5+Fu*YIF`(7lujljj@>)u=Pv@edUz24>Q z6VJ&~-Kwe3D~g`gTfetD!Ylmd_l9CERx-L7)fV3|!(=`Zp21&Fg7~WtM?&cpZLP4Z zM&Y@TglG99ixpqj+&ORZ5p6sN$tqi3L zV|tnfvKXV|#gztF3M?QZ>^ySzeoD#3#<3u7j(LA*DME%Yt(s~572?uQ#r(7?>ziq^ zNU>COnb5XVchdauv+mk>Zbh|T1ldsl#ztlHc_HbGM(Co-J1?ZtX=9gbwRW$fWW(tR zpZYGOj%L)r;=qxErv&DCCzjlIvj@O%&mk+H-KLpcqdg6@!IRHIUY%Jz`i`j{70&pj zyK0J17}?RlZ^`)7mvAYh_uue+Ppi*sW9y!$#@O0J;+Ccz&jVsf!oPF*jW#C`1Q97C z|7zwe|M)$9C2NqLJ^!xu(O%HQ=w;vpwp2cE zCZ%G?wDnPYF;m?GJN&4wu5Kgwl8b=C`{URKb3IIv-6FZ&CnGUPjQOSu$=n6UZ&ygd z>Sia*+Mu8eSs>d0F}kp7$?mACmWsL`hCA|BI3pI^O||W{Gl88fI8pgq%-Ps5HZ?gh zk(R^;f@w)HG!`ue9?gLVrN&Vc{3rxkn7vYl<0fw?-TS||V<>DIipruX2Y^H%k#-12 yJEQ{vi9k6VKsh?vB3w`i1mw!Cr2hmGlVjq(=lp+wBIisi0{{+-_iT43=lugo!*O{4 literal 0 HcmV?d00001 diff --git a/numpy/img/nabla.png b/numpy/img/nabla.png new file mode 100644 index 0000000000000000000000000000000000000000..6a0cc87872d2685af171b444e44d4779e96f1256 GIT binary patch literal 2772 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 T(BjZ4=>Q Date: Thu, 7 Apr 2022 14:36:16 +0300 Subject: [PATCH 8/9] Ensure integer division --- numpy/game-of-life/solution/game-of-life.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/numpy/game-of-life/solution/game-of-life.py b/numpy/game-of-life/solution/game-of-life.py index b20ebd6..67b8774 100644 --- a/numpy/game-of-life/solution/game-of-life.py +++ b/numpy/game-of-life/solution/game-of-life.py @@ -16,8 +16,8 @@ def initialize(size, shape='cross'): board = np.random.rand(size, size).round(0).astype(int) elif shape == 'cross': board = np.zeros((size, size), int) - board[size/2,:] = 1 - board[:,size/2] = 1 + board[size//2,:] = 1 + board[:,size//2] = 1 else: raise NotImplementedError('Unknown initial shape') From a7625fd02e0e7b71a24c5893d21cb41a4320ea73 Mon Sep 17 00:00:00 2001 From: Jussi Enkovaara Date: Tue, 25 Feb 2025 10:00:17 +0200 Subject: [PATCH 9/9] Update licensing information --- COPYING | 8 + LICENSE | 30 -- LICENSES/CC-BY-NC-SA-4.0.txt | 170 +++++++ LICENSES/MIT.txt | 18 + README.md | 6 + cython/c-functions/README.md | 6 + cython/c-functions/fib.py | 4 + cython/c-functions/solution/fib.pyx | 4 + cython/c-functions/solution/fib_py.py | 4 + cython/c-functions/solution/setup.py | 4 + cython/c-functions/solution/test_fib.py | 4 + cython/heat-equation/README.md | 6 + cython/heat-equation/heat.py | 4 + cython/heat-equation/heat_main.py | 4 + cython/heat-equation/profile.md | 6 + cython/heat-equation/solution/evolve_new.pyx | 50 ++ cython/heat-equation/solution/evolve_py.py | 32 ++ cython/heat-equation/solution/heat.pyx | 4 + cython/heat-equation/solution/heat_main.py | 4 + cython/heat-equation/solution/setup.py | 4 + cython/simple-extension/README.md | 6 + .../simple-extension/solution/cyt_module.pyx | 4 + cython/simple-extension/solution/setup.py | 4 + cython/static-typing/README.md | 6 + cython/static-typing/cyt_module.pyx | 4 + cython/static-typing/setup.py | 4 + cython/static-typing/solution/cyt_module.pyx | 4 + cython/static-typing/solution/setup.py | 4 + demos/broadcasting.py | 4 + demos/cython/mandel.py | 4 + demos/cython/mandel_cyt.pyx | 4 + demos/cython/mandel_cyt_1.pyx | 4 + demos/cython/mandel_cyt_2.pyx | 4 + demos/cython/mandel_cyt_3.pyx | 4 + demos/cython/mandel_cyt_4.pyx | 4 + demos/cython/mandel_cyt_5.pyx | 4 + demos/cython/mandel_main.py | 4 + demos/cython/setup.py | 4 + demos/interface/c-extension/example.c | 6 + demos/interface/c-extension/setup.py | 4 + demos/interface/cffi/example.py | 4 + demos/interface/cffi/myclib.c | 6 + demos/interface/fortran/add.f90 | 4 + demos/interface/fortran/example.py | 4 + demos/lock.py | 4 + demos/manager.py | 4 + demos/memory_usage.py | 4 + demos/mpi-alltoall.py | 4 + demos/mpi-bcast.py | 4 + demos/mpi-cartesian.py | 4 + demos/mpi-collective.py | 4 + demos/mpi-custom-operator.py | 4 + demos/mpi-example.py | 4 + demos/mpi-gather.py | 4 + demos/mpi-halo-exchange.py | 4 + demos/mpi-hello.py | 4 + demos/mpi-isend.py | 4 + demos/mpi-manual-buffer.py | 4 + demos/mpi-msg-chain.py | 4 + demos/mpi-p2p.py | 4 + demos/mpi-reduce.py | 4 + demos/mpi-scatter.py | 4 + demos/mpi-send-array.py | 4 + demos/mpi-send.py | 4 + demos/mpi-sendrecv.py | 4 + demos/mpi-split.py | 4 + demos/mpi-status.py | 4 + demos/performance/gpaw/c6h6.py | 4 + demos/performance/matmul/matmul.c | 6 + demos/performance/matmul/matmul.py | 4 + demos/performance/matmul/test_matmul.py | 4 + demos/performance/timing-with.py | 4 + demos/performance/timing.py | 4 + demos/pool-map.py | 4 + demos/pool.py | 4 + demos/shared-mem.py | 4 + demos/spawn.py | 4 + demos/task-queue.py | 4 + docs/00-overview.md | 6 + docs/01-numpy-basics.md | 6 + docs/02-numpy-tools.md | 6 + docs/03-numpy-advanced.md | 6 + docs/04-performance-analysis.md | 6 + docs/05-cython.md | 6 + docs/06-multiprocessing.md | 6 + docs/07-mpi4py.md | 6 + docs/LICENSE | 438 ------------------ docs/img/appliance-settings.png.license | 3 + docs/img/case_study_left-01.svg.license | 3 + docs/img/case_study_left-02.svg.license | 3 + docs/img/case_study_left-03.svg.license | 3 + docs/img/case_study_left-04.svg.license | 3 + docs/img/case_study_left-05.svg.license | 3 + docs/img/case_study_left-06.svg.license | 3 + docs/img/case_study_left-07.svg.license | 3 + docs/img/case_study_right-01.svg.license | 3 + docs/img/case_study_right-02.svg.license | 3 + docs/img/case_study_right-03.svg.license | 3 + docs/img/case_study_right-04.svg.license | 3 + docs/img/case_study_right-05.svg.license | 3 + docs/img/case_study_right-06.svg.license | 3 + docs/img/comm_patt.svg.license | 3 + docs/img/communication-patterns.png.license | 3 + docs/img/communication-patterns.svg.license | 3 + docs/img/communication-schematic.png.license | 3 + docs/img/communication-schematic.svg.license | 3 + docs/img/communication-schematic2.png.license | 3 + docs/img/communication-schematic2.svg.license | 3 + docs/img/communicator.svg.license | 3 + docs/img/compp.png | Bin 0 -> 22791 bytes docs/img/compp.png.license | 3 + docs/img/compp.svg.license | 3 + docs/img/data-model.svg.license | 3 + docs/img/data-parallel.png | Bin 0 -> 9649 bytes docs/img/data-parallel.png.license | 3 + docs/img/data-parallel.svg.license | 3 + docs/img/fractal.svg.license | 3 + docs/img/heat.png.license | 3 + docs/img/import-appliance-2.png.license | 3 + docs/img/import-appliance.png.license | 3 + docs/img/list-vs-array.svg.license | 3 + docs/img/login.png.license | 3 + docs/img/mpi-all2all.png.license | 3 + docs/img/mpi-all2all.svg.license | 3 + docs/img/mpi-bcast.png.license | 3 + docs/img/mpi-bcast.svg.license | 3 + docs/img/mpi-data-model.png.license | 3 + docs/img/mpi-data-model.svg.license | 3 + docs/img/mpi-gather.png.license | 3 + docs/img/mpi-gather.svg.license | 3 + docs/img/mpi-reduce.png.license | 3 + docs/img/mpi-reduce.svg.license | 3 + docs/img/mpi-scatter.png.license | 3 + docs/img/mpi-scatter.svg.license | 3 + docs/img/ndarray-in-memory-offset.png.license | 3 + docs/img/ndarray-in-memory-offset.svg.license | 3 + docs/img/ndarray-in-memory.png.license | 3 + docs/img/ndarray-in-memory.svg.license | 3 + docs/img/non-blocking-pattern.png.license | 3 + docs/img/non-blocking-pattern.svg.license | 3 + docs/img/parallel-sum-0.png.license | 3 + docs/img/parallel-sum-0.svg.license | 3 + docs/img/parallel-sum-1.1.png.license | 3 + docs/img/parallel-sum-1.1.svg.license | 3 + docs/img/parallel-sum-1.2.png.license | 3 + docs/img/parallel-sum-1.2.svg.license | 3 + docs/img/parallel-sum-2.png.license | 3 + docs/img/parallel-sum-2.svg.license | 3 + docs/img/parallel-sum-3.1.png.license | 3 + docs/img/parallel-sum-3.1.svg.license | 3 + docs/img/parallel-sum-3.2.png.license | 3 + docs/img/parallel-sum-3.2.svg.license | 3 + docs/img/parallel-sum-4.png.license | 3 + docs/img/parallel-sum-4.svg.license | 3 + docs/img/parallel-sum.svg.license | 3 + ...ocesses-threads-highlight-proc.svg.license | 3 + docs/img/processes-threads.png.license | 3 + docs/img/processes-threads.svg.license | 3 + docs/img/scaling.png | Bin 0 -> 8461 bytes docs/img/scaling.png.license | 3 + docs/img/start-vm.png.license | 3 + docs/img/task-farm.png | Bin 0 -> 54446 bytes docs/img/task-farm.png.license | 3 + docs/img/task-farm.svg.license | 3 + docs/img/terminal.png.license | 3 + docs/img/unboxing-boxing.png | Bin 0 -> 57913 bytes docs/img/unboxing-boxing.png.license | 3 + docs/img/unboxing-boxing.svg.license | 3 + docs/img/usage_pattern.svg.license | 3 + docs/img/vectorised-difference.png.license | 3 + docs/img/vectorised-difference.svg.license | 3 + docs/mooc/index.md | 6 + .../numerical-computing/anatomy-of-ndarray.md | 6 + docs/mooc/numerical-computing/broadcasting.md | 6 + .../creating-and-accessing.md | 6 + docs/mooc/numerical-computing/file-io.md | 6 + .../numerical-computing/linear-algebra.md | 6 + docs/mooc/numerical-computing/numexpr.md | 6 + .../numerical-computing/random-numbers.md | 6 + .../numerical-computing/simple-operations.md | 6 + docs/mooc/numerical-computing/summary.md | 6 + .../numerical-computing/temporary-arrays.md | 6 + .../vectorised-operations.md | 6 + .../collectives-1-to-n.md | 6 + .../collectives-n-to-1.md | 6 + .../collectives-n-to-n.md | 6 + .../parallel-programming/communicators.md | 6 + docs/mooc/parallel-programming/concepts.md | 6 + .../mooc/parallel-programming/intro-to-mpi.md | 6 + .../mooc/parallel-programming/non-blocking.md | 6 + .../mooc/parallel-programming/parallel-sum.md | 6 + .../python-in-parallel.md | 6 + .../send-receive-array.md | 6 + .../mooc/parallel-programming/send-receive.md | 6 + docs/mooc/parallel-programming/summary.md | 6 + .../python-and-performance/heat-equation.md | 6 + .../performance-analysis.md | 6 + .../performance-bottlenecks.md | 6 + .../python-and-performance/prerequisities.md | 6 + .../setting-environment.md | 6 + docs/mooc/python-and-performance/summary.md | 6 + .../using-own-timers.md | 6 + .../python-and-performance/using-timeit.md | 6 + .../avoiding-function-call-overheads.md | 6 + .../creating-cython-modules.md | 6 + .../interfacing-c-with-cffi.md | 6 + .../interfacing-c-with-cython.md | 6 + .../interfacing-fortran.md | 6 + .../using-compiled-code/numpy-and-cython.md | 6 + .../using-compiled-code/profiling-cython.md | 6 + docs/mooc/using-compiled-code/summary.md | 6 + .../using-static-typing.md | 6 + .../using-compiled-code/what-is-cython.md | 6 + exercise-instructions.md | 6 + interface/c/README.md | 6 + interface/c/evolve.c | 6 + interface/c/heat.py | 4 + interface/c/heat_main.py | 4 + interface/c/solution/build_evolve.py | 4 + interface/c/solution/evolve_cyt.pyx | 4 + interface/c/solution/heat_cffi.py | 4 + interface/c/solution/heat_cython.py | 4 + interface/c/solution/heat_main.py | 4 + interface/c/solution/setup.py | 4 + interface/c/solution/setup2.py | 4 + interface/fortran/README.md | 6 + interface/fortran/evolve.f90 | 4 + interface/fortran/heat.py | 4 + interface/fortran/heat_main.py | 4 + interface/fortran/solution/evolve.f90 | 4 + interface/fortran/solution/heat.py | 4 + interface/fortran/solution/heat_main.py | 4 + mpi/collectives/README.md | 6 + mpi/collectives/skeleton.py | 4 + mpi/collectives/solution/collectives.py | 4 + mpi/heat-equation-cython/README.md | 6 + mpi/heat-equation-cython/solution/evolve.pyx | 4 + mpi/heat-equation-cython/solution/heat-p2p.py | 4 + mpi/heat-equation-cython/solution/setup.py | 4 + mpi/heat-equation/README.md | 6 + .../domain_decomposition.png.license | 3 + mpi/heat-equation/skeleton.py | 4 + mpi/heat-equation/solution/heat-p2p.py | 4 + mpi/hello-world/README.md | 6 + mpi/hello-world/solution/hello-world.py | 4 + mpi/message-chain/README.md | 6 + mpi/message-chain/solution/msg-chain.py | 4 + mpi/message-exchange/README.md | 6 + mpi/message-exchange/solution/msg-exchange.py | 4 + mpi/non-blocking/README.md | 6 + mpi/non-blocking/solution/heat.py | 4 + mpi/non-blocking/solution/msg-chain.py | 4 + .../data-sharing/solution/data-manager.py | 4 + .../data-sharing/solution/shared-memory.py | 4 + multiprocessing/pipes/count-w.py | 4 + multiprocessing/pipes/fasta.py | 5 + multiprocessing/simple-calculation/README.md | 6 + .../simple-calculation/solution/square.py | 4 + multiprocessing/work-distribution/README.md | 6 + .../work-distribution/center-of-coords.py | 4 + multiprocessing/work-distribution/pdb.py | 5 + .../solution/pool-of-workers.py | 4 + .../work-distribution/solution/task-queue.py | 4 + numpy/advanced-indexing/README.md | 6 + .../advanced-indexing/solution/index-mask.py | 4 + numpy/array-creation/README.md | 6 + numpy/array-creation/solution/create-array.py | 4 + numpy/array-slicing/README.md | 6 + numpy/array-slicing/solution/slice-2d.py | 4 + numpy/broadcast-rotation/README.md | 6 + numpy/broadcast-rotation/solution/rotate.py | 4 + numpy/broadcast-translation/README.md | 6 + .../solution/translate.py | 4 + numpy/dna-mutation/README.md | 6 + numpy/dna-mutation/skeleton.py | 4 + numpy/dna-mutation/solution/mutate.py | 4 + numpy/finite-difference/README.md | 6 + .../solution/finite-difference.py | 4 + numpy/game-of-life/README.md | 6 + numpy/game-of-life/gol_initial.png.license | 3 + numpy/game-of-life/solution/game-of-life.py | 4 + numpy/heat-equation/README.md | 6 + numpy/heat-equation/heat.py | 4 + numpy/heat-equation/heat_main.py | 4 + numpy/heat-equation/solution/heat.py | 4 + numpy/heat-equation/solution/heat_main.py | 4 + numpy/img/finite-difference.png.license | 3 + numpy/img/heat-equation.png.license | 3 + numpy/img/heat-stability.png.license | 3 + numpy/img/heat-time-propagation.png.license | 3 + numpy/img/nabla.png.license | 3 + numpy/img/rieman-sum1.png.license | 3 + numpy/img/rieman-sum2.png.license | 3 + numpy/img/rotation-matrix.png.license | 3 + numpy/input-output/README.md | 6 + numpy/input-output/solution/input-output.py | 4 + numpy/integration/README.md | 6 + numpy/integration/solution/riemann-sum.py | 4 + numpy/linear-algebra/README.md | 6 + .../linear-algebra/solution/matrix-product.py | 4 + numpy/masked-array/README.md | 6 + numpy/masked-array/solution/faulty-data.py | 4 + numpy/numexpr/README.md | 6 + numpy/polynomials/README.md | 6 + numpy/polynomials/solution/fit.py | 4 + numpy/random-numbers/README.md | 6 + .../random-numbers/solution/uniform-normal.py | 4 + numpy/reference-copy/README.md | 6 + numpy/split-combine/README.md | 6 + numpy/split-combine/solution/split-combine.py | 4 + numpy/subdiagonal-matrix/README.md | 6 + .../solution/subdiagonal.py | 4 + numpy/temporary-arrays/README.md | 6 + performance/cprofile/README.md | 6 + performance/cprofile/heat.py | 4 + performance/cprofile/heat_main.py | 4 + test/test.py | 4 + 317 files changed, 1597 insertions(+), 468 deletions(-) create mode 100644 COPYING delete mode 100644 LICENSE create mode 100644 LICENSES/CC-BY-NC-SA-4.0.txt create mode 100644 LICENSES/MIT.txt create mode 100644 cython/heat-equation/solution/evolve_new.pyx create mode 100644 cython/heat-equation/solution/evolve_py.py delete mode 100644 docs/LICENSE create mode 100644 docs/img/appliance-settings.png.license create mode 100644 docs/img/case_study_left-01.svg.license create mode 100644 docs/img/case_study_left-02.svg.license create mode 100644 docs/img/case_study_left-03.svg.license create mode 100644 docs/img/case_study_left-04.svg.license create mode 100644 docs/img/case_study_left-05.svg.license create mode 100644 docs/img/case_study_left-06.svg.license create mode 100644 docs/img/case_study_left-07.svg.license create mode 100644 docs/img/case_study_right-01.svg.license create mode 100644 docs/img/case_study_right-02.svg.license create mode 100644 docs/img/case_study_right-03.svg.license create mode 100644 docs/img/case_study_right-04.svg.license create mode 100644 docs/img/case_study_right-05.svg.license create mode 100644 docs/img/case_study_right-06.svg.license create mode 100644 docs/img/comm_patt.svg.license create mode 100644 docs/img/communication-patterns.png.license create mode 100644 docs/img/communication-patterns.svg.license create mode 100644 docs/img/communication-schematic.png.license create mode 100644 docs/img/communication-schematic.svg.license create mode 100644 docs/img/communication-schematic2.png.license create mode 100644 docs/img/communication-schematic2.svg.license create mode 100644 docs/img/communicator.svg.license create mode 100644 docs/img/compp.png create mode 100644 docs/img/compp.png.license create mode 100644 docs/img/compp.svg.license create mode 100644 docs/img/data-model.svg.license create mode 100644 docs/img/data-parallel.png create mode 100644 docs/img/data-parallel.png.license create mode 100644 docs/img/data-parallel.svg.license create mode 100644 docs/img/fractal.svg.license create mode 100644 docs/img/heat.png.license create mode 100644 docs/img/import-appliance-2.png.license create mode 100644 docs/img/import-appliance.png.license create mode 100644 docs/img/list-vs-array.svg.license create mode 100644 docs/img/login.png.license create mode 100644 docs/img/mpi-all2all.png.license create mode 100644 docs/img/mpi-all2all.svg.license create mode 100644 docs/img/mpi-bcast.png.license create mode 100644 docs/img/mpi-bcast.svg.license create mode 100644 docs/img/mpi-data-model.png.license create mode 100644 docs/img/mpi-data-model.svg.license create mode 100644 docs/img/mpi-gather.png.license create mode 100644 docs/img/mpi-gather.svg.license create mode 100644 docs/img/mpi-reduce.png.license create mode 100644 docs/img/mpi-reduce.svg.license create mode 100644 docs/img/mpi-scatter.png.license create mode 100644 docs/img/mpi-scatter.svg.license create mode 100644 docs/img/ndarray-in-memory-offset.png.license create mode 100644 docs/img/ndarray-in-memory-offset.svg.license create mode 100644 docs/img/ndarray-in-memory.png.license create mode 100644 docs/img/ndarray-in-memory.svg.license create mode 100644 docs/img/non-blocking-pattern.png.license create mode 100644 docs/img/non-blocking-pattern.svg.license create mode 100644 docs/img/parallel-sum-0.png.license create mode 100644 docs/img/parallel-sum-0.svg.license create mode 100644 docs/img/parallel-sum-1.1.png.license create mode 100644 docs/img/parallel-sum-1.1.svg.license create mode 100644 docs/img/parallel-sum-1.2.png.license create mode 100644 docs/img/parallel-sum-1.2.svg.license create mode 100644 docs/img/parallel-sum-2.png.license create mode 100644 docs/img/parallel-sum-2.svg.license create mode 100644 docs/img/parallel-sum-3.1.png.license create mode 100644 docs/img/parallel-sum-3.1.svg.license create mode 100644 docs/img/parallel-sum-3.2.png.license create mode 100644 docs/img/parallel-sum-3.2.svg.license create mode 100644 docs/img/parallel-sum-4.png.license create mode 100644 docs/img/parallel-sum-4.svg.license create mode 100644 docs/img/parallel-sum.svg.license create mode 100644 docs/img/processes-threads-highlight-proc.svg.license create mode 100644 docs/img/processes-threads.png.license create mode 100644 docs/img/processes-threads.svg.license create mode 100644 docs/img/scaling.png create mode 100644 docs/img/scaling.png.license create mode 100644 docs/img/start-vm.png.license create mode 100644 docs/img/task-farm.png create mode 100644 docs/img/task-farm.png.license create mode 100644 docs/img/task-farm.svg.license create mode 100644 docs/img/terminal.png.license create mode 100644 docs/img/unboxing-boxing.png create mode 100644 docs/img/unboxing-boxing.png.license create mode 100644 docs/img/unboxing-boxing.svg.license create mode 100644 docs/img/usage_pattern.svg.license create mode 100644 docs/img/vectorised-difference.png.license create mode 100644 docs/img/vectorised-difference.svg.license create mode 100644 mpi/heat-equation/domain_decomposition.png.license create mode 100644 numpy/game-of-life/gol_initial.png.license create mode 100644 numpy/img/finite-difference.png.license create mode 100644 numpy/img/heat-equation.png.license create mode 100644 numpy/img/heat-stability.png.license create mode 100644 numpy/img/heat-time-propagation.png.license create mode 100644 numpy/img/nabla.png.license create mode 100644 numpy/img/rieman-sum1.png.license create mode 100644 numpy/img/rieman-sum2.png.license create mode 100644 numpy/img/rotation-matrix.png.license diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..494684e --- /dev/null +++ b/COPYING @@ -0,0 +1,8 @@ +All material Copyright (c) CSC - IT Center for Science Ltd. unless otherwise noted. + +All text and image material licensed under Creative Commons BY-NC-SA 4.0 unless +otherwise noted. + +All code samples licensed under MIT license unless otherwise noted. + +See LICENSES/ and individual file headers for more details. diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 9c99a1f..0000000 --- a/LICENSE +++ /dev/null @@ -1,30 +0,0 @@ -MIT License - -Copyright (c) 2019 CSC - IT Center for Science Ltd. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - ---- - -All material in the directory 'docs/' and its sub-directories is licensed -under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 -International (CC-BY-NC-SA 4.0) license. - -Full text of the license is available in the file 'docs/LICENSE' and at -. diff --git a/LICENSES/CC-BY-NC-SA-4.0.txt b/LICENSES/CC-BY-NC-SA-4.0.txt new file mode 100644 index 0000000..baee873 --- /dev/null +++ b/LICENSES/CC-BY-NC-SA-4.0.txt @@ -0,0 +1,170 @@ +Creative Commons Attribution-NonCommercial-ShareAlike 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. + +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. + +Creative Commons Attribution-NonCommercial-ShareAlike 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-NonCommercial-ShareAlike 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. BY-NC-SA Compatible License means a license listed at creativecommons.org/compatiblelicenses, approved by Creative Commons as essentially the equivalent of this Public License. + + d. 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. + + e. 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. + + f. 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. + + g. License Elements means the license attributes listed in the name of a Creative Commons Public License. The License Elements of this Public License are Attribution, NonCommercial, and ShareAlike. + + h. Licensed Material means the artistic or literary work, database, or other material to which the Licensor applied this Public License. + + i. 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. + + j. Licensor means the individual(s) or entity(ies) granting rights under this Public License. + + k. NonCommercial means not primarily intended for or directed towards commercial advantage or monetary compensation. For purposes of this Public License, the exchange of the Licensed Material for other material subject to Copyright and Similar Rights by digital file-sharing or similar means is NonCommercial provided there is no payment of monetary compensation in connection with the exchange. + + l. 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. + + m. 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. + + n. 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, for NonCommercial purposes only; and + + B. produce, reproduce, and Share Adapted Material for NonCommercial purposes only. + + 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. Additional offer from the Licensor – Adapted Material. Every recipient of Adapted Material from You automatically receives an offer from the Licensor to exercise the Licensed Rights in the Adapted Material under the conditions of the Adapter’s License You apply. + + C. 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, including when the Licensed Material is used other than for NonCommercial purposes. + +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. + + b. ShareAlike.In addition to the conditions in Section 3(a), if You Share Adapted Material You produce, the following conditions also apply. + + 1. The Adapter’s License You apply must be a Creative Commons license with the same License Elements, this version or later, or a BY-NC-SA Compatible License. + + 2. You must include the text of, or the URI or hyperlink to, the Adapter's License You apply. You may satisfy this condition in any reasonable manner based on the medium, means, and context in which You Share Adapted Material. + + 3. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, Adapted Material that restrict exercise of the rights granted under the Adapter's License You apply. + +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 for NonCommercial purposes only; + + 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, including for purposes of Section 3(b); 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.” 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. diff --git a/LICENSES/MIT.txt b/LICENSES/MIT.txt new file mode 100644 index 0000000..fc2cf8e --- /dev/null +++ b/LICENSES/MIT.txt @@ -0,0 +1,18 @@ +MIT License + +Copyright (c) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the +following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT +LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO +EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index 22d94d9..1c80c66 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,9 @@ + + # Python in High Performance Computing Exercise material and model answers for the CSC course "Python in High Performance Computing". The course is part of PRACE Training activity at CSC. diff --git a/cython/c-functions/README.md b/cython/c-functions/README.md index c79f63c..c1645a7 100644 --- a/cython/c-functions/README.md +++ b/cython/c-functions/README.md @@ -1,3 +1,9 @@ + + ## Using C-functions Fibonacci numbers are a sequence of integers defined by the recurrence diff --git a/cython/c-functions/fib.py b/cython/c-functions/fib.py index 0b2bfa4..45499ae 100644 --- a/cython/c-functions/fib.py +++ b/cython/c-functions/fib.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + def fibonacci(n): if n < 2: return n diff --git a/cython/c-functions/solution/fib.pyx b/cython/c-functions/solution/fib.pyx index f8946d6..91f7546 100644 --- a/cython/c-functions/solution/fib.pyx +++ b/cython/c-functions/solution/fib.pyx @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + cpdef int fibonacci(int n): if n < 2: return n diff --git a/cython/c-functions/solution/fib_py.py b/cython/c-functions/solution/fib_py.py index 5b8692a..ae0c259 100644 --- a/cython/c-functions/solution/fib_py.py +++ b/cython/c-functions/solution/fib_py.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from functools import lru_cache def fibonacci(n): diff --git a/cython/c-functions/solution/setup.py b/cython/c-functions/solution/setup.py index cb4073b..9d715f5 100644 --- a/cython/c-functions/solution/setup.py +++ b/cython/c-functions/solution/setup.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from distutils.core import setup, Extension from Cython.Build import cythonize diff --git a/cython/c-functions/solution/test_fib.py b/cython/c-functions/solution/test_fib.py index e333721..99a1742 100644 --- a/cython/c-functions/solution/test_fib.py +++ b/cython/c-functions/solution/test_fib.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from fib import fibonacci from fib_py import fibonacci as fibonacci_py, fibonacci_cached from timeit import repeat diff --git a/cython/heat-equation/README.md b/cython/heat-equation/README.md index 6f3a72b..b1ea439 100644 --- a/cython/heat-equation/README.md +++ b/cython/heat-equation/README.md @@ -1,3 +1,9 @@ + + ## Optimising heat equation with Cython ### Creating a Cython extension diff --git a/cython/heat-equation/heat.py b/cython/heat-equation/heat.py index cd6a03d..1e4abbd 100644 --- a/cython/heat-equation/heat.py +++ b/cython/heat-equation/heat.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np import matplotlib matplotlib.use('Agg') diff --git a/cython/heat-equation/heat_main.py b/cython/heat-equation/heat_main.py index b129e5c..d51d915 100644 --- a/cython/heat-equation/heat_main.py +++ b/cython/heat-equation/heat_main.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from __future__ import print_function import time import argparse diff --git a/cython/heat-equation/profile.md b/cython/heat-equation/profile.md index b846704..01d5892 100644 --- a/cython/heat-equation/profile.md +++ b/cython/heat-equation/profile.md @@ -1,3 +1,9 @@ + + ## Example profile for heat equation solver ``` diff --git a/cython/heat-equation/solution/evolve_new.pyx b/cython/heat-equation/solution/evolve_new.pyx new file mode 100644 index 0000000..ac36760 --- /dev/null +++ b/cython/heat-equation/solution/evolve_new.pyx @@ -0,0 +1,50 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + +# cython: profile=True + +import numpy as np +cimport numpy as cnp + +import cython + +@cython.boundscheck(False) +@cython.wraparound(False) +@cython.cdivision(True) +cdef laplacian(cnp.ndarray[cnp.double_t, ndim=2]u, cnp.ndarray[cnp.double_t, ndim=2]du, double dx2, double dy2): + + cdef int n = u.shape[0] + cdef int m = u.shape[1] + + cdef int i,j + + # Multiplication is more efficient than division + cdef double dx2inv = 1. / dx2 + cdef double dy2inv = 1. / dy2 + + for i in range(1, n-1): + for j in range(1, m-1): + du[i, j] = (u[i+1, j] - 2*u[i, j] + u[i-1, j]) * dx2inv + \ + (u[i, j+1] - 2*u[i, j] + u[i, j-1]) * dy2inv + + + +@cython.boundscheck(False) +@cython.wraparound(False) +@cython.cdivision(True) +def evolve(cnp.ndarray[cnp.double_t, ndim=2]u, + cnp.ndarray[cnp.double_t, ndim=2]u_previous, + double a, double dt, double dx2, double dy2): + """Explicit time evolution. + u: new temperature field + u_previous: previous field + a: diffusion constant + dt: time step. """ + + laplacian(u_previous, u, dx2, dy2) + # u *= a * dt + u = u_previous + a*dt * u + + u_previous[:] = u[:] + diff --git a/cython/heat-equation/solution/evolve_py.py b/cython/heat-equation/solution/evolve_py.py new file mode 100644 index 0000000..103eaf3 --- /dev/null +++ b/cython/heat-equation/solution/evolve_py.py @@ -0,0 +1,32 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + +import numpy as np +from numba import jit, void, double + +# @jit(void(double[:,:], double[:,:], double, double, double, double), nopython=True, cache=True, fastmath=True, error_model='numpy') +# @jit(nopython=True, cache=True, fastmath=True) +@jit(nopython=True) +def evolve(u, u_previous, a, dt, dx2, dy2): + """Explicit time evolution. + u: new temperature field + u_previous: previous field + a: diffusion constant + dt: time step. """ + + n, m = u.shape + + # dx2inv = 1.0 / dx2 + # dy2inv = 1.0 / dy2 + for i in range(1, n-1): + for j in range(1, m-1): + u[i, j] = u_previous[i, j] + a * dt * ( \ + (u_previous[i+1, j] - 2*u_previous[i, j] + \ + u_previous[i-1, j]) / dx2 + \ + # u_previous[i-1, j]) * dx2inv + \ + (u_previous[i, j+1] - 2*u_previous[i, j] + \ + u_previous[i, j-1]) / dy2 ) + # u_previous[i, j-1]) * dy2inv ) + u_previous[:] = u[:] + diff --git a/cython/heat-equation/solution/heat.pyx b/cython/heat-equation/solution/heat.pyx index 6d4a0cb..6a9eed9 100644 --- a/cython/heat-equation/solution/heat.pyx +++ b/cython/heat-equation/solution/heat.pyx @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np cimport numpy as cnp import cython diff --git a/cython/heat-equation/solution/heat_main.py b/cython/heat-equation/solution/heat_main.py index b129e5c..d51d915 100644 --- a/cython/heat-equation/solution/heat_main.py +++ b/cython/heat-equation/solution/heat_main.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from __future__ import print_function import time import argparse diff --git a/cython/heat-equation/solution/setup.py b/cython/heat-equation/solution/setup.py index 3906cb8..6afb069 100644 --- a/cython/heat-equation/solution/setup.py +++ b/cython/heat-equation/solution/setup.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from distutils.core import setup, Extension from Cython.Build import cythonize diff --git a/cython/simple-extension/README.md b/cython/simple-extension/README.md index d4b33d5..3f1ea95 100644 --- a/cython/simple-extension/README.md +++ b/cython/simple-extension/README.md @@ -1,3 +1,9 @@ + + ## Simple Cython extension ### Creating a Cython extension diff --git a/cython/simple-extension/solution/cyt_module.pyx b/cython/simple-extension/solution/cyt_module.pyx index 0059fa1..8faea5a 100644 --- a/cython/simple-extension/solution/cyt_module.pyx +++ b/cython/simple-extension/solution/cyt_module.pyx @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + def subtract(x, y): result = x - y return result diff --git a/cython/simple-extension/solution/setup.py b/cython/simple-extension/solution/setup.py index c944b64..a470a14 100644 --- a/cython/simple-extension/solution/setup.py +++ b/cython/simple-extension/solution/setup.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from distutils.core import setup, Extension from Cython.Build import cythonize diff --git a/cython/static-typing/README.md b/cython/static-typing/README.md index 1c98277..f9ccc41 100644 --- a/cython/static-typing/README.md +++ b/cython/static-typing/README.md @@ -1,3 +1,9 @@ + + ## Using static typing Continue with the simple Cython module for subtracting two numbers: diff --git a/cython/static-typing/cyt_module.pyx b/cython/static-typing/cyt_module.pyx index 0059fa1..8faea5a 100644 --- a/cython/static-typing/cyt_module.pyx +++ b/cython/static-typing/cyt_module.pyx @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + def subtract(x, y): result = x - y return result diff --git a/cython/static-typing/setup.py b/cython/static-typing/setup.py index c944b64..a470a14 100644 --- a/cython/static-typing/setup.py +++ b/cython/static-typing/setup.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from distutils.core import setup, Extension from Cython.Build import cythonize diff --git a/cython/static-typing/solution/cyt_module.pyx b/cython/static-typing/solution/cyt_module.pyx index 942222b..9f02422 100644 --- a/cython/static-typing/solution/cyt_module.pyx +++ b/cython/static-typing/solution/cyt_module.pyx @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + def subtract(int x, int y): cdef int result result = x - y diff --git a/cython/static-typing/solution/setup.py b/cython/static-typing/solution/setup.py index c944b64..a470a14 100644 --- a/cython/static-typing/solution/setup.py +++ b/cython/static-typing/solution/setup.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from distutils.core import setup, Extension from Cython.Build import cythonize diff --git a/demos/broadcasting.py b/demos/broadcasting.py index b78399a..62ad60f 100644 --- a/demos/broadcasting.py +++ b/demos/broadcasting.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np a1 = np.random.random((10,3)) diff --git a/demos/cython/mandel.py b/demos/cython/mandel.py index 85e6cfa..8cf0a0e 100644 --- a/demos/cython/mandel.py +++ b/demos/cython/mandel.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from time import time import numpy as np diff --git a/demos/cython/mandel_cyt.pyx b/demos/cython/mandel_cyt.pyx index a736ece..f2f3f29 100644 --- a/demos/cython/mandel_cyt.pyx +++ b/demos/cython/mandel_cyt.pyx @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from time import time import numpy as np cimport numpy as cnp diff --git a/demos/cython/mandel_cyt_1.pyx b/demos/cython/mandel_cyt_1.pyx index 2843c9d..fac9f50 100644 --- a/demos/cython/mandel_cyt_1.pyx +++ b/demos/cython/mandel_cyt_1.pyx @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from time import time import numpy as np diff --git a/demos/cython/mandel_cyt_2.pyx b/demos/cython/mandel_cyt_2.pyx index 217f6f1..3e529fc 100644 --- a/demos/cython/mandel_cyt_2.pyx +++ b/demos/cython/mandel_cyt_2.pyx @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from time import time import numpy as np diff --git a/demos/cython/mandel_cyt_3.pyx b/demos/cython/mandel_cyt_3.pyx index 8d76f65..f8ffb4a 100644 --- a/demos/cython/mandel_cyt_3.pyx +++ b/demos/cython/mandel_cyt_3.pyx @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from time import time import numpy as np cimport numpy as cnp diff --git a/demos/cython/mandel_cyt_4.pyx b/demos/cython/mandel_cyt_4.pyx index e23cbf2..c8d93a4 100644 --- a/demos/cython/mandel_cyt_4.pyx +++ b/demos/cython/mandel_cyt_4.pyx @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from time import time import numpy as np cimport numpy as cnp diff --git a/demos/cython/mandel_cyt_5.pyx b/demos/cython/mandel_cyt_5.pyx index 5fb8cf5..e70c5ad 100644 --- a/demos/cython/mandel_cyt_5.pyx +++ b/demos/cython/mandel_cyt_5.pyx @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from time import time import numpy as np cimport numpy as cnp diff --git a/demos/cython/mandel_main.py b/demos/cython/mandel_main.py index 0c1784d..ddd836e 100644 --- a/demos/cython/mandel_main.py +++ b/demos/cython/mandel_main.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np import matplotlib.pyplot as plt import sys diff --git a/demos/cython/setup.py b/demos/cython/setup.py index 7e1a92b..68fef9e 100644 --- a/demos/cython/setup.py +++ b/demos/cython/setup.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from distutils.core import setup, Extension from Cython.Build import cythonize diff --git a/demos/interface/c-extension/example.c b/demos/interface/c-extension/example.c index 7f89742..6ac2773 100644 --- a/demos/interface/c-extension/example.c +++ b/demos/interface/c-extension/example.c @@ -1,3 +1,9 @@ +/* + * SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + * + * SPDX-License-Identifier: MIT + */ + #include #include diff --git a/demos/interface/c-extension/setup.py b/demos/interface/c-extension/setup.py index cf69b19..26dc6e3 100644 --- a/demos/interface/c-extension/setup.py +++ b/demos/interface/c-extension/setup.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from distutils.core import setup, Extension import numpy as np diff --git a/demos/interface/cffi/example.py b/demos/interface/cffi/example.py index 4fdfc8b..0d3963e 100644 --- a/demos/interface/cffi/example.py +++ b/demos/interface/cffi/example.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from cffi import FFI import numpy as np diff --git a/demos/interface/cffi/myclib.c b/demos/interface/cffi/myclib.c index 109330a..64e4ef7 100644 --- a/demos/interface/cffi/myclib.c +++ b/demos/interface/cffi/myclib.c @@ -1,3 +1,9 @@ +/* + * SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + * + * SPDX-License-Identifier: MIT + */ + void add(double *a, double *b, int n) { int i; diff --git a/demos/interface/fortran/add.f90 b/demos/interface/fortran/add.f90 index 05ad248..0ec43ac 100644 --- a/demos/interface/fortran/add.f90 +++ b/demos/interface/fortran/add.f90 @@ -1,3 +1,7 @@ +! SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +! +! SPDX-License-Identifier: MIT + subroutine add(a, b, c, n) implicit none diff --git a/demos/interface/fortran/example.py b/demos/interface/fortran/example.py index 18b6412..7fceffe 100644 --- a/demos/interface/fortran/example.py +++ b/demos/interface/fortran/example.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import add import numpy as np diff --git a/demos/lock.py b/demos/lock.py index b65be1d..973f630 100644 --- a/demos/lock.py +++ b/demos/lock.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from multiprocessing import Process, Lock import random import time diff --git a/demos/manager.py b/demos/manager.py index fa4a868..a9c897c 100644 --- a/demos/manager.py +++ b/demos/manager.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from multiprocessing import Process, Manager def f(x): diff --git a/demos/memory_usage.py b/demos/memory_usage.py index c6c0fed..99e36d2 100644 --- a/demos/memory_usage.py +++ b/demos/memory_usage.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np import os diff --git a/demos/mpi-alltoall.py b/demos/mpi-alltoall.py index c3234fd..8e45ea9 100644 --- a/demos/mpi-alltoall.py +++ b/demos/mpi-alltoall.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from mpi4py import MPI import numpy as np from sys import stdout diff --git a/demos/mpi-bcast.py b/demos/mpi-bcast.py index cb8e25d..a6c6ab9 100644 --- a/demos/mpi-bcast.py +++ b/demos/mpi-bcast.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from mpi4py import MPI import numpy as np from sys import stdout diff --git a/demos/mpi-cartesian.py b/demos/mpi-cartesian.py index 90fbe52..5b4dcea 100644 --- a/demos/mpi-cartesian.py +++ b/demos/mpi-cartesian.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from mpi4py import MPI from numpy import arange, empty diff --git a/demos/mpi-collective.py b/demos/mpi-collective.py index f73f854..2bde36c 100644 --- a/demos/mpi-collective.py +++ b/demos/mpi-collective.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from mpi4py import MPI from numpy import arange, empty diff --git a/demos/mpi-custom-operator.py b/demos/mpi-custom-operator.py index 94fd035..9f5af74 100644 --- a/demos/mpi-custom-operator.py +++ b/demos/mpi-custom-operator.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from mpi4py import MPI def add(x,y): diff --git a/demos/mpi-example.py b/demos/mpi-example.py index 9834674..319ee17 100644 --- a/demos/mpi-example.py +++ b/demos/mpi-example.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from mpi4py import MPI import numpy diff --git a/demos/mpi-gather.py b/demos/mpi-gather.py index fa206d2..cbb1cd8 100644 --- a/demos/mpi-gather.py +++ b/demos/mpi-gather.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from mpi4py import MPI import numpy as np from sys import stdout diff --git a/demos/mpi-halo-exchange.py b/demos/mpi-halo-exchange.py index b4fd5b5..62617b6 100644 --- a/demos/mpi-halo-exchange.py +++ b/demos/mpi-halo-exchange.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from mpi4py import MPI from numpy import zeros, ones diff --git a/demos/mpi-hello.py b/demos/mpi-hello.py index af85f23..db6931a 100644 --- a/demos/mpi-hello.py +++ b/demos/mpi-hello.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from mpi4py import MPI comm = MPI.COMM_WORLD diff --git a/demos/mpi-isend.py b/demos/mpi-isend.py index ac438f7..00335ae 100644 --- a/demos/mpi-isend.py +++ b/demos/mpi-isend.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from mpi4py import MPI from numpy import arange, empty diff --git a/demos/mpi-manual-buffer.py b/demos/mpi-manual-buffer.py index 61588e2..b46de04 100644 --- a/demos/mpi-manual-buffer.py +++ b/demos/mpi-manual-buffer.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from mpi4py import MPI import numpy diff --git a/demos/mpi-msg-chain.py b/demos/mpi-msg-chain.py index 76dffcb..b488966 100644 --- a/demos/mpi-msg-chain.py +++ b/demos/mpi-msg-chain.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from mpi4py import MPI import numpy diff --git a/demos/mpi-p2p.py b/demos/mpi-p2p.py index 3a5b12f..39dd0b8 100644 --- a/demos/mpi-p2p.py +++ b/demos/mpi-p2p.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from mpi4py import MPI from numpy import arange, empty diff --git a/demos/mpi-reduce.py b/demos/mpi-reduce.py index f9e03f6..4ab3328 100644 --- a/demos/mpi-reduce.py +++ b/demos/mpi-reduce.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from mpi4py import MPI from numpy import arange, empty diff --git a/demos/mpi-scatter.py b/demos/mpi-scatter.py index 0c3c62e..50104f5 100644 --- a/demos/mpi-scatter.py +++ b/demos/mpi-scatter.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from mpi4py import MPI import numpy as np from sys import stdout diff --git a/demos/mpi-send-array.py b/demos/mpi-send-array.py index b27b612..0cc5868 100644 --- a/demos/mpi-send-array.py +++ b/demos/mpi-send-array.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from mpi4py import MPI import numpy diff --git a/demos/mpi-send.py b/demos/mpi-send.py index 35b3ddd..2a7c543 100644 --- a/demos/mpi-send.py +++ b/demos/mpi-send.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from mpi4py import MPI comm = MPI.COMM_WORLD # communicator object containing all processes diff --git a/demos/mpi-sendrecv.py b/demos/mpi-sendrecv.py index b43f684..495e256 100644 --- a/demos/mpi-sendrecv.py +++ b/demos/mpi-sendrecv.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from mpi4py import MPI import numpy diff --git a/demos/mpi-split.py b/demos/mpi-split.py index 94ee6e5..2934006 100644 --- a/demos/mpi-split.py +++ b/demos/mpi-split.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from mpi4py import MPI comm = MPI.COMM_WORLD diff --git a/demos/mpi-status.py b/demos/mpi-status.py index 1a38bc3..dcdd9f6 100644 --- a/demos/mpi-status.py +++ b/demos/mpi-status.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from mpi4py import MPI comm = MPI.COMM_WORLD diff --git a/demos/performance/gpaw/c6h6.py b/demos/performance/gpaw/c6h6.py index 0c1b067..50aa641 100644 --- a/demos/performance/gpaw/c6h6.py +++ b/demos/performance/gpaw/c6h6.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from ase.build import molecule from gpaw import GPAW import cProfile diff --git a/demos/performance/matmul/matmul.c b/demos/performance/matmul/matmul.c index a19a358..69b385c 100644 --- a/demos/performance/matmul/matmul.c +++ b/demos/performance/matmul/matmul.c @@ -1,3 +1,9 @@ +/* + * SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + * + * SPDX-License-Identifier: MIT + */ + #include #include #include diff --git a/demos/performance/matmul/matmul.py b/demos/performance/matmul/matmul.py index eae222a..69d3a12 100644 --- a/demos/performance/matmul/matmul.py +++ b/demos/performance/matmul/matmul.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np def multiply(a, b): diff --git a/demos/performance/matmul/test_matmul.py b/demos/performance/matmul/test_matmul.py index 5ec71c7..73b40e7 100644 --- a/demos/performance/matmul/test_matmul.py +++ b/demos/performance/matmul/test_matmul.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import os from timeit import repeat import numpy as np diff --git a/demos/performance/timing-with.py b/demos/performance/timing-with.py index cf46bb4..e09e144 100644 --- a/demos/performance/timing-with.py +++ b/demos/performance/timing-with.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np import time diff --git a/demos/performance/timing.py b/demos/performance/timing.py index 0330fc4..beb274a 100644 --- a/demos/performance/timing.py +++ b/demos/performance/timing.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np from time import perf_counter diff --git a/demos/pool-map.py b/demos/pool-map.py index 33bdbcf..1e1b6c4 100644 --- a/demos/pool-map.py +++ b/demos/pool-map.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from multiprocessing import Pool import time diff --git a/demos/pool.py b/demos/pool.py index 247dc02..918d6f6 100644 --- a/demos/pool.py +++ b/demos/pool.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from multiprocessing import Pool import time diff --git a/demos/shared-mem.py b/demos/shared-mem.py index d068f61..0ecb2ca 100644 --- a/demos/shared-mem.py +++ b/demos/shared-mem.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from multiprocessing import Process, Array def squared(a): diff --git a/demos/spawn.py b/demos/spawn.py index 364c88c..d5f9497 100644 --- a/demos/spawn.py +++ b/demos/spawn.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from multiprocessing import Process import os diff --git a/demos/task-queue.py b/demos/task-queue.py index fa130df..db5d110 100644 --- a/demos/task-queue.py +++ b/demos/task-queue.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from multiprocessing import Process, Queue def f(q, i): diff --git a/docs/00-overview.md b/docs/00-overview.md index 51887f0..4beca89 100644 --- a/docs/00-overview.md +++ b/docs/00-overview.md @@ -1,3 +1,9 @@ + + --- title: Python and High-Performance Computing lang: en diff --git a/docs/01-numpy-basics.md b/docs/01-numpy-basics.md index 56772aa..10a873d 100644 --- a/docs/01-numpy-basics.md +++ b/docs/01-numpy-basics.md @@ -1,3 +1,9 @@ + + --- title: Numpy basics lang: en diff --git a/docs/02-numpy-tools.md b/docs/02-numpy-tools.md index 0f331fe..68b365f 100644 --- a/docs/02-numpy-tools.md +++ b/docs/02-numpy-tools.md @@ -1,3 +1,9 @@ + + --- title: Numpy tools lang: en diff --git a/docs/03-numpy-advanced.md b/docs/03-numpy-advanced.md index d6d643f..1b050f0 100644 --- a/docs/03-numpy-advanced.md +++ b/docs/03-numpy-advanced.md @@ -1,3 +1,9 @@ + + --- title: Advanced concepts in NumPy lang: en diff --git a/docs/04-performance-analysis.md b/docs/04-performance-analysis.md index bce003a..2fdb1c3 100644 --- a/docs/04-performance-analysis.md +++ b/docs/04-performance-analysis.md @@ -1,3 +1,9 @@ + + --- title: Performance analysis lang: en diff --git a/docs/05-cython.md b/docs/05-cython.md index 3da7870..e94b04c 100644 --- a/docs/05-cython.md +++ b/docs/05-cython.md @@ -1,3 +1,9 @@ + + --- title: Cython and interfacing external libraries lang: en diff --git a/docs/06-multiprocessing.md b/docs/06-multiprocessing.md index d468e43..f64380a 100644 --- a/docs/06-multiprocessing.md +++ b/docs/06-multiprocessing.md @@ -1,3 +1,9 @@ + + --- title: Multiprocessing lang: en diff --git a/docs/07-mpi4py.md b/docs/07-mpi4py.md index 9e7d533..4873b92 100644 --- a/docs/07-mpi4py.md +++ b/docs/07-mpi4py.md @@ -1,3 +1,9 @@ + + --- title: MPI for Python lang: en diff --git a/docs/LICENSE b/docs/LICENSE deleted file mode 100644 index 7cdbe0b..0000000 --- a/docs/LICENSE +++ /dev/null @@ -1,438 +0,0 @@ -Attribution-NonCommercial-ShareAlike 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-NonCommercial-ShareAlike 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-NonCommercial-ShareAlike 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. BY-NC-SA Compatible License means a license listed at - creativecommons.org/compatiblelicenses, approved by Creative - Commons as essentially the equivalent of this Public License. - - d. 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. - - e. 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. - - f. 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. - - g. License Elements means the license attributes listed in the name - of a Creative Commons Public License. The License Elements of this - Public License are Attribution, NonCommercial, and ShareAlike. - - h. Licensed Material means the artistic or literary work, database, - or other material to which the Licensor applied this Public - License. - - i. 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. - - j. Licensor means the individual(s) or entity(ies) granting rights - under this Public License. - - k. NonCommercial means not primarily intended for or directed towards - commercial advantage or monetary compensation. For purposes of - this Public License, the exchange of the Licensed Material for - other material subject to Copyright and Similar Rights by digital - file-sharing or similar means is NonCommercial provided there is - no payment of monetary compensation in connection with the - exchange. - - l. 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. - - m. 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. - - n. 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, for NonCommercial purposes only; and - - b. produce, reproduce, and Share Adapted Material for - NonCommercial purposes only. - - 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. Additional offer from the Licensor -- Adapted Material. - Every recipient of Adapted Material from You - automatically receives an offer from the Licensor to - exercise the Licensed Rights in the Adapted Material - under the conditions of the Adapter's License You apply. - - c. 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, including when - the Licensed Material is used other than for NonCommercial - purposes. - - -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. - - b. ShareAlike. - - In addition to the conditions in Section 3(a), if You Share - Adapted Material You produce, the following conditions also apply. - - 1. The Adapter's License You apply must be a Creative Commons - license with the same License Elements, this version or - later, or a BY-NC-SA Compatible License. - - 2. You must include the text of, or the URI or hyperlink to, the - Adapter's License You apply. You may satisfy this condition - in any reasonable manner based on the medium, means, and - context in which You Share Adapted Material. - - 3. You may not offer or impose any additional or different terms - or conditions on, or apply any Effective Technological - Measures to, Adapted Material that restrict exercise of the - rights granted under the Adapter's License You apply. - - -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 for NonCommercial purposes - only; - - 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, - including for purposes of Section 3(b); 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. - diff --git a/docs/img/appliance-settings.png.license b/docs/img/appliance-settings.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/appliance-settings.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/case_study_left-01.svg.license b/docs/img/case_study_left-01.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/case_study_left-01.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/case_study_left-02.svg.license b/docs/img/case_study_left-02.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/case_study_left-02.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/case_study_left-03.svg.license b/docs/img/case_study_left-03.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/case_study_left-03.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/case_study_left-04.svg.license b/docs/img/case_study_left-04.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/case_study_left-04.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/case_study_left-05.svg.license b/docs/img/case_study_left-05.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/case_study_left-05.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/case_study_left-06.svg.license b/docs/img/case_study_left-06.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/case_study_left-06.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/case_study_left-07.svg.license b/docs/img/case_study_left-07.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/case_study_left-07.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/case_study_right-01.svg.license b/docs/img/case_study_right-01.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/case_study_right-01.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/case_study_right-02.svg.license b/docs/img/case_study_right-02.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/case_study_right-02.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/case_study_right-03.svg.license b/docs/img/case_study_right-03.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/case_study_right-03.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/case_study_right-04.svg.license b/docs/img/case_study_right-04.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/case_study_right-04.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/case_study_right-05.svg.license b/docs/img/case_study_right-05.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/case_study_right-05.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/case_study_right-06.svg.license b/docs/img/case_study_right-06.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/case_study_right-06.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/comm_patt.svg.license b/docs/img/comm_patt.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/comm_patt.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/communication-patterns.png.license b/docs/img/communication-patterns.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/communication-patterns.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/communication-patterns.svg.license b/docs/img/communication-patterns.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/communication-patterns.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/communication-schematic.png.license b/docs/img/communication-schematic.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/communication-schematic.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/communication-schematic.svg.license b/docs/img/communication-schematic.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/communication-schematic.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/communication-schematic2.png.license b/docs/img/communication-schematic2.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/communication-schematic2.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/communication-schematic2.svg.license b/docs/img/communication-schematic2.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/communication-schematic2.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/communicator.svg.license b/docs/img/communicator.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/communicator.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/compp.png b/docs/img/compp.png new file mode 100644 index 0000000000000000000000000000000000000000..fa8f2f26fd891d4993e425830ec734e412adf2cb GIT binary patch literal 22791 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 Y7ks>j8Mou9K&S>WJC8zE8M(y&53;B{;Q#;t literal 0 HcmV?d00001 diff --git a/docs/img/compp.png.license b/docs/img/compp.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/compp.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/compp.svg.license b/docs/img/compp.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/compp.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/data-model.svg.license b/docs/img/data-model.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/data-model.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/data-parallel.png b/docs/img/data-parallel.png new file mode 100644 index 0000000000000000000000000000000000000000..4dbbbaee72c73310c5a1dc3d2ed0873e97130df7 GIT binary patch literal 9649 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 + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/data-parallel.svg.license b/docs/img/data-parallel.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/data-parallel.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/fractal.svg.license b/docs/img/fractal.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/fractal.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/heat.png.license b/docs/img/heat.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/heat.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/import-appliance-2.png.license b/docs/img/import-appliance-2.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/import-appliance-2.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/import-appliance.png.license b/docs/img/import-appliance.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/import-appliance.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/list-vs-array.svg.license b/docs/img/list-vs-array.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/list-vs-array.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/login.png.license b/docs/img/login.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/login.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/mpi-all2all.png.license b/docs/img/mpi-all2all.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/mpi-all2all.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/mpi-all2all.svg.license b/docs/img/mpi-all2all.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/mpi-all2all.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/mpi-bcast.png.license b/docs/img/mpi-bcast.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/mpi-bcast.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/mpi-bcast.svg.license b/docs/img/mpi-bcast.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/mpi-bcast.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/mpi-data-model.png.license b/docs/img/mpi-data-model.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/mpi-data-model.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/mpi-data-model.svg.license b/docs/img/mpi-data-model.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/mpi-data-model.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/mpi-gather.png.license b/docs/img/mpi-gather.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/mpi-gather.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/mpi-gather.svg.license b/docs/img/mpi-gather.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/mpi-gather.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/mpi-reduce.png.license b/docs/img/mpi-reduce.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/mpi-reduce.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/mpi-reduce.svg.license b/docs/img/mpi-reduce.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/mpi-reduce.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/mpi-scatter.png.license b/docs/img/mpi-scatter.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/mpi-scatter.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/mpi-scatter.svg.license b/docs/img/mpi-scatter.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/mpi-scatter.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/ndarray-in-memory-offset.png.license b/docs/img/ndarray-in-memory-offset.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/ndarray-in-memory-offset.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/ndarray-in-memory-offset.svg.license b/docs/img/ndarray-in-memory-offset.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/ndarray-in-memory-offset.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/ndarray-in-memory.png.license b/docs/img/ndarray-in-memory.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/ndarray-in-memory.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/ndarray-in-memory.svg.license b/docs/img/ndarray-in-memory.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/ndarray-in-memory.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/non-blocking-pattern.png.license b/docs/img/non-blocking-pattern.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/non-blocking-pattern.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/non-blocking-pattern.svg.license b/docs/img/non-blocking-pattern.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/non-blocking-pattern.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/parallel-sum-0.png.license b/docs/img/parallel-sum-0.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/parallel-sum-0.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/parallel-sum-0.svg.license b/docs/img/parallel-sum-0.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/parallel-sum-0.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/parallel-sum-1.1.png.license b/docs/img/parallel-sum-1.1.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/parallel-sum-1.1.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/parallel-sum-1.1.svg.license b/docs/img/parallel-sum-1.1.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/parallel-sum-1.1.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/parallel-sum-1.2.png.license b/docs/img/parallel-sum-1.2.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/parallel-sum-1.2.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/parallel-sum-1.2.svg.license b/docs/img/parallel-sum-1.2.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/parallel-sum-1.2.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/parallel-sum-2.png.license b/docs/img/parallel-sum-2.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/parallel-sum-2.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/parallel-sum-2.svg.license b/docs/img/parallel-sum-2.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/parallel-sum-2.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/parallel-sum-3.1.png.license b/docs/img/parallel-sum-3.1.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/parallel-sum-3.1.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/parallel-sum-3.1.svg.license b/docs/img/parallel-sum-3.1.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/parallel-sum-3.1.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/parallel-sum-3.2.png.license b/docs/img/parallel-sum-3.2.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/parallel-sum-3.2.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/parallel-sum-3.2.svg.license b/docs/img/parallel-sum-3.2.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/parallel-sum-3.2.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/parallel-sum-4.png.license b/docs/img/parallel-sum-4.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/parallel-sum-4.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/parallel-sum-4.svg.license b/docs/img/parallel-sum-4.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/parallel-sum-4.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/parallel-sum.svg.license b/docs/img/parallel-sum.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/parallel-sum.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/processes-threads-highlight-proc.svg.license b/docs/img/processes-threads-highlight-proc.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/processes-threads-highlight-proc.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/processes-threads.png.license b/docs/img/processes-threads.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/processes-threads.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/processes-threads.svg.license b/docs/img/processes-threads.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/processes-threads.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/scaling.png b/docs/img/scaling.png new file mode 100644 index 0000000000000000000000000000000000000000..f696625f85e606528ef72bdd7a8e0e5953314f99 GIT binary patch literal 8461 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 + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/start-vm.png.license b/docs/img/start-vm.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/start-vm.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/task-farm.png b/docs/img/task-farm.png new file mode 100644 index 0000000000000000000000000000000000000000..f2348adc78dcf26d25aca236f67ee118afd6ce28 GIT binary patch literal 54446 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 Hu0mjff!A^F literal 0 HcmV?d00001 diff --git a/docs/img/task-farm.png.license b/docs/img/task-farm.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/task-farm.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/task-farm.svg.license b/docs/img/task-farm.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/task-farm.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/terminal.png.license b/docs/img/terminal.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/terminal.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/unboxing-boxing.png b/docs/img/unboxing-boxing.png new file mode 100644 index 0000000000000000000000000000000000000000..5a3d7d4d9a34ff29b1eb96713fc2fa46511427b2 GIT binary patch literal 57913 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 z c{vx02{$Aw;ArfkBpQYtJbMCvFfjWn+=hR{ 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 ARR910 literal 0 HcmV?d00001 diff --git a/docs/img/unboxing-boxing.png.license b/docs/img/unboxing-boxing.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/unboxing-boxing.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/unboxing-boxing.svg.license b/docs/img/unboxing-boxing.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/unboxing-boxing.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/usage_pattern.svg.license b/docs/img/usage_pattern.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/usage_pattern.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/vectorised-difference.png.license b/docs/img/vectorised-difference.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/vectorised-difference.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/img/vectorised-difference.svg.license b/docs/img/vectorised-difference.svg.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/docs/img/vectorised-difference.svg.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/docs/mooc/index.md b/docs/mooc/index.md index 4d10b3f..68e4339 100644 --- a/docs/mooc/index.md +++ b/docs/mooc/index.md @@ -1,3 +1,9 @@ + + # Introduction and performance analysis ## Welcome to the course diff --git a/docs/mooc/numerical-computing/anatomy-of-ndarray.md b/docs/mooc/numerical-computing/anatomy-of-ndarray.md index 428e51d..39fc5fd 100644 --- a/docs/mooc/numerical-computing/anatomy-of-ndarray.md +++ b/docs/mooc/numerical-computing/anatomy-of-ndarray.md @@ -1,3 +1,9 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ## Course setup Download (clone) the exercise material with diff --git a/interface/c/README.md b/interface/c/README.md index f0b6bc3..8ed53b0 100644 --- a/interface/c/README.md +++ b/interface/c/README.md @@ -1,3 +1,9 @@ + + ## Interfacing with C ### Using cffi diff --git a/interface/c/evolve.c b/interface/c/evolve.c index 94bcaa6..6e3d6d4 100644 --- a/interface/c/evolve.c +++ b/interface/c/evolve.c @@ -1,3 +1,9 @@ +/* + * SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + * + * SPDX-License-Identifier: MIT + */ + #include void evolve(double *u, double *u_previous, int nx, int ny, diff --git a/interface/c/heat.py b/interface/c/heat.py index cd6a03d..1e4abbd 100644 --- a/interface/c/heat.py +++ b/interface/c/heat.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np import matplotlib matplotlib.use('Agg') diff --git a/interface/c/heat_main.py b/interface/c/heat_main.py index b129e5c..d51d915 100644 --- a/interface/c/heat_main.py +++ b/interface/c/heat_main.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from __future__ import print_function import time import argparse diff --git a/interface/c/solution/build_evolve.py b/interface/c/solution/build_evolve.py index 5be2bfb..a470ba8 100644 --- a/interface/c/solution/build_evolve.py +++ b/interface/c/solution/build_evolve.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from cffi import FFI ffibuilder = FFI() diff --git a/interface/c/solution/evolve_cyt.pyx b/interface/c/solution/evolve_cyt.pyx index 0bcf35f..6c1d51f 100644 --- a/interface/c/solution/evolve_cyt.pyx +++ b/interface/c/solution/evolve_cyt.pyx @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np cimport numpy as cnp diff --git a/interface/c/solution/heat_cffi.py b/interface/c/solution/heat_cffi.py index 344fe11..1db16a6 100644 --- a/interface/c/solution/heat_cffi.py +++ b/interface/c/solution/heat_cffi.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np import matplotlib matplotlib.use('Agg') diff --git a/interface/c/solution/heat_cython.py b/interface/c/solution/heat_cython.py index ce9c0d6..d05fe7d 100644 --- a/interface/c/solution/heat_cython.py +++ b/interface/c/solution/heat_cython.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np import matplotlib matplotlib.use('Agg') diff --git a/interface/c/solution/heat_main.py b/interface/c/solution/heat_main.py index 09282a4..7edddf1 100644 --- a/interface/c/solution/heat_main.py +++ b/interface/c/solution/heat_main.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from __future__ import print_function import time import argparse diff --git a/interface/c/solution/setup.py b/interface/c/solution/setup.py index 353810e..56e6212 100644 --- a/interface/c/solution/setup.py +++ b/interface/c/solution/setup.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from distutils.core import setup, Extension from Cython.Build import cythonize diff --git a/interface/c/solution/setup2.py b/interface/c/solution/setup2.py index 8bb8d95..ccafd44 100644 --- a/interface/c/solution/setup2.py +++ b/interface/c/solution/setup2.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from distutils.core import setup, Extension from Cython.Build import cythonize diff --git a/interface/fortran/README.md b/interface/fortran/README.md index ab3a160..95d881d 100644 --- a/interface/fortran/README.md +++ b/interface/fortran/README.md @@ -1,3 +1,9 @@ + + ## Interfacing with Fortran The file [evolve.f90](evolve.f90) contain a pure Fortran implementation of the diff --git a/interface/fortran/evolve.f90 b/interface/fortran/evolve.f90 index af01020..e30f2d1 100644 --- a/interface/fortran/evolve.f90 +++ b/interface/fortran/evolve.f90 @@ -1,3 +1,7 @@ +! SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +! +! SPDX-License-Identifier: MIT + subroutine evolve(u, u_previous, nx, ny, a, dt, dx2, dy2) implicit none diff --git a/interface/fortran/heat.py b/interface/fortran/heat.py index cd6a03d..1e4abbd 100644 --- a/interface/fortran/heat.py +++ b/interface/fortran/heat.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np import matplotlib matplotlib.use('Agg') diff --git a/interface/fortran/heat_main.py b/interface/fortran/heat_main.py index b129e5c..d51d915 100644 --- a/interface/fortran/heat_main.py +++ b/interface/fortran/heat_main.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from __future__ import print_function import time import argparse diff --git a/interface/fortran/solution/evolve.f90 b/interface/fortran/solution/evolve.f90 index b37972d..d29327f 100644 --- a/interface/fortran/solution/evolve.f90 +++ b/interface/fortran/solution/evolve.f90 @@ -1,3 +1,7 @@ +! SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +! +! SPDX-License-Identifier: MIT + subroutine evolve(u, u_previous, nx, ny, a, dt, dx2, dy2) implicit none diff --git a/interface/fortran/solution/heat.py b/interface/fortran/solution/heat.py index a9ad106..db6ddc6 100644 --- a/interface/fortran/solution/heat.py +++ b/interface/fortran/solution/heat.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np import matplotlib matplotlib.use('Agg') diff --git a/interface/fortran/solution/heat_main.py b/interface/fortran/solution/heat_main.py index b129e5c..d51d915 100644 --- a/interface/fortran/solution/heat_main.py +++ b/interface/fortran/solution/heat_main.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from __future__ import print_function import time import argparse diff --git a/mpi/collectives/README.md b/mpi/collectives/README.md index 6a530b1..fb248b7 100644 --- a/mpi/collectives/README.md +++ b/mpi/collectives/README.md @@ -1,3 +1,9 @@ + + ## Collective operations In this exercise we test different routines for collective communication. diff --git a/mpi/collectives/skeleton.py b/mpi/collectives/skeleton.py index dc209d7..25ed149 100644 --- a/mpi/collectives/skeleton.py +++ b/mpi/collectives/skeleton.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from mpi4py import MPI import numpy diff --git a/mpi/collectives/solution/collectives.py b/mpi/collectives/solution/collectives.py index 3a2b824..3e622a1 100644 --- a/mpi/collectives/solution/collectives.py +++ b/mpi/collectives/solution/collectives.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from mpi4py import MPI import numpy from sys import stdout diff --git a/mpi/heat-equation-cython/README.md b/mpi/heat-equation-cython/README.md index 2f1dd2c..7c199b9 100644 --- a/mpi/heat-equation-cython/README.md +++ b/mpi/heat-equation-cython/README.md @@ -1,3 +1,9 @@ + + ## Parallel heat equation with Cython kernel In this exercise we finalize the optimization of heat equation solver by diff --git a/mpi/heat-equation-cython/solution/evolve.pyx b/mpi/heat-equation-cython/solution/evolve.pyx index 37a32d9..7924b65 100644 --- a/mpi/heat-equation-cython/solution/evolve.pyx +++ b/mpi/heat-equation-cython/solution/evolve.pyx @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + # cython: profile=True import numpy as np diff --git a/mpi/heat-equation-cython/solution/heat-p2p.py b/mpi/heat-equation-cython/solution/heat-p2p.py index 6b99d80..6a170ad 100644 --- a/mpi/heat-equation-cython/solution/heat-p2p.py +++ b/mpi/heat-equation-cython/solution/heat-p2p.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from __future__ import print_function import numpy as np import time diff --git a/mpi/heat-equation-cython/solution/setup.py b/mpi/heat-equation-cython/solution/setup.py index 27aa5e8..26a7c26 100644 --- a/mpi/heat-equation-cython/solution/setup.py +++ b/mpi/heat-equation-cython/solution/setup.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from distutils.core import setup, Extension from Cython.Build import cythonize diff --git a/mpi/heat-equation/README.md b/mpi/heat-equation/README.md index 21e4ccc..a6eb106 100644 --- a/mpi/heat-equation/README.md +++ b/mpi/heat-equation/README.md @@ -1,3 +1,9 @@ + + ## Parallel heat equation Parallelize the [heat equation](../../numpy/heat-equation) program with MPI, diff --git a/mpi/heat-equation/domain_decomposition.png.license b/mpi/heat-equation/domain_decomposition.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/mpi/heat-equation/domain_decomposition.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/mpi/heat-equation/skeleton.py b/mpi/heat-equation/skeleton.py index de2ffce..8b0e3a4 100644 --- a/mpi/heat-equation/skeleton.py +++ b/mpi/heat-equation/skeleton.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from __future__ import print_function import numpy as np import time diff --git a/mpi/heat-equation/solution/heat-p2p.py b/mpi/heat-equation/solution/heat-p2p.py index ed6a5cd..04ce1d4 100644 --- a/mpi/heat-equation/solution/heat-p2p.py +++ b/mpi/heat-equation/solution/heat-p2p.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from __future__ import print_function import numpy as np import time diff --git a/mpi/hello-world/README.md b/mpi/hello-world/README.md index 270348d..c3c3049 100644 --- a/mpi/hello-world/README.md +++ b/mpi/hello-world/README.md @@ -1,3 +1,9 @@ + + ## Hello world Write a parallel Python program using MPI that prints out the number of diff --git a/mpi/hello-world/solution/hello-world.py b/mpi/hello-world/solution/hello-world.py index af85f23..db6931a 100644 --- a/mpi/hello-world/solution/hello-world.py +++ b/mpi/hello-world/solution/hello-world.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from mpi4py import MPI comm = MPI.COMM_WORLD diff --git a/mpi/message-chain/README.md b/mpi/message-chain/README.md index c72b606..2edeb35 100644 --- a/mpi/message-chain/README.md +++ b/mpi/message-chain/README.md @@ -1,3 +1,9 @@ + + ## Message chain Write a simple program where every MPI task sends data to the next one. Let diff --git a/mpi/message-chain/solution/msg-chain.py b/mpi/message-chain/solution/msg-chain.py index 99207e5..3159eb5 100644 --- a/mpi/message-chain/solution/msg-chain.py +++ b/mpi/message-chain/solution/msg-chain.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from mpi4py import MPI import numpy from sys import stdout diff --git a/mpi/message-exchange/README.md b/mpi/message-exchange/README.md index 85159f5..a666b1d 100644 --- a/mpi/message-exchange/README.md +++ b/mpi/message-exchange/README.md @@ -1,3 +1,9 @@ + + ## Simple message exchange ### Communicating general Python objects diff --git a/mpi/message-exchange/solution/msg-exchange.py b/mpi/message-exchange/solution/msg-exchange.py index b418e4e..b71bf9d 100644 --- a/mpi/message-exchange/solution/msg-exchange.py +++ b/mpi/message-exchange/solution/msg-exchange.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from mpi4py import MPI import numpy diff --git a/mpi/non-blocking/README.md b/mpi/non-blocking/README.md index 5222b1b..6409357 100644 --- a/mpi/non-blocking/README.md +++ b/mpi/non-blocking/README.md @@ -1,3 +1,9 @@ + + ## Non-blocking communication Go back to the [Message chain](../message-chain) exercise and implement it diff --git a/mpi/non-blocking/solution/heat.py b/mpi/non-blocking/solution/heat.py index e994300..9fd421f 100644 --- a/mpi/non-blocking/solution/heat.py +++ b/mpi/non-blocking/solution/heat.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from __future__ import print_function import numpy as np import time diff --git a/mpi/non-blocking/solution/msg-chain.py b/mpi/non-blocking/solution/msg-chain.py index 15c6902..1b26243 100644 --- a/mpi/non-blocking/solution/msg-chain.py +++ b/mpi/non-blocking/solution/msg-chain.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from mpi4py import MPI import numpy from sys import stdout diff --git a/multiprocessing/data-sharing/solution/data-manager.py b/multiprocessing/data-sharing/solution/data-manager.py index d8535fc..6a3f98f 100644 --- a/multiprocessing/data-sharing/solution/data-manager.py +++ b/multiprocessing/data-sharing/solution/data-manager.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from multiprocessing import Process, Manager def squared(a, i): diff --git a/multiprocessing/data-sharing/solution/shared-memory.py b/multiprocessing/data-sharing/solution/shared-memory.py index b95d0f3..697f941 100644 --- a/multiprocessing/data-sharing/solution/shared-memory.py +++ b/multiprocessing/data-sharing/solution/shared-memory.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from multiprocessing import Process, Array def squared(a, i): diff --git a/multiprocessing/pipes/count-w.py b/multiprocessing/pipes/count-w.py index f9847a0..7c7da0c 100644 --- a/multiprocessing/pipes/count-w.py +++ b/multiprocessing/pipes/count-w.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from multiprocessing import Process, Pipe from fasta import Fasta diff --git a/multiprocessing/pipes/fasta.py b/multiprocessing/pipes/fasta.py index f1fef51..d9c00fd 100644 --- a/multiprocessing/pipes/fasta.py +++ b/multiprocessing/pipes/fasta.py @@ -1,4 +1,9 @@ #!/usr/bin/python + +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + # -*- coding: ISO-8859-1 -*- """ Simple parser for Fasta sequence files. diff --git a/multiprocessing/simple-calculation/README.md b/multiprocessing/simple-calculation/README.md index f5f1466..3552a36 100644 --- a/multiprocessing/simple-calculation/README.md +++ b/multiprocessing/simple-calculation/README.md @@ -1,3 +1,9 @@ + + ## Simple calculation Calculate the square of all numbers 1...10 using a separate `Process` to diff --git a/multiprocessing/simple-calculation/solution/square.py b/multiprocessing/simple-calculation/solution/square.py index def86f0..36f1d98 100644 --- a/multiprocessing/simple-calculation/solution/square.py +++ b/multiprocessing/simple-calculation/solution/square.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from multiprocessing import Process def squared(x): diff --git a/multiprocessing/work-distribution/README.md b/multiprocessing/work-distribution/README.md index 6268d26..df3fb29 100644 --- a/multiprocessing/work-distribution/README.md +++ b/multiprocessing/work-distribution/README.md @@ -1,3 +1,9 @@ + + ## Work distribution Read the atom coordinates of the Zika virus [5ire.pdb](5ire.pdb) using the diff --git a/multiprocessing/work-distribution/center-of-coords.py b/multiprocessing/work-distribution/center-of-coords.py index 2cfe22a..21ce634 100644 --- a/multiprocessing/work-distribution/center-of-coords.py +++ b/multiprocessing/work-distribution/center-of-coords.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from multiprocessing import Pool, Queue, Process from pdb import PDB from numpy import array diff --git a/multiprocessing/work-distribution/pdb.py b/multiprocessing/work-distribution/pdb.py index abdce83..d4d7e5a 100644 --- a/multiprocessing/work-distribution/pdb.py +++ b/multiprocessing/work-distribution/pdb.py @@ -1,4 +1,9 @@ #!/usr/bin/python + +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + # -*- coding: ISO-8859-1 -*- """ Simple parser for reading atoms from a PDB file. diff --git a/multiprocessing/work-distribution/solution/pool-of-workers.py b/multiprocessing/work-distribution/solution/pool-of-workers.py index e7e2378..f2d5f15 100644 --- a/multiprocessing/work-distribution/solution/pool-of-workers.py +++ b/multiprocessing/work-distribution/solution/pool-of-workers.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from multiprocessing import Pool, Queue, Process from pdb import PDB from numpy import array diff --git a/multiprocessing/work-distribution/solution/task-queue.py b/multiprocessing/work-distribution/solution/task-queue.py index a453abe..aaef53f 100644 --- a/multiprocessing/work-distribution/solution/task-queue.py +++ b/multiprocessing/work-distribution/solution/task-queue.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from multiprocessing import Pool, Queue, Process from pdb import PDB from numpy import array diff --git a/numpy/advanced-indexing/README.md b/numpy/advanced-indexing/README.md index 28a8fb6..2a334db 100644 --- a/numpy/advanced-indexing/README.md +++ b/numpy/advanced-indexing/README.md @@ -1,3 +1,9 @@ + + ## Advanced indexing Start with 10x10 array of uniformly distribute random numbers diff --git a/numpy/advanced-indexing/solution/index-mask.py b/numpy/advanced-indexing/solution/index-mask.py index 7238a7f..b97aae8 100644 --- a/numpy/advanced-indexing/solution/index-mask.py +++ b/numpy/advanced-indexing/solution/index-mask.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np arr = np.random.random(size=(10,10)) diff --git a/numpy/array-creation/README.md b/numpy/array-creation/README.md index 31c4c5f..99bc2f1 100644 --- a/numpy/array-creation/README.md +++ b/numpy/array-creation/README.md @@ -1,3 +1,9 @@ + + ## Array creation 1. Start from a Python list containing both integers and floating point values, diff --git a/numpy/array-creation/solution/create-array.py b/numpy/array-creation/solution/create-array.py index c611203..dcafe33 100644 --- a/numpy/array-creation/solution/create-array.py +++ b/numpy/array-creation/solution/create-array.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np a = [4, 6, 21.12, 11, 0.23] diff --git a/numpy/array-slicing/README.md b/numpy/array-slicing/README.md index c0a150d..f9c390e 100644 --- a/numpy/array-slicing/README.md +++ b/numpy/array-slicing/README.md @@ -1,3 +1,9 @@ + + ## Array slicing First, create a 4x4 array with arbitrary values, then diff --git a/numpy/array-slicing/solution/slice-2d.py b/numpy/array-slicing/solution/slice-2d.py index d9072bc..55ae2c2 100644 --- a/numpy/array-slicing/solution/slice-2d.py +++ b/numpy/array-slicing/solution/slice-2d.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np my_list = [[1.1, 1.2, 1.3, 1.4], diff --git a/numpy/broadcast-rotation/README.md b/numpy/broadcast-rotation/README.md index c043e6e..806aadb 100644 --- a/numpy/broadcast-rotation/README.md +++ b/numpy/broadcast-rotation/README.md @@ -1,3 +1,9 @@ + + ## Rotation with broadcasting Two dimensional coordinates can be rotated by my multiplying the 2-element diff --git a/numpy/broadcast-rotation/solution/rotate.py b/numpy/broadcast-rotation/solution/rotate.py index 6fec195..0b369f8 100644 --- a/numpy/broadcast-rotation/solution/rotate.py +++ b/numpy/broadcast-rotation/solution/rotate.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np from math import sin, cos, pi import numpy.ma as ma diff --git a/numpy/broadcast-translation/README.md b/numpy/broadcast-translation/README.md index 4a60aac..d28c386 100644 --- a/numpy/broadcast-translation/README.md +++ b/numpy/broadcast-translation/README.md @@ -1,3 +1,9 @@ + + ## Translation with broadcasting NumPy broadcasting is powerful tool for dealing with different, but compatible diff --git a/numpy/broadcast-translation/solution/translate.py b/numpy/broadcast-translation/solution/translate.py index 28d7ab1..18aafeb 100644 --- a/numpy/broadcast-translation/solution/translate.py +++ b/numpy/broadcast-translation/solution/translate.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np import matplotlib.pyplot as plt diff --git a/numpy/dna-mutation/README.md b/numpy/dna-mutation/README.md index 72f7149..e1d46da 100644 --- a/numpy/dna-mutation/README.md +++ b/numpy/dna-mutation/README.md @@ -1,3 +1,9 @@ + + ## Mutating DNA sequence with NumPy Create a NumPy character array representing a DNA sequence. diff --git a/numpy/dna-mutation/skeleton.py b/numpy/dna-mutation/skeleton.py index b6917fe..59a6f3c 100644 --- a/numpy/dna-mutation/skeleton.py +++ b/numpy/dna-mutation/skeleton.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np # Generate N element long random character array from given alphabet diff --git a/numpy/dna-mutation/solution/mutate.py b/numpy/dna-mutation/solution/mutate.py index e5e9f26..d2ce8f9 100644 --- a/numpy/dna-mutation/solution/mutate.py +++ b/numpy/dna-mutation/solution/mutate.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np # Generate N element long random character array from given alphabet diff --git a/numpy/finite-difference/README.md b/numpy/finite-difference/README.md index 777ab47..9d9096c 100644 --- a/numpy/finite-difference/README.md +++ b/numpy/finite-difference/README.md @@ -1,3 +1,9 @@ + + ## Finite-difference Vectorization is crucial for obtaining good performance with NumPy. diff --git a/numpy/finite-difference/solution/finite-difference.py b/numpy/finite-difference/solution/finite-difference.py index b34721e..d686155 100644 --- a/numpy/finite-difference/solution/finite-difference.py +++ b/numpy/finite-difference/solution/finite-difference.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np import matplotlib.pyplot as plt diff --git a/numpy/game-of-life/README.md b/numpy/game-of-life/README.md index d3f3e35..2a5608b 100644 --- a/numpy/game-of-life/README.md +++ b/numpy/game-of-life/README.md @@ -1,3 +1,9 @@ + + ## Game of Life [Game of Life](http://en.wikipedia.org/wiki/Conway's_Game_of_Life) is a diff --git a/numpy/game-of-life/gol_initial.png.license b/numpy/game-of-life/gol_initial.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/numpy/game-of-life/gol_initial.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/numpy/game-of-life/solution/game-of-life.py b/numpy/game-of-life/solution/game-of-life.py index 67b8774..41ebc71 100644 --- a/numpy/game-of-life/solution/game-of-life.py +++ b/numpy/game-of-life/solution/game-of-life.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from optparse import OptionParser import numpy as np import matplotlib.pyplot as plt diff --git a/numpy/heat-equation/README.md b/numpy/heat-equation/README.md index 96b30be..2f704ef 100644 --- a/numpy/heat-equation/README.md +++ b/numpy/heat-equation/README.md @@ -1,3 +1,9 @@ + + ## Two dimensional heat equation Heat (or diffusion) equation is diff --git a/numpy/heat-equation/heat.py b/numpy/heat-equation/heat.py index 95f1038..c2db33a 100644 --- a/numpy/heat-equation/heat.py +++ b/numpy/heat-equation/heat.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np import time diff --git a/numpy/heat-equation/heat_main.py b/numpy/heat-equation/heat_main.py index b129e5c..d51d915 100644 --- a/numpy/heat-equation/heat_main.py +++ b/numpy/heat-equation/heat_main.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from __future__ import print_function import time import argparse diff --git a/numpy/heat-equation/solution/heat.py b/numpy/heat-equation/solution/heat.py index 754558f..944ad8c 100644 --- a/numpy/heat-equation/solution/heat.py +++ b/numpy/heat-equation/solution/heat.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np import matplotlib matplotlib.use('Agg') diff --git a/numpy/heat-equation/solution/heat_main.py b/numpy/heat-equation/solution/heat_main.py index b129e5c..d51d915 100644 --- a/numpy/heat-equation/solution/heat_main.py +++ b/numpy/heat-equation/solution/heat_main.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from __future__ import print_function import time import argparse diff --git a/numpy/img/finite-difference.png.license b/numpy/img/finite-difference.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/numpy/img/finite-difference.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/numpy/img/heat-equation.png.license b/numpy/img/heat-equation.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/numpy/img/heat-equation.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/numpy/img/heat-stability.png.license b/numpy/img/heat-stability.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/numpy/img/heat-stability.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/numpy/img/heat-time-propagation.png.license b/numpy/img/heat-time-propagation.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/numpy/img/heat-time-propagation.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/numpy/img/nabla.png.license b/numpy/img/nabla.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/numpy/img/nabla.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/numpy/img/rieman-sum1.png.license b/numpy/img/rieman-sum1.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/numpy/img/rieman-sum1.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/numpy/img/rieman-sum2.png.license b/numpy/img/rieman-sum2.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/numpy/img/rieman-sum2.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/numpy/img/rotation-matrix.png.license b/numpy/img/rotation-matrix.png.license new file mode 100644 index 0000000..eb89bb6 --- /dev/null +++ b/numpy/img/rotation-matrix.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. + +SPDX-License-Identifier: CC-BY-NC-SA-4.0 diff --git a/numpy/input-output/README.md b/numpy/input-output/README.md index 0f93360..506dda7 100644 --- a/numpy/input-output/README.md +++ b/numpy/input-output/README.md @@ -1,3 +1,9 @@ + + ## Input and output File [xy-coordinates.dat](xy-coordinates.dat) contains a list of (x,y) value diff --git a/numpy/input-output/solution/input-output.py b/numpy/input-output/solution/input-output.py index 948248d..093c910 100644 --- a/numpy/input-output/solution/input-output.py +++ b/numpy/input-output/solution/input-output.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np import sys diff --git a/numpy/integration/README.md b/numpy/integration/README.md index 857f76e..2b6ee20 100644 --- a/numpy/integration/README.md +++ b/numpy/integration/README.md @@ -1,3 +1,9 @@ + + ## Numerical integration A simple method for evaluating integrals numerically is by the middle Riemann diff --git a/numpy/integration/solution/riemann-sum.py b/numpy/integration/solution/riemann-sum.py index 512e4f0..35b481d 100644 --- a/numpy/integration/solution/riemann-sum.py +++ b/numpy/integration/solution/riemann-sum.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np # Construct xi diff --git a/numpy/linear-algebra/README.md b/numpy/linear-algebra/README.md index ce23f94..18611f4 100644 --- a/numpy/linear-algebra/README.md +++ b/numpy/linear-algebra/README.md @@ -1,3 +1,9 @@ + + ## Linear algebra 1. Construct two symmetric 2x2 matrices **A** and **B**. diff --git a/numpy/linear-algebra/solution/matrix-product.py b/numpy/linear-algebra/solution/matrix-product.py index 62cfaff..819eb4c 100644 --- a/numpy/linear-algebra/solution/matrix-product.py +++ b/numpy/linear-algebra/solution/matrix-product.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np A = np.random.random((2,2)) diff --git a/numpy/masked-array/README.md b/numpy/masked-array/README.md index e7f13f3..fb854f5 100644 --- a/numpy/masked-array/README.md +++ b/numpy/masked-array/README.md @@ -1,3 +1,9 @@ + + ## Masked arrays File [faulty_data.dat](faulty_data.dat) contains x, y data which should follow diff --git a/numpy/masked-array/solution/faulty-data.py b/numpy/masked-array/solution/faulty-data.py index deeb185..6e67a44 100644 --- a/numpy/masked-array/solution/faulty-data.py +++ b/numpy/masked-array/solution/faulty-data.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np import numpy.ma as ma import matplotlib.pyplot as plt diff --git a/numpy/numexpr/README.md b/numpy/numexpr/README.md index 3a66529..8fb2563 100644 --- a/numpy/numexpr/README.md +++ b/numpy/numexpr/README.md @@ -1,3 +1,9 @@ + + ## Numexpr Try different array expressions and investigate how much **numexpr** can speed diff --git a/numpy/polynomials/README.md b/numpy/polynomials/README.md index d51a07c..4f87d87 100644 --- a/numpy/polynomials/README.md +++ b/numpy/polynomials/README.md @@ -1,3 +1,9 @@ + + ## Polynomials Fit a second order polynomial to the data of previous exercises by using diff --git a/numpy/polynomials/solution/fit.py b/numpy/polynomials/solution/fit.py index 12f7d79..092db4f 100644 --- a/numpy/polynomials/solution/fit.py +++ b/numpy/polynomials/solution/fit.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np import matplotlib.pyplot as plt import sys diff --git a/numpy/random-numbers/README.md b/numpy/random-numbers/README.md index 9d08f9b..d05b5c4 100644 --- a/numpy/random-numbers/README.md +++ b/numpy/random-numbers/README.md @@ -1,3 +1,9 @@ + + ## Random numbers Generate a one dimensional 1000 element array of uniformly distributed random diff --git a/numpy/random-numbers/solution/uniform-normal.py b/numpy/random-numbers/solution/uniform-normal.py index 9dfcc2f..21656b1 100644 --- a/numpy/random-numbers/solution/uniform-normal.py +++ b/numpy/random-numbers/solution/uniform-normal.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np import matplotlib.pyplot as plt diff --git a/numpy/reference-copy/README.md b/numpy/reference-copy/README.md index c2bfe2f..9fe0368 100644 --- a/numpy/reference-copy/README.md +++ b/numpy/reference-copy/README.md @@ -1,3 +1,9 @@ + + Investigate the behavior of the statements below by looking at the values of the arrays a and b after assignments: diff --git a/numpy/split-combine/README.md b/numpy/split-combine/README.md index 7c65974..8422c5f 100644 --- a/numpy/split-combine/README.md +++ b/numpy/split-combine/README.md @@ -1,3 +1,9 @@ + + ## Split and combine arrays Create a new 8x8 array with some values (or continue with the one created in diff --git a/numpy/split-combine/solution/split-combine.py b/numpy/split-combine/solution/split-combine.py index f2dc377..e3ae91d 100644 --- a/numpy/split-combine/solution/split-combine.py +++ b/numpy/split-combine/solution/split-combine.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np my_list = [[j +1 + (i + 1) / 10 for i in range(8)] for j in range(8)] diff --git a/numpy/subdiagonal-matrix/README.md b/numpy/subdiagonal-matrix/README.md index ce32ea2..a35d6f4 100644 --- a/numpy/subdiagonal-matrix/README.md +++ b/numpy/subdiagonal-matrix/README.md @@ -1,3 +1,9 @@ + + ## Subdiagonal matrix Create a 6x6 matrix with 1’s above and below the diagonal and zeros diff --git a/numpy/subdiagonal-matrix/solution/subdiagonal.py b/numpy/subdiagonal-matrix/solution/subdiagonal.py index ccac093..866d9c0 100644 --- a/numpy/subdiagonal-matrix/solution/subdiagonal.py +++ b/numpy/subdiagonal-matrix/solution/subdiagonal.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np mat = np.eye(6, k=1) + np.eye(6, k=-1) diff --git a/numpy/temporary-arrays/README.md b/numpy/temporary-arrays/README.md index c68729b..1dcd945 100644 --- a/numpy/temporary-arrays/README.md +++ b/numpy/temporary-arrays/README.md @@ -1,3 +1,9 @@ + + ## Temporary arrays Try different NumPy array expressions and investigate how much memory is used diff --git a/performance/cprofile/README.md b/performance/cprofile/README.md index 34df473..29741ce 100644 --- a/performance/cprofile/README.md +++ b/performance/cprofile/README.md @@ -1,3 +1,9 @@ + + ## Using cProfile In this exercise we analyze the performance of heat equation solver with cProfile. diff --git a/performance/cprofile/heat.py b/performance/cprofile/heat.py index cd6a03d..1e4abbd 100644 --- a/performance/cprofile/heat.py +++ b/performance/cprofile/heat.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + import numpy as np import matplotlib matplotlib.use('Agg') diff --git a/performance/cprofile/heat_main.py b/performance/cprofile/heat_main.py index b129e5c..d51d915 100644 --- a/performance/cprofile/heat_main.py +++ b/performance/cprofile/heat_main.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from __future__ import print_function import time import argparse diff --git a/test/test.py b/test/test.py index 6ee0931..921b48b 100644 --- a/test/test.py +++ b/test/test.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 CSC - IT Center for Science Ltd. +# +# SPDX-License-Identifier: MIT + from importlib import import_module fail = False