diff --git a/README.md b/README.md index 50bf120d0770dcfc9bcf4bddf0c618f56dfa11d9..5097ee69a535db0361a722bbb9e0627e806b79d3 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,184 @@ -# CS-206 Parallelism and Concurrency 2020 +This repository will be used as the website for Parallelism and Concurrency CS-206. It will be updated weekly throughout the semester. This README contains general information about the class. +- [previous-exams](previous-exams) contains PDFs for the previous exams. +- [exercises](exercises) contains markdown documents for exercises and solutions. +- [slides](slides) contains the slides presented in class. +- [labs](labs) contains markdown documents for the labs. + +We will use GitLab's issue tracker as a discussion forum. Feel free to [open an issue](https://gitlab.epfl.ch/lamp/cs206/issues) if you have any comments or questions. + +# First-week tasks + +1. Join [the Discord](https://discord.gg/hJsreTeZjc) +1. Log into gitlab: https://gitlab.epfl.ch/users/sign_in +1. Please fill in [this table](https://docs.google.com/spreadsheets/d/1rcq_UMgR6bAH-iK1L2I6WoClZtCqUoIOLqQO3NJKdgg) with your GASPAR and SCIPER number + * Choose the group for the exercises + * This will initialize your GitLab repository for the course +1. Follow the [Tools Setup](labs/tools-setup.md) page. +1. Do the [example lab](labs/example-lab.md). +1. Watch all videos under *Parallelism 1: Introduction to Parallel Programming* below +1. Do the [first graded lab](labs/lab1-parallel-box-blur-filter/). + +# Grading + +The grading of the course is divided between exercies (5%), labs (25%), midterm exam (30%) and final exam (40%). + +# Staff + +| Role | People | +| :--- | :--- | +| Professors | [Martin Odersky](https://people.epfl.ch/martin.odersky), [Viktor KunÄak](https://people.epfl.ch/viktor.kuncak) | +| TAs | [Aleksander Boruch-Gruszecki](https://people.epfl.ch/aleksander.boruch-gruszecki), [Dragana Milovancevic](https://people.epfl.ch/dragana.milovancevic), [Guillaume Martres](https://people.epfl.ch/guillaume.martres), [Nicolas Stucki](https://people.epfl.ch/nicolas.stucki), [Olivier Blanvillain](https://people.epfl.ch/olivier.blanvillain) | +| Student TAs | [Antoine Masanet](https://people.epfl.ch/antoine.masanet), [Lucas Giordano](https://people.epfl.ch/lucas.giordano), [Kajetan Pyszkowski](https://people.epfl.ch/kajetan.pyszkowski), [Marco Vögeli](https://people.epfl.ch/marco.vogeli), [Quentin Guignard](https://people.epfl.ch/quentin.guignard), [Sara Djambazovska](https://people.epfl.ch/sara.djambazovska) | + +# Course Schedule + +Lectures are partially live (on Zoom) and partially prerecorded (on YouTube). +Live sessions will be held on Wednesdays from 14:15 to 16:00. +Weekly Discord sessions will be held on Wednesdays from 14:15 to 16:00 for exercises (if it is a week with exercises) and 16:15 to 18:00 for labs. +You should watch the prerecorded lectures before doing the exercies. +In the first week of the semester, there will be a live Zoom session on Wednesday at 14:15 to welcome you to the class and answer questions you might have, followed by a Discord session. + +<!-- seq 0 7 100 | xargs -i date -d "02/24/2021 {} days" +"%d.%m.%Y" --> + +| Week | Date | Topic | Lectures (14:15-16:00) | Exercises (14:15-16:00) | Labs (16:15-18:00) | +| :-- | :-- | :-- | :-- | :-- | :-- | +| 1 | 24.02.21 | Parallelism 1 | Prerecorded | Welcome Zoom session | Lab 1 | +| 2 | 03.03.21 | Parallelism 2 | Prerecorded | Exercise 1 | Lab 1 & 2 | +| 3 | 10.03.21 | Parallelism 3 | Prerecorded | Exercise 2 | Lab 2 & 3 | +| 4 | 17.03.21 | Parallelism 4 | Prerecorded | Exercise 3 | Lab 3 & 4 | +| 5 | 24.03.21 | Concurrency 1 | Live | | Lab 4 & 5 | +| 6 | 31.03.21 | Concurrency 2 | Live | | Lab 5 & 6 | +| 7 | 07.04.21 | _Easter_ | | | | +| 8 | 14.04.21 | **Midterm Exam** | | | | +| 9 | 21.04.21 | Concurrency 3 | Live | | Lab 6 | +| 10 | 28.04.21 | Actors 1 | Prerecorded | Exercise 4 | Lab 7 | +| 11 | 05.05.21 | Actors 2 | Prerecorded | Exercise 5 | Lab 7 | +| 12 | 12.05.21 | Spark 1 | Prerecorded | Exercise 6 | Lab 8 | +| 13 | 19.05.21 | Spark 2 | Prerecorded | Exercise 7 | Lab 8 & 9 | +| 14 | 26.05.21 | Spark 3 | Prerecorded | Exercise 8 | Lab 9 | +| 15 | 02.06.21 | **Final Exam** | | | | + +Solutions to the exercises are released after each deadline. We do not provide solutions for the labs. + +Before each Discord session, students should watch videos corresponding to that week's topic: + +### Parallelism 1: Introduction to Parallel Programming + +- [Introduction to Parallel Computing](https://www.youtube.com/watch?v=94O72nyNFY0) +- [Parallelism on the JVM I](https://www.youtube.com/watch?v=I8w-q1TPtjA) +- [Parallelism on the JVM II](https://www.youtube.com/watch?v=BbVWGWTNAXw) +- [Running Computations in Parallel](https://www.youtube.com/watch?v=KkMZGJ3M2-o) +- [Monte Carlo Method to Estimate Pi](https://www.youtube.com/watch?v=VBCf-aTgpPU) +- [First-Class Tasks](https://www.youtube.com/watch?v=mrVVaXCuhBc) +- [How Fast are Parallel Programs?](https://www.youtube.com/watch?v=Lpnexp_Qxgo) +- [Benchmarking Parallel Programs](https://www.youtube.com/watch?v=LvS_kjCssfg) + +### Parallelism 2: Basic Task Parallel Algorithms + +- [Parallel Sorting](https://www.youtube.com/watch?v=AcuvVgQbphg) +- [Data Operations and Parallel Mapping](https://www.youtube.com/watch?v=ghYtMLrphZw) +- [Parallel Fold (Reduce) Operation](https://www.youtube.com/watch?v=hEBgyhIoWww) +- [Associativity I](https://www.youtube.com/watch?v=q-Cl3whISCY) +- [Associativity II](https://www.youtube.com/watch?v=XBjqYavDUB8) +- [Parallel Scan (Prefix Sum) Operation](https://www.youtube.com/watch?v=CYr3YaQiMwo) + +### Parallelism 3: Data-Parallelism + +- [Data-Parallel Programming](https://www.youtube.com/watch?v=WW7TabCiOV8) +- [Data-Parallel Operations I](https://www.youtube.com/watch?v=Vd35YQ8DEO4) +- [Data-Parallel Operations II](https://www.youtube.com/watch?v=dcMgKtuAh3s) +- [Scala Parallel Operations](https://www.youtube.com/watch?v=NjkxjAT7ohE) +- [Splitters and Combiners](https://www.youtube.com/watch?v=Redz85Nlle4) + +### Parallelism 4: Data-Structures for Parallel Computing + +- [Implementing Combiners](https://www.youtube.com/watch?v=dTP0ntniB2I) +- [Parallel Two-phase Construction](https://www.youtube.com/watch?v=XcMtq3OdjQ0) +- [Conc-Tree Data Structure](https://www.youtube.com/watch?v=cUXHXKL8Xvs) +- [Amortized, Constant-Time Append Operation](https://www.youtube.com/watch?v=Ic5DUZLITVI) +- [Conc-Tree Combiners](https://www.youtube.com/watch?v=aLfFlCC1vjc) + +### Concurrency 1, 2 & 3 + +- Live lectures + +### Actors 1 + +- [Introduction: why actors?](https://www.youtube.com/watch?v=ZQAe9AItH8o) +- [The Actor Model](https://www.youtube.com/watch?v=c49tDZuFtPA) + +### Actors 2 + +- [Message Processing Semantics](https://www.youtube.com/watch?v=Uxn1eg6R0Fc) +- [Designing Actor Systems](https://www.youtube.com/watch?v=uxeMJLo3h9k) +- [Testing Actor Systems](https://www.youtube.com/watch?v=T_2nwLr-H2s) + +### Spark 1: Spark Basics + +- [From Parallel to Distributed](https://www.youtube.com/watch?v=bfMbJ8NzTZI) +- [Latency](https://www.youtube.com/watch?v=igNIz2Ent5E) +- [RDDs, Spark's Distributed Collection](https://www.youtube.com/watch?v=EuVmW62aIXI) +- [RDDs: Transformations and Actions](https://www.youtube.com/watch?v=qJlfATheS38) +- [Evaluation in Spark: Unlike Scala Collections!](https://www.youtube.com/watch?v=0pVYuuUrN74) +- [Cluster Topology Matters](https://www.youtube.com/watch?v=lS4vRzwrmtU) + +### Spark 2: Reduction Operations & Distributed Key-Value Pairs + +- [Reduction Operations](https://www.youtube.com/watch?v=JhF0_Ka_iqU) +- [Pair RDDs](https://www.youtube.com/watch?v=kIUzgweDMUs) +- [Transformations and Actions on Pair RDDs](https://www.youtube.com/watch?v=ovf0GFbnp5g) +- [Joins](https://www.youtube.com/watch?v=kYpaZpj4qTM) + +### Spark 3: Partitioning and Shuffling + +- [Shuffling: What it is and Why it's important](https://www.youtube.com/watch?v=LrgA4PrKrks) +- [Partitioning](https://www.youtube.com/watch?v=sTcki6mxjcA) +- [Optimizing with Partitioners](https://www.youtube.com/watch?v=4Vfp5kp2jnE) +- [Wide vs Narrow Dependencies](https://www.youtube.com/watch?v=L9BnaYp10c8) + + +# Labs + +Labs are individual assignments where you get to write Scala programs using the concepts learned during lectures. +Labs are submitted by pushing your code on GitLab, see details in the [grading and submission](labs/grading-and-submission.md) page. + +| Labs | Name | Start date | Due date (23:59 [AoE](https://en.wikipedia.org/wiki/Anywhere_on_Earth)) | +| :-- | :-- | :-- | :-- | +| Lab 1 | Parallel Box Blur Filter | 22.02.21 | 07.03.2021 | +| Lab 2 | Reductions and Prefix Sums | 01.03.21 | 14.03.2021 | +| Lab 3 | K-Means | 08.03.21 | 21.03.2021 | +| Lab 4 | Barnes-Hut Simulation | 15.03.21 | 28.03.2021 | +| Lab 5 | Bounded Buffer | 22.03.21 | 04.04.2021 | +| Lab 6 | Lock-free Sorted List | 29.03.21 | 25.04.2021 | +| Lab 7 | Actors Binary Tree | 26.04.21 | 09.05.2021 | +| Lab 8 | Wikipedia | 10.05.21 | 23.05.2021 | +| Lab 9 | StackOverflow | 17.05.21 | 30.05.2021 | + +# Exercises + +Exercises are pen and paper style questions that will help you consolidate the knowledge learned during lectures. +Exercises should be done in groups and submitted on GitLab. +You should form groups of up to five students for each exercise, solve the exercise remotely with your group (using Discord, Hangouts, Zoom, ...), and write your solutions in a text file. +The first line of your solution file should list all the group members' SCIPER numbers. +After you solve the exercise with your group, each member should submit a copy of this file to their GitLab repository following the instructions given in the problem statement. +Exercises will be given a participation grade at the end of the semester, which accounts for 5% of the overall course grade. + +| Exercises | Start date | Due date (23:59 [AoE](https://en.wikipedia.org/wiki/Anywhere_on_Earth)) | +| :-- | :-- | :-- | +| Exercise 1 | 01.03.2021 | 07.03.2021 | +| Exercise 2 | 08.03.2021 | 14.03.2021 | +| Exercise 3 | 15.03.2021 | 21.03.2021 | +| Exercise 4 | 26.04.2021 | 02.05.2021 | +| Exercise 5 | 03.05.2021 | 09.05.2021 | +| Exercise 6 | 10.05.2021 | 16.05.2021 | +| Exercise 7 | 17.05.2021 | 23.05.2021 | +| Exercise 8 | 24.05.2021 | 30.05.2021 | + +# Exams + +The midterm exam will take place on 14.04.21. The midterm exam will cover all the material seen in the class up to week 6 (included). + +The final exam will take place on 02.06.21. The final exam will cover all material seen during the semester. + +Information about exams organization will be communicated by email. diff --git a/exercises/exercise-1.md b/exercises/exercise-1.md new file mode 100644 index 0000000000000000000000000000000000000000..0787288e47d07337d6c4aa3863cb1bb253879fb0 --- /dev/null +++ b/exercises/exercise-1.md @@ -0,0 +1,132 @@ +# Exercise 1 + +Use the following commands to make a fresh clone of your repository: + +``` +git clone -b exercise-1 git@gitlab.epfl.ch:lamp/student-repositories-s21/cs206-GASPAR.git exercise-1 +``` + +Update the README.md file with your solutions. Don't forget to list the group members' SCIPER numbers. + +# Problem 1: Introduction to Concurrency + +Freshly graduated from EPFL, you all have been hired as contractors for a successful and rapidly growing bank. The bank has recently been experiencing problems with their money management system, coded in Scala, and so they hired the best and brightest young engineers they could find: you! The system has been working perfectly fine so far, they tell you. In the past days, due to an increased number of customers, they had to switch from a single threaded sequential execution environment to a multithreaded concurrent environment, in which multiple threads may perform transactions concurrently. That's when problems started, your manager says… + +Below is the code responsible to withdraw money from the account from and transfer it to the account to, within the same bank. + +```scala +def transfer(from: Account, to: Account, amount: BigInt) { + require(amount >= 0) + + val balanceFrom = from.balance + if (balanceFrom >= amount) { + from.balance = balanceFrom - amount + val balanceTo = to.balance + to.balance = balanceTo + amount + } +} +``` + +For the bank, it is very important that the following two properties hold after any sequence of completed transfer transactions: + +1. The balance of an account never goes below 0. +2. The total sum of money held by the bank is constant. + +## Question 1 + +Does the above transfer method respect the two properties in a *sequential* execution environment, that is, when there is only one thread in the program? + +## Question 2 + +What can go wrong in a setting where multiple threads can execute the `transfer` method concurrently? For each of the two desired properties of the system, check if its holds in this concurrent environment. If not, come up with an example execution which exhibits a violation of the property. + +# Question 3 + +For each of the proposed implementations of `transfer` below, check which of the properties hold. Additionally, check if the system is vulnerable to *deadlocks*. + +Variant 1 + +```scala +def transfer(from: Account, to: Account, amount: Long): Unit = { + require(amount >= 0) + + val balanceFrom = from.balance + if (balanceFrom >= amount) { + from.synchronized { + from.balance = balanceFrom - amount + } + to.synchronized { + val balanceTo = to.balance + to.balance = balanceTo + amount + } + } +} +``` + +Variant 2 + +```scala +def transfer(from: Account, to: Account, amount: Long): Unit = { + require(amount >= 0) + + from.synchronized { + val balanceFrom = from.balance + if (balanceFrom >= amount) { + from.balance = balanceFrom - amount + to.synchronized { + val balanceTo = to.balance + to.balance = balanceTo + amount + } + } + } +} +``` + +Variant 3 + +```scala +object lock // Global object +def transfer(from: Account, to: Account, amount: Long): Unit = { + require(amount >= 0) + + lock.synchronized { + val balanceFrom = from.balance + if (balanceFrom >= amount) { + from.balance = balanceFrom - amount + val balanceTo = to.balance + to.balance = balanceTo + amount + } + } +} +``` + +# Problem 2: Parallel Reductions + +## Question 1 + +As a group, write a function called `minMax`, which should take a non-empty array as input and return a pair containing the smallest and the largest element of the array. + +```scala +def minMax(a: Array[Int]): (Int, Int) = ??? +``` + +Now write a parallel version of the function. You may use the constructs `task` and/or `parallel`, as seen in the lectures. + +## Question 2 + +Imagine that the data structure you are given, instead of an `Array[A]`, is one called `ParSeq[A]`. This class offers the two following methods, which work in parallel: + +```scala +def map[B](f: A => B): ParSeq[B] +def reduce(f: (A, A) => A): A +``` + +Can you write the following `minMax` function in terms of `map` and/or `reduce` operations ? + +```scala +def minMax(data: ParSeq[Int]): (Int, Int) = ??? +``` + +## Question 3 + +What property does the function `f` passed to reduce need to satisfy in order to have the same result regardless on how reduce groups the applications of the operation f to the elements of the data structure? Prove that your function `f` indeed satisfies that property. diff --git a/exercises/images/2-1.png b/exercises/images/2-1.png new file mode 100644 index 0000000000000000000000000000000000000000..b527b78472c6021df5f712d9806b71d0d46add33 Binary files /dev/null and b/exercises/images/2-1.png differ diff --git a/exercises/images/2-2.png b/exercises/images/2-2.png new file mode 100644 index 0000000000000000000000000000000000000000..f436cbb79777c392a4e848f7ad53de6fd840d5ad Binary files /dev/null and b/exercises/images/2-2.png differ diff --git a/exercises/images/8-1.png b/exercises/images/8-1.png new file mode 100644 index 0000000000000000000000000000000000000000..c5c61e4221053ef561d9516df0368c0f7dc09606 Binary files /dev/null and b/exercises/images/8-1.png differ diff --git a/labs/example-lab.md b/labs/example-lab.md new file mode 100644 index 0000000000000000000000000000000000000000..1ab37a2e474b970380a234f494f1ad377e92f9dc --- /dev/null +++ b/labs/example-lab.md @@ -0,0 +1,229 @@ +# Example Lab + +The goal of this assignment is to familiarize yourself with the infrastructure and tools used in this class. Even though the grade in this assignment won't influence your grade for the course, it is important that you work through this assignment carefully. + +## Part 1: Obtaining the Project Files + +First, make sure you've followed the [Tools Setup](tools-setup.md) page. + +**At this point, we strongly encourage you to take the time to read at least the first three chapters of the [Git Book](https://git-scm.com/book/en/v2). If you just copy-paste the commands we give you without understanding them, it's likely that you'll make a mistake somewhere and waste time. Git can be a huge productivity enhancer when used correctly, so it's definitely worth the investment!** + +We'll starting by cloning the repository containing all our assignment (make +sure to replace `GASPAR` with your EPFL username (the one with letters, not the +one with number) in the following command). + +```shell +git clone -b example git@gitlab.epfl.ch:lamp/student-repositories-s21/cs206-GASPAR.git cs206-example +``` + +```shell +cd cs206-example +``` + +Now that we've obtained the project, let's take a look at its structure: + +```shell +. +├── build.sbt +├── project +│  ├── ... +└── src + ├── main + │  └── scala + │  └── example + │  └── Lists.scala + └── test + └── scala + └── example + └── ListsSuite.scala +``` + +- All the files ending with `.sbt` or in the `project/` directory are build tool configuration files: you don't need to modify them or look at them for any of the assignments +- The project sources are in `src/main/scala/` +- The sources of the unit tests are in `src/test/scala/`. You will need to make all the tests pass to complete the assignments, and you should write additional tests to check for cases that our tests do not cover. + +## Part 2: Using sbt + +Start sbt by running: +```shell +sbt +``` + +Once it's finished starting (this may take a while), you'll be able to enter sbt +commands. You can compile your project using `compile` and run the tests with +`test` (this automatically compiles your code if needed to). Note that if +compilation fails, no tests will be run. The first time you'll run `test` in an +assignment you should see many errors: that's normal, your job is to make the +tests pass! To do this, it's useful to understand in details what the test +output means, here's an example: + + + +This tells us several things: + +- There's a test named `max of a few numbers (10pts)` in the class `ListsSuite` in the package `example` +- The test failed with an exception: `scala.NotImplementedError: an implementation is missing`. This is followed by a stack trace showing where the exception happened. +- This exception was thrown from the method `scala.Predef$.???` in the file `Predef.scala` at line 284. +- This method was called from `example.Lists$.max` in the file `Lists.scala` at line 40. +- ... which was itself called from the method `example.ListsSuite.max of a few + numbers` in the file `ListsSuite.scala` at line 83. + +It's now time to look at some code: the next section will show you how to start and navigate using the IDE. + +## Part 3: Using the IDE + +### Startup + +This course is run with an experimental version of Scala called Dotty that will become Scala 3 in the future. Because it's so new, most IDEs like IntelliJ and Eclipse are unlikely to work correctly with it. Thankfully we've developed our own IDE support. It's designed to work with any text editor but we currently only support VSCode. If you've followed the [Tools Setup](https://lampepfl-courses.github.io/moocs/tools-setup/Tools%20Setup.html) page you should have VSCode installed by now, but don't start it just yet, instead run the following command from `sbt`: +```shell +launchIDE +``` + +This will download the Dotty extension for VSCode and set everything up. You will need to do this for every assignment, and we recommend always using this command to start the IDE. + +The first time the IDE starts, it will take some time to download more components, as displayed in the bottom left: + + + +#### Data collection + +Fixing bugs in the compiler and the IDE is much easier when we have all the information needed to reproduce them. To help us achieve that, we've added an optional data collection mechanism in the IDE extension, when you start an assignment, you'll see the following pop-up: + + +You are free to either allow or deny the data collection, but we would appreciate it if you clicked "Allow". If you do, you'll contribute to making Scala better! If you change your mind, you can turn on or off the data collection at any time by clicking on the "Scala telemetry" button on the bottom-left of the IDE window: + + + + +### Usage + +It's now time to dig in! Earlier we talked about a failing test, the stack trace told us that it was failing on line 83 of the file ListsSuite.scala, so let's open that file: + + + +Here's the source code of the test method: + + + +This looks like a regular method except for a few things: + +- It starts with `@Test`, this is an annotation that lets JUnit (the testing framework we use) know that this is a test method. +- The name of the method starts and ends with backticks (\`): this is what allows us to put spaces in the method name. Normally, names defined in Scala cannot contain special characters such as spaces or dashes, but any character is allowed as long as backticks are put around the name (even emojis 🔥!). We've taken advantage of this in the tests we define to give them nicer names: `max of a few numbers failed` is easier to read than `maxOfAFewNumbers failed`, but this is just a convention: if you define your own tests you're free to name them however you want. + +Recall that the second line of the stack trace was: +```scala +at example.Lists$.max(Lists.scala:40) +``` + +This tells us that the crash happened when calling `max`, we can hover with our mouse over the call to `max` in the test method to get more information on it: + + + + +The hover is split into two parts: the first part is: +```scala +(xs: List[Int]): Int +``` +This means that `max` is a method that takes a `List` of `Int` as argument and +returns an `Int`. The second part is the documentation of `max`. We can jump to +the definition of max by `Ctrl+click` (`Cmd+click` on Mac) or by `right click -> +Go to Definition` (*note: this is currently broken under Windows, you'll have to +manually open `src/main/scala/example/Lists.scala`*). Once there we see: + + + +Now we know why the test failed: `max` calls `???`, which is a method defined in the Scala standard library that simply crashes your program: whenever you see it in an assignment it means that this is something you need to replace by your own implementation. + +You now know enough to be able to work with the IDE, here are some additional tips: + +- When you press `Enter` to make a new line, the IDE will automatically indent the + line if needed (for example, if the last word on the previous line was + `then`), however it will never unindent code for you (for example, when + writing `else`). You can always indent code manually by pressing `Tab` and + unindent it by pressing `Shift + Tab`. +- When working on an assignment, you are free to create as many methods, classes and objects as you want. **But you shouldn't change the name of existing methods, classes and objects, because that may break the automated grading system, this is important!**. +- You can see a list of all warnings and errors reported by the compiler by clicking on  at the bottom left of VSCode. +- The IDE can show you on hover the documentation of classes, defs and vals defined in the current project but support for external project is currently missing. To compensate for this, you can consult the documentation online: + - The documentation for the Scala standard library is at [https://www.scala-lang.org/files/archive/api/2.13.1/](https://www.scala-lang.org/files/archive/api/2.13.1/) + - The documentation for the Java standard library is at [https://docs.oracle.com/en/java/javase/11/docs/api/index.html](https://docs.oracle.com/en/java/javase/11/docs/api/index.html) +- You can customize Visual Studio Code as much as you want, including installing additional extensions, but please avoid installing other Scala-related extensions: they may conflict with the one we use for this course. +- While working on your assignment, you will regularly want to go back to the sbt console to run the tests. You could simply run the command `test` every time, but you can take advantage of the watch mode instead: if a command is prefixed by `~`, sbt will watch the source directory for changes and re-run the command every time a file is saved. So a possible workflow is: + + 1. Start sbt + 2. Run `launchIDE` + 3. Once the IDE has started, go back to sbt and run `~test` (or run `~compile` if you don't want to look at the tests) + 4. Work in the IDE, and check the output of the sbt console from time to time + +- We're actively working on improving the IDE support using Visual Studio Code + and interested in hearing your ideas and suggestions. Feel free to share your + feedback (both good and bad) with us using Gitlab issues! + +## Part 4: Running your code + +Writing code and running tests is nice, but sometimes more direct feedback is useful, like when you want to experiment with Scala, or try out some methods that you implemented. You can do this using the Scala REPL (Read/Eval/Print Loop) or with a worksheet. + +### The REPL +After having started sbt, you can start the REPL by typing `console`, you will see the following prompt: +```scala +scala> +``` +At this point you can write any Scala expression you want, for example: +```scala +scala> val l = List(3,7,2) +val l: List[Int] = List(3, 7, 2) +``` + +(If you write an expression without wrapping it in a `val` or a `def`, the REPL will give it a name for you, starting with `res`) + +```scala +scala> l.isEmpty +val res0: Boolean = false + +scala> println(res0) +false + +scala> l.tail.head +res1: Int = 7 + +scala> List().isEmpty +res2: Boolean = true +``` + +The classes of the assignment are available inside the REPL, so you can for instance import all the methods from `object Lists` and start using `max`: + +```scala +scala> import example.Lists._ +import example.Lists._ + +scala> max(List(1,3,2)) +res1: Int = 3 +``` + +You can enter a multiline expression in the REPL by using `Alt+Enter` +(`Option+Enter` on macOS) instead of `Enter`: + +```scala +scala> if 1 == 1 then + | "a" + | else + | "b" +val res0: String = a +``` + +In order to exit the Scala REPL and go back to sbt, type `Ctrl+D`. + +### The worksheet mode +A *worksheet* is a file where every line of code written in the IDE is executed and its output displayed as a comment. + +#### Creating a worksheet +Any file that ends in `.sc` is considered to be a worksheet by the IDE. Once VSCode is launched in a project, all you have to do is create a new file and save it (`Ctrl+N, Ctrl+S`) using any name as long as it ends in `.sc`. + +#### Using the worksheet mode + +Inside this file, you can type any line of code you would type in the REPL. To run the worksheet, either press the "Run this worksheet" button at the top of the file, or save the file. Each line of code will be executed one by one and its output is shown in green on the right. If your code contains an infinite loop, the worksheet will never finish running by itself, but you can cancel it by clicking the same button used to run the worksheet at the top of the file. + +**IMPORTANT**: When you run a worksheet, you should have sbt open and either `~test` or `~compile` running as recommended in Part 3, otherwise changes to other files won't be reflected in the output of your worksheet. + +## Part 5: Submitting your Solution + +[Click here to learn how to submit your assignment.](grading-and-submission.md) diff --git a/labs/grading-and-submission.md b/labs/grading-and-submission.md new file mode 100644 index 0000000000000000000000000000000000000000..d853c9ce49c35773a8ea83757f64684f9d51bf84 --- /dev/null +++ b/labs/grading-and-submission.md @@ -0,0 +1,106 @@ +# Grading and submission + +## Local tests and grading + +Each lab is shipped with two sets of tests: + * The tests defined under `src/test/scala`, these are usually incomplete: we + strongly encourage you to write additional tests to exercise every aspect of + your code. You can run these tests from `sbt` using the following command: + ```shell + test + ``` + * The **grading tests**, that we use to grade your labs, these are + provided as a "black box": you can run them but are not allowed to see their + content, to encourage you to write your own tests. You can run them from + `sbt` using the following command: + ```shell + grading:test + ``` + + Your grade is determined by the number of these tests that pass, see the + next section to see how to actually get a grade. + +(remember that you can always put `~` before an sbt command to automatically +re-run it when you save a file) + +## Committing and pushing your code + +**You need to push your code to gitlab before the deadline for the lab to +receive a grade. If you forget, your grade will be zero.** + +If you've read the first few chapters of [Git +book](https://git-scm.com/book/en/v2) as recommended, you must already be +familiar with committing and pushing, but let's go over the basics once again: + +At any point while working on an lab, you can see what changes you +haven't committed by writing: +```shell +git status +``` + +(If you get the error `Not a valid command: git`, it means you're inside sbt, +you can't run git from sbt itself, you need to open another terminal in the same +directory) + +This will display the list of files you have modified since the last commit, to +see the exact changes you made, run: +```shell +git diff +``` + +To save these changes in a commit, run: (replace `"My message"` by a message +describing the changes since the last commit, see [How to Write a Git Commit +Message](https://chris.beams.io/posts/git-commit/) for some tips on writing +good commit messages) +```shell +git commit -am "My message" +``` + +(It's good practice to commit your code regularly to document your changes) + +You can then synchronize your local git repository with the gitlab server by +first running: +```shell + git pull --no-rebase +``` + +This will merge in your local repository any change we made to the lab +(we only change labs to fix critical bugs found after it's been released, +so most of the time this will not do anything). + +Finally, you can push your changes to gitlab: +```shell +git push +``` + +Note that there are also graphical user interfaces to interact with git, for +example [VSCode has built-in git +support](https://code.visualstudio.com/docs/editor/versioncontrol#_git-support). + +Once you've pushed your code, you can see the result online by going to +`gitlab.epfl.ch/lamp/students-repositories-s21/cs206-GASPAR/pipelines` where +`GASPAR` is your username (you can also access this page from the main page of +your repository by clicking on the rocket icon on the left side of the gitlab +interface, then clicking on "Pipelines"). + + + +The grading pipeline contains two steps: + * *compile*: your code does not compile for grading if the job fail. + * *grade*: the job results in a warning if you do not get the maximum grade + (10.00/10.00) + +If a job is marked "pending", it means there are other students running jobs at +the same time and you'll have to wait a bit for your job to run. + +You can click on the `grade` job to see its output: + + + + + +Your grade is given on the line that starts with `Your overall score for this +lab is` + +**If you push to gitlab multiple times, your final grade will be based on the +last commit you pushed before the deadline.** diff --git a/labs/images/clone-url.png b/labs/images/clone-url.png new file mode 100644 index 0000000000000000000000000000000000000000..784cec1aecafc709da76a3f23bebadf7cfdc180a Binary files /dev/null and b/labs/images/clone-url.png differ diff --git a/labs/images/downloading-dls.png b/labs/images/downloading-dls.png new file mode 100644 index 0000000000000000000000000000000000000000..9c2aa05782059ed8e315a5d309c0ba813da82c1c Binary files /dev/null and b/labs/images/downloading-dls.png differ diff --git a/labs/images/gitlab-public-ssh-key.png b/labs/images/gitlab-public-ssh-key.png new file mode 100644 index 0000000000000000000000000000000000000000..f57459d9d7862d4a924a327b629583d01725932f Binary files /dev/null and b/labs/images/gitlab-public-ssh-key.png differ diff --git a/labs/images/gitlab-settings.png b/labs/images/gitlab-settings.png new file mode 100644 index 0000000000000000000000000000000000000000..1f5363204a2e91c337bb8296cc8c7efd158d9304 Binary files /dev/null and b/labs/images/gitlab-settings.png differ diff --git a/labs/images/hover.png b/labs/images/hover.png new file mode 100644 index 0000000000000000000000000000000000000000..0fa09a5e447ffe124093ecf184b8ef0e051a349a Binary files /dev/null and b/labs/images/hover.png differ diff --git a/labs/images/max-def.png b/labs/images/max-def.png new file mode 100644 index 0000000000000000000000000000000000000000..14cd64f48a65de2a539b574537204946d1f4e411 Binary files /dev/null and b/labs/images/max-def.png differ diff --git a/labs/images/open-test.png b/labs/images/open-test.png new file mode 100644 index 0000000000000000000000000000000000000000..b397b1810ff800961b051506ec5f4d5b6de75b5b Binary files /dev/null and b/labs/images/open-test.png differ diff --git a/labs/images/pipeline-details.png b/labs/images/pipeline-details.png new file mode 100644 index 0000000000000000000000000000000000000000..426346c5adbc56e96f48e572c35018fd66456371 Binary files /dev/null and b/labs/images/pipeline-details.png differ diff --git a/labs/images/pipeline-logs.png b/labs/images/pipeline-logs.png new file mode 100644 index 0000000000000000000000000000000000000000..607626e390391db912455cd95748cb07459afde2 Binary files /dev/null and b/labs/images/pipeline-logs.png differ diff --git a/labs/images/pipeline-tab.png b/labs/images/pipeline-tab.png new file mode 100644 index 0000000000000000000000000000000000000000..b2756a91a19ceb5972c00295fb8796958d1a91ae Binary files /dev/null and b/labs/images/pipeline-tab.png differ diff --git a/labs/images/sbt-test-error.png b/labs/images/sbt-test-error.png new file mode 100644 index 0000000000000000000000000000000000000000..e4c43ca9e2250f2de84e93f16d80c19131a74a72 Binary files /dev/null and b/labs/images/sbt-test-error.png differ diff --git a/labs/images/telemetry-allow.png b/labs/images/telemetry-allow.png new file mode 100644 index 0000000000000000000000000000000000000000..74ce0a6bd0cb17f5d6696d8430ccc0dc6441e3f7 Binary files /dev/null and b/labs/images/telemetry-allow.png differ diff --git a/labs/images/telemetry-status.png b/labs/images/telemetry-status.png new file mode 100644 index 0000000000000000000000000000000000000000..3163eb31cc8d5b60ce12e79a68ef00d25df9a19d Binary files /dev/null and b/labs/images/telemetry-status.png differ diff --git a/labs/images/test-source.png b/labs/images/test-source.png new file mode 100644 index 0000000000000000000000000000000000000000..3bfc84dd11ed846b3549634542ac69d972d75533 Binary files /dev/null and b/labs/images/test-source.png differ diff --git a/labs/images/warnings-errors.png b/labs/images/warnings-errors.png new file mode 100644 index 0000000000000000000000000000000000000000..be5b9d6ff528c1e1b51523217078a54b48f10399 Binary files /dev/null and b/labs/images/warnings-errors.png differ diff --git a/labs/lab1-parallel-box-blur-filter/README.md b/labs/lab1-parallel-box-blur-filter/README.md new file mode 100755 index 0000000000000000000000000000000000000000..b45bc80b16f1c940fdc83eb6f3dd3d6038643760 --- /dev/null +++ b/labs/lab1-parallel-box-blur-filter/README.md @@ -0,0 +1,324 @@ +# Parallel Box Blur Filter + +Use the following commands to make a fresh clone of your repository: + +``` +git clone -b scalashop git@gitlab.epfl.ch:lamp/student-repositories-s21/cs206-GASPAR.git cs206-scalashop +``` + +## Useful links + + * [A guide to the Scala parallel collections](https://docs.scala-lang.org/overviews/parallel-collections/overview.html) + * [The API documentation of the Scala parallel collections](https://www.javadoc.io/doc/org.scala-lang.modules/scala-parallel-collections_2.13/latest/scala/collection/index.html) + * [The API documentation of the Scala standard library](https://www.scala-lang.org/files/archive/api/2.13.1) + * [The API documentation of the Java standard library](https://docs.oracle.com/en/java/javase/13/docs/api/index.html) + +## Troubleshooting + +### Compilation fails + +If you see compilation errors even though you did not write any code yet, it means +you're not using the correct version of Java, see step 2 and 3 of the [tool setup page](https://gitlab.epfl.ch/lamp/cs206/blob/master/labs/tools-setup.md). + +### Fixing spurious errors in the IDE + +When you open the project in the IDE, you might see red lines under valid code, +to fix this problem: + +1. Delete the file `Interfaces.scala` in `src/main/scala/scalashop` +2. Open the file `package.scala` in `src/main/scala/scalashop` +3. In `package.scala`, copy-paste the content of https://gitlab.epfl.ch/lamp/cs206-2020/snippets/33/raw + **below** the line `import org.scalameter._` +4. Save the file, quit the IDE and run `launchIDE` again. + +## Setup scalashop + +In this assignment, we will implement a box blur filter, used in applications +like Adobe® PhotoShop® to blur images. +For the purposes of this assignment, a filter is an algorithm that takes an +input image and transforms it in some way into an output image. +The box blur filter outputs an image in which every pixel has an average value +of the surrounding pixels from the original image. +The box blur filter is an example of an *embarrassingly parallel* problem -- no +or very little effort is required to separate it into parallel tasks. +Every pixel of the output image can be computed independently of the other +pixels, and in parallel. + +We will proceed in four steps. First, we will implement the kernel of the box +blur filter, a method used to compute a single pixel of the output image. +Then we will implement two versions of the parallel box blur, and measure the +performance difference. +Finally, we will try out our parallel box blur implementations on real images, +using ScalaShop -- the image manipulation tool that would impress even +the Adobe® folks. + +By the time you are finished with this assignment, you will: + +- understand how the box blur filter works +- be able to recognize embarrassingly parallel problems +- know how to measure the performance of a parallel algorithm +- see how to agglomerate parallel computations into batches +- better understand how memory access patterns affect performance of parallel + algorithms + + +## Preliminaries + +Before we begin, we need to cover some basic data types and helper methods. +These utilities have already been implemented in the package object (in the file `package.scala`) for this +exercise. +First, we will use the `RGBA` type to refer to the value of an image pixel. +We will limit ourselves to 32-bit pixel depth images, so we define `RGBA` to +be equal to the 32-bit integer type: + +```scala +type RGBA = Int +``` + +Why do we call this type `RGBA`? +This is because each pixel value is composed from 4 components - red, green, +blue and alpha, where alpha denotes the amount of transparency in the +respective pixel. +These components are referred to as *channels*. +The value of each channel is at least 0 and at most 255. + +We can extract the red, green, blue and alpha channel using the following +utility methods, which use bit masking and bit shifting: + +```scala +def red(c: RGBA): Int = (0xff000000 & c) >>> 24 +def green(c: RGBA): Int = (0x00ff0000 & c) >>> 16 +def blue(c: RGBA): Int = (0x0000ff00 & c) >>> 8 +def alpha(c: RGBA): Int = (0x000000ff & c) >>> 0 +``` + +Similarly, given the values of the four channels, we can obtain the pixel value +like this: + +```scala +def rgba(r: Int, g: Int, b: Int, a: Int): RGBA = + (r << 24) | (g << 16) | (b << 8) | (a << 0) +``` + +Now that we know how to manipulate individual pixels, we can define our image +type `Img`: + +```scala +class Img(val width: Int, val height: Int) { + private val data = new Array[RGBA](width * height) + def apply(x: Int, y: Int): RGBA = data(y * width + x) + def update(x: Int, y: Int, c: RGBA): Unit = data(y * width + x) = c +} +``` + +The image is a two-dimensional entity -- to refer to a pixel in an image, we +need to specify an `x` and `y` component. +On the other hand, the underlying memory model is one-dimensional -- a single +offset value specifies the position in the array. +When we store the image into memory, we need to map between the +two-dimensional image model and the one-dimensional memory model. +We will do this by storing consecutive rows of the image one after another, as +illustrated in the following figure: + + + +Thus, the offset of a pixel at coordinates `x` and `y`, is equal to +`y * width + x`, where `width` is the number of pixels in a single row. +Although there are other mappings used in practice, we will restrict to this +simple mapping throughout the exercise. + +To ensure that the value of the `x` and `y` coordinates are confined to the +dimensions of the image, namely width and height, occasionally we have to call +the `clamp` method: + +```scala +def clamp(v: Int, min: Int, max: Int): Int +``` + +Finally, we will use the `task` construct to start parallel computations. +Every `task` construct invocation returns an object on which we can call the +`join` method. +Calling the `join` method blocks the execution of the program until the parallel +computation ends. +Below, we calculate the expression `1 + 1` in parallel to the main program: + +```scala +val computation = task { + val result = 1 + 1 + println("Done!") + result +} +println("About to wait for some heavy calculation...") +computation.join() +``` + +We now have everything we need to start implementing the parallel box filter. + + +## The Box Blur Filter Kernel + +In the first part of the assignment, we will implement the box blur filter +kernel method. +A kernel is a method that computes the resulting value of a single pixel. +The kernel method is typically computationally cheap and is not worth +parallelizing its implementation. +However, as we will later see, we can apply the same kernel method to different +pixels in parallel. + + + +The `boxBlurKernel` method takes the source image `src`, coordinates `x` and `y` +of the pixel, and the `radius` of the blur. +It returns the resulting average value of the surrounding pixels. +We compute the average value by separating the pixel into four channels, +computing the average of each of the channels, +and using the four average values to produce the final pixel value. +In the previous figure, the `radius` parameter is equal to `1` and the average +is computed from `9` pixels. + +You can find its signature in the package object of this assignment: + + def boxBlurKernel(src: Img, x: Int, y: Int, radius: Int): RGBA + +Implement the `boxBlurKernel` method. +Use two nested `while`-loops. +Make sure that the pixels at the image edges are affected only by the +pixels inside the image (hint: use the `clamp` method from the package object). + + +## Vertical Stripping Box Blur + +We can now implement the parallel box blur filter. +Note that the `boxBlurKernel` method is relatively inexpensive. +Executing `boxBlurKernel` might be much faster than starting a parallel +computation, so having a separate parallel computation for the value of each +pixel would be far too expensive. +For this reason, we want to batch together many `boxBlurKernel` calls, and have +a smaller number of parallel tasks. +This is sometimes referred to as *agglomeration*, and is present in many +parallel algorithm implementations. + +There are many different ways we can do agglomeration for the parallel box blur. +One is to divide the image into a fixed number of equally wide vertical strips. +For each strip, we start a parallel task, and wait for their completion. +Within each strip, we traverse the pixels going from the top to the bottom of +the image, as illustrated in the following figure: + + + +We start by implementing the sequential `blur` method in the +`VerticalBoxBlur.scala` source file, which takes the source image `src`, the +destination image `dst`, the starting (included) and ending (excluded) `x` coordinates +(i.e, column indices) of the strip, called `from` and `end`, and the blur `radius`. +The `blur` method blurs the pixels from the `src` image and writes them to the +`dst` image: + +```scala +def blur(src: Img, dst: Img, from: Int, end: Int, radius: Int): Unit +``` + +The implementation of `blur` should rely on the previously defined `boxBlurKernel`. + +Then, implement the `parBlur` method, which divides the image into `numTasks` vertical strips and runs each task in parallel: + +```scala +def parBlur(src: Img, dst: Img, numTasks: Int, radius: Int): Unit +``` + +Use Scala ranges to create a list of splitting points +(hint: use the `by` method on ranges). +Then use collection combinators on the list of splitting points to create a list +of start and end tuples, one for each strip +(hint: use the `zip` and `tail` methods). +Finally, use the `task` construct to start a parallel task for each strip, +and then call `join` on each task to wait for its completion. + +### Benchmarking VerticalBoxBlur + +Before running the benchmarking program, go to the top of `VerticalBoxBlur.scala` +and replace the line: +```scala + Key.verbose -> true +``` +by: +```scala + Key.verbose -> false +``` + + +Now you can run the `VerticalBoxBlur` program with the following sbt command: + +``` +> runMain scalashop.VerticalBoxBlurRunner +``` + +Change the number of tasks and the radius parameter. +How does the performance change? + + +## Horizontal Stripping Box Blur + +In this part of the exercise we will pick an alternative agglomeration for the +box blur algorithm. +Instead of dividing the image into vertical strips, we will divide it into +horizontal strips in a similar way: + + + +We implement the two methods, `blur` and `parBlur` in a similar way as before: + +```scala +def blur(src: Img, dst: Img, from: Int, end: Int, radius: Int): Unit +def parBlur(src: Img, dst: Img, numTasks: Int, radius: Int): Unit +``` + +Note that the arguments `from` (included) and `end` (excluded) this time denote the values of the +`y` coordinate (i.e, row indices), and that we traverse the pixels left-to-right within each strip. + +### Benchmarking HorizontalBoxBlur + +Before running the benchmarking program, go to the top of `HorizontalBoxBlur.scala` +and replace the line: +```scala + Key.verbose -> true +``` +by: +```scala + Key.verbose -> false +``` + + +Now you can now run the `HorizontalBoxBlur` program from sbt with: + +``` +> runMain scalashop.HorizontalBoxBlurRunner +``` + +If you implemented the two blur versions correctly, you should observe that the +horizontal stripping is slightly faster. +This is because the pixel traversal order visits the pixels which are closer +together in memory (remember the mapping between the pixel coordinates and the +memory addresses). As a result, each core can reuse some of the pixels that it +fetched from the memory during the previous invocation of `boxBlurKernel`. +The processor cores spend less time fetching pixels from memory and lower the +pressure on the memory bus. + + +## ScalaShop + +Now we have everything we need to start ScalaShop, from sbt run: + +``` +> runMain scalashop.ScalaShop +``` + +Change the blur implementation, parallelism level and blur radius, and study the +effect your changes have on performance. + + * Which of the two blur implementations is faster? + * For which values of the `radius` parameter is the difference most significant? + * Why? + * What if we split the image into rectangles? Will this be faster? + +*"Adobe" and "Photoshop" are either registered trademarks or trademarks of Adobe +Systems Incorporated in the United States and/or other countries.* diff --git a/labs/lab1-parallel-box-blur-filter/avg.svg b/labs/lab1-parallel-box-blur-filter/avg.svg new file mode 100755 index 0000000000000000000000000000000000000000..dd2eea9a1e5112c9fc0237950692a7ddca23b650 --- /dev/null +++ b/labs/lab1-parallel-box-blur-filter/avg.svg @@ -0,0 +1,360 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="210mm" + height="297mm" + viewBox="0 0 744.09448819 1052.3622047" + id="svg2" + version="1.1" + inkscape:version="0.91 r13725" + inkscape:export-filename="C:\cygwin\home\axel22\workspaces\scala\parprog\statements\scalashop\kernel.png" + inkscape:export-xdpi="16.044189" + inkscape:export-ydpi="16.044189" + sodipodi:docname="avg.svg"> + <defs + id="defs4"> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker13978" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path13980" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker13264" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path13266" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker11620" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path11622" /> + </marker> + <marker + inkscape:stockid="Arrow1Lend" + orient="auto" + refY="0.0" + refX="0.0" + id="marker11430" + style="overflow:visible;" + inkscape:isstock="true"> + <path + id="path11432" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + transform="scale(0.8) rotate(180) translate(12.5,0)" /> + </marker> + <marker + inkscape:stockid="Arrow1Lend" + orient="auto" + refY="0.0" + refX="0.0" + id="marker11220" + style="overflow:visible;" + inkscape:isstock="true"> + <path + id="path11222" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + transform="scale(0.8) rotate(180) translate(12.5,0)" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker8210" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path8212" /> + </marker> + <marker + inkscape:stockid="Arrow1Lend" + orient="auto" + refY="0.0" + refX="0.0" + id="marker8122" + style="overflow:visible;" + inkscape:isstock="true"> + <path + id="path8124" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + transform="scale(0.8) rotate(180) translate(12.5,0)" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker8004" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path8006" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker7904" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path7906" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker7810" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path7812" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker5934" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path5936" /> + </marker> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="0.55904437" + inkscape:cx="498.91476" + inkscape:cy="485.13131" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:snap-nodes="false" + inkscape:snap-bbox="false" + inkscape:window-width="1600" + inkscape:window-height="877" + inkscape:window-x="-4" + inkscape:window-y="-4" + inkscape:window-maximized="1" /> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1"> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3.06535697;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 569.48922,182.84133 0,536.93787" + id="path3342" + inkscape:connector-curvature="0" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3.06535697;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 476.55518,182.84133 0,536.93787" + id="path3346" + inkscape:connector-curvature="0" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3.06535697;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 390.18714,182.84133 0,536.93787" + id="path3350" + inkscape:connector-curvature="0" /> + <path + inkscape:connector-curvature="0" + id="path3352" + d="m 304.82925,182.84133 0,536.93787" + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3.06535697;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.53745508;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 630.8714,268.75392 -419.48108,0" + id="path3354" + inkscape:connector-curvature="0" /> + <path + inkscape:connector-curvature="0" + id="path3356" + d="m 630.8714,359.12582 -419.48108,0" + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.53745508;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.53745508;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 630.8714,454.81371 -419.48108,0" + id="path3358" + inkscape:connector-curvature="0" /> + <path + inkscape:connector-curvature="0" + id="path3360" + d="m 630.8714,550.05861 -419.48108,0" + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.53745508;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.53745508;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 630.8714,649.73349 -419.48108,0" + id="path3362" + inkscape:connector-curvature="0" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3.06535697;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 213.41044,182.84133 0,536.93787" + id="path3364" + inkscape:connector-curvature="0" /> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:37.4613266px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + x="643.29187" + y="549.94373" + id="text11422" + sodipodi:linespacing="125%" + transform="scale(1.0677679,0.93653312)"><tspan + sodipodi:role="line" + id="tspan11424" + x="643.29187" + y="549.94373" + style="font-size:65.55731964px">. . .</tspan></text> + <text + sodipodi:linespacing="125%" + id="text11426" + y="-384.24774" + x="803.21533" + style="font-style:normal;font-weight:normal;font-size:37.4613266px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + xml:space="preserve" + transform="matrix(0,0.93653312,-1.0677679,0,0,0)"><tspan + style="font-size:65.55731964px" + y="-384.24774" + x="803.21533" + id="tspan11428" + sodipodi:role="line">. . .</tspan></text> + <rect + style="fill:#000000;fill-opacity:0.85806454;fill-rule:evenodd;stroke:#000000;stroke-width:0.93653309px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + id="rect3403" + width="87.649574" + height="97.272865" + x="389.95117" + y="453.85275" /> + <rect + y="358.1488" + x="304.09036" + height="97.272865" + width="87.649574" + id="rect6045" + style="fill:#000000;fill-opacity:0.45161288;fill-rule:evenodd;stroke:#000000;stroke-width:0.93653309px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + <rect + style="fill:#000000;fill-opacity:0.45161288;fill-rule:evenodd;stroke:#000000;stroke-width:0.93653309px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + id="rect6047" + width="87.649574" + height="97.272865" + x="389.95117" + y="358.1488" /> + <rect + y="358.1488" + x="479.3895" + height="97.272865" + width="87.649574" + id="rect6049" + style="fill:#000000;fill-opacity:0.45161288;fill-rule:evenodd;stroke:#000000;stroke-width:0.93653309px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + <rect + style="fill:#000000;fill-opacity:0.45161288;fill-rule:evenodd;stroke:#000000;stroke-width:0.93653309px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + id="rect6051" + width="87.649574" + height="97.272865" + x="304.09036" + y="453.85275" /> + <rect + y="453.85275" + x="479.3895" + height="97.272865" + width="87.649574" + id="rect6053" + style="fill:#000000;fill-opacity:0.45161288;fill-rule:evenodd;stroke:#000000;stroke-width:0.93653309px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + <rect + style="fill:#000000;fill-opacity:0.45161288;fill-rule:evenodd;stroke:#000000;stroke-width:0.93653309px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + id="rect6055" + width="87.649574" + height="97.272865" + x="479.3895" + y="551.12567" /> + <rect + y="551.12567" + x="388.16238" + height="97.272865" + width="87.649574" + id="rect6057" + style="fill:#000000;fill-opacity:0.45161288;fill-rule:evenodd;stroke:#000000;stroke-width:0.93653309px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + <rect + style="fill:#000000;fill-opacity:0.45161288;fill-rule:evenodd;stroke:#000000;stroke-width:0.93653309px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + id="rect6059" + width="87.649574" + height="97.272865" + x="302.30157" + y="551.12567" /> + <path + inkscape:connector-curvature="0" + id="path6065" + d="m 630.8714,182.89311 -419.48108,0" + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.53745508;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + </g> +</svg> diff --git a/labs/lab1-parallel-box-blur-filter/horiz.svg b/labs/lab1-parallel-box-blur-filter/horiz.svg new file mode 100755 index 0000000000000000000000000000000000000000..b20844e771db0fac5f74a02ce168f16957d57db5 --- /dev/null +++ b/labs/lab1-parallel-box-blur-filter/horiz.svg @@ -0,0 +1,360 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="210mm" + height="297mm" + viewBox="0 0 744.09448819 1052.3622047" + id="svg2" + version="1.1" + inkscape:version="0.91 r13725" + inkscape:export-filename="C:\cygwin\home\axel22\workspaces\scala\parprog\statements\scalashop\horizontal.png" + inkscape:export-xdpi="32.263706" + inkscape:export-ydpi="32.263706" + sodipodi:docname="horiz.svg"> + <defs + id="defs4"> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker13978" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path13980" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker13264" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path13266" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker11620" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path11622" /> + </marker> + <marker + inkscape:stockid="Arrow1Lend" + orient="auto" + refY="0.0" + refX="0.0" + id="marker11430" + style="overflow:visible;" + inkscape:isstock="true"> + <path + id="path11432" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + transform="scale(0.8) rotate(180) translate(12.5,0)" /> + </marker> + <marker + inkscape:stockid="Arrow1Lend" + orient="auto" + refY="0.0" + refX="0.0" + id="marker11220" + style="overflow:visible;" + inkscape:isstock="true"> + <path + id="path11222" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + transform="scale(0.8) rotate(180) translate(12.5,0)" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker8210" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path8212" /> + </marker> + <marker + inkscape:stockid="Arrow1Lend" + orient="auto" + refY="0.0" + refX="0.0" + id="marker8122" + style="overflow:visible;" + inkscape:isstock="true"> + <path + id="path8124" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + transform="scale(0.8) rotate(180) translate(12.5,0)" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker8004" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path8006" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker7904" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path7906" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker7810" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path7812" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker5934" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path5936" /> + </marker> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="0.55904437" + inkscape:cx="498.91476" + inkscape:cy="485.13131" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:snap-nodes="false" + inkscape:snap-bbox="false" + inkscape:window-width="1600" + inkscape:window-height="877" + inkscape:window-x="-4" + inkscape:window-y="-4" + inkscape:window-maximized="1" /> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1"> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3.06535697;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 569.48922,182.84133 0,536.93787" + id="path3342" + inkscape:connector-curvature="0" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3.06535697;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 476.55518,182.84133 0,536.93787" + id="path3346" + inkscape:connector-curvature="0" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3.06535697;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 390.18714,182.84133 0,536.93787" + id="path3350" + inkscape:connector-curvature="0" /> + <path + inkscape:connector-curvature="0" + id="path3352" + d="m 304.82925,182.84133 0,536.93787" + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3.06535697;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.53745508;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 630.8714,268.75392 -419.48108,0" + id="path3354" + inkscape:connector-curvature="0" /> + <path + inkscape:connector-curvature="0" + id="path3356" + d="m 630.8714,359.12582 -419.48108,0" + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.53745508;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.53745508;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 630.8714,454.81371 -419.48108,0" + id="path3358" + inkscape:connector-curvature="0" /> + <path + inkscape:connector-curvature="0" + id="path3360" + d="m 630.8714,550.05861 -419.48108,0" + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.53745508;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.53745508;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 630.8714,649.73349 -419.48108,0" + id="path3362" + inkscape:connector-curvature="0" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3.06535697;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 213.41044,182.84133 0,536.93787" + id="path3364" + inkscape:connector-curvature="0" /> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:37.4613266px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + x="643.29187" + y="549.94373" + id="text11422" + sodipodi:linespacing="125%" + transform="scale(1.0677679,0.93653312)"><tspan + sodipodi:role="line" + id="tspan11424" + x="643.29187" + y="549.94373" + style="font-size:65.55731964px">. . .</tspan></text> + <text + sodipodi:linespacing="125%" + id="text11426" + y="-384.24774" + x="803.21533" + style="font-style:normal;font-weight:normal;font-size:37.4613266px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + xml:space="preserve" + transform="matrix(0,0.93653312,-1.0677679,0,0,0)"><tspan + style="font-size:65.55731964px" + y="-384.24774" + x="803.21533" + id="tspan11428" + sodipodi:role="line">. . .</tspan></text> + <rect + style="fill:#000000;fill-opacity:0.85806454;fill-rule:evenodd;stroke:#000000;stroke-width:0.93653309px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + id="rect3403" + width="87.649574" + height="97.272865" + x="389.95117" + y="453.85275" /> + <rect + y="358.1488" + x="304.09036" + height="97.272865" + width="87.649574" + id="rect6045" + style="fill:#000000;fill-opacity:0.45161288;fill-rule:evenodd;stroke:#000000;stroke-width:0.93653309px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + <rect + style="fill:#000000;fill-opacity:0.45161288;fill-rule:evenodd;stroke:#000000;stroke-width:0.93653309px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + id="rect6047" + width="87.649574" + height="97.272865" + x="389.95117" + y="358.1488" /> + <rect + y="358.1488" + x="479.3895" + height="97.272865" + width="87.649574" + id="rect6049" + style="fill:#000000;fill-opacity:0.45161288;fill-rule:evenodd;stroke:#000000;stroke-width:0.93653309px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + <rect + style="fill:#000000;fill-opacity:0.45161288;fill-rule:evenodd;stroke:#000000;stroke-width:0.93653309px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + id="rect6051" + width="87.649574" + height="97.272865" + x="304.09036" + y="453.85275" /> + <rect + y="453.85275" + x="479.3895" + height="97.272865" + width="87.649574" + id="rect6053" + style="fill:#000000;fill-opacity:0.45161288;fill-rule:evenodd;stroke:#000000;stroke-width:0.93653309px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + <rect + style="fill:#000000;fill-opacity:0.45161288;fill-rule:evenodd;stroke:#000000;stroke-width:0.93653309px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + id="rect6055" + width="87.649574" + height="97.272865" + x="479.3895" + y="551.12567" /> + <rect + y="551.12567" + x="388.16238" + height="97.272865" + width="87.649574" + id="rect6057" + style="fill:#000000;fill-opacity:0.45161288;fill-rule:evenodd;stroke:#000000;stroke-width:0.93653309px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + <rect + style="fill:#000000;fill-opacity:0.45161288;fill-rule:evenodd;stroke:#000000;stroke-width:0.93653309px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + id="rect6059" + width="87.649574" + height="97.272865" + x="302.30157" + y="551.12567" /> + <path + inkscape:connector-curvature="0" + id="path6065" + d="m 630.8714,182.89311 -419.48108,0" + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.53745508;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + </g> +</svg> diff --git a/labs/lab1-parallel-box-blur-filter/horizontal.png b/labs/lab1-parallel-box-blur-filter/horizontal.png new file mode 100755 index 0000000000000000000000000000000000000000..cc52fe74986a3bbebda0200ec89f5f9202ec0a05 Binary files /dev/null and b/labs/lab1-parallel-box-blur-filter/horizontal.png differ diff --git a/labs/lab1-parallel-box-blur-filter/kernel.png b/labs/lab1-parallel-box-blur-filter/kernel.png new file mode 100755 index 0000000000000000000000000000000000000000..06aeca6c29596c6104302991be09c442a9dc78be Binary files /dev/null and b/labs/lab1-parallel-box-blur-filter/kernel.png differ diff --git a/labs/lab1-parallel-box-blur-filter/mapping.png b/labs/lab1-parallel-box-blur-filter/mapping.png new file mode 100755 index 0000000000000000000000000000000000000000..c8ba9ef5d9a96550eb0a1eeba45fbcad0423b469 Binary files /dev/null and b/labs/lab1-parallel-box-blur-filter/mapping.png differ diff --git a/labs/lab1-parallel-box-blur-filter/mapping.svg b/labs/lab1-parallel-box-blur-filter/mapping.svg new file mode 100755 index 0000000000000000000000000000000000000000..c36c621eff29c31af15bbe02964d146bf4de9e44 --- /dev/null +++ b/labs/lab1-parallel-box-blur-filter/mapping.svg @@ -0,0 +1,735 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="210mm" + height="297mm" + viewBox="0 0 744.09448819 1052.3622047" + id="svg2" + version="1.1" + inkscape:version="0.91 r13725" + inkscape:export-filename="C:\cygwin\home\axel22\workspaces\scala\parprog\statements\scalashop\mapping.png" + inkscape:export-xdpi="32.263699" + inkscape:export-ydpi="32.263699" + sodipodi:docname="mapping.svg"> + <defs + id="defs4"> + <marker + inkscape:isstock="true" + style="overflow:visible" + id="marker6574" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lstart"> + <path + transform="scale(0.8) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path6576" /> + </marker> + <marker + inkscape:stockid="Arrow1Lstart" + orient="auto" + refY="0.0" + refX="0.0" + id="Arrow1Lstart" + style="overflow:visible" + inkscape:isstock="true" + inkscape:collect="always"> + <path + id="path6282" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + transform="scale(0.8) translate(12.5,0)" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker13978" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path13980" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker13264" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path13266" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker11620" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path11622" /> + </marker> + <marker + inkscape:stockid="Arrow1Lend" + orient="auto" + refY="0.0" + refX="0.0" + id="marker11430" + style="overflow:visible;" + inkscape:isstock="true"> + <path + id="path11432" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + transform="scale(0.8) rotate(180) translate(12.5,0)" /> + </marker> + <marker + inkscape:stockid="Arrow1Lend" + orient="auto" + refY="0.0" + refX="0.0" + id="marker11220" + style="overflow:visible;" + inkscape:isstock="true"> + <path + id="path11222" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + transform="scale(0.8) rotate(180) translate(12.5,0)" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker8210" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path8212" /> + </marker> + <marker + inkscape:stockid="Arrow1Lend" + orient="auto" + refY="0.0" + refX="0.0" + id="marker8122" + style="overflow:visible;" + inkscape:isstock="true"> + <path + id="path8124" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + transform="scale(0.8) rotate(180) translate(12.5,0)" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker8004" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path8006" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker7904" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path7906" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker7810" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path7812" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker5934" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path5936" /> + </marker> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="0.39530407" + inkscape:cx="614.73965" + inkscape:cy="665.95015" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:snap-nodes="false" + inkscape:snap-bbox="false" + inkscape:window-width="1600" + inkscape:window-height="877" + inkscape:window-x="-4" + inkscape:window-y="-4" + inkscape:window-maximized="1" /> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1"> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3.06535697;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 569.48922,182.84133 0,536.93787" + id="path3342" + inkscape:connector-curvature="0" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3.06535697;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 476.55518,182.84133 0,536.93787" + id="path3346" + inkscape:connector-curvature="0" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3.06535697;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 390.18714,182.84133 0,536.93787" + id="path3350" + inkscape:connector-curvature="0" /> + <path + inkscape:connector-curvature="0" + id="path3352" + d="m 304.82925,182.84133 0,536.93787" + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3.06535697;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.60156703;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 652.3366,268.75392 -440.94628,0" + id="path3354" + inkscape:connector-curvature="0" /> + <path + inkscape:connector-curvature="0" + id="path3356" + d="m 652.3366,359.12582 -440.94628,0" + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.60156703;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.60156703;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 652.3366,454.81371 -440.94628,0" + id="path3358" + inkscape:connector-curvature="0" /> + <path + inkscape:connector-curvature="0" + id="path3360" + d="m 652.3366,550.05861 -440.94628,0" + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.60156703;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.60156703;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 652.3366,649.73349 -440.94628,0" + id="path3362" + inkscape:connector-curvature="0" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3.06535697;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 213.41044,182.84133 0,536.93787" + id="path3364" + inkscape:connector-curvature="0" /> + <text + sodipodi:linespacing="125%" + id="text11426" + y="-384.24774" + x="803.21533" + style="font-style:normal;font-weight:normal;font-size:37.4613266px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + xml:space="preserve" + transform="matrix(0,0.93653312,-1.0677679,0,0,0)"><tspan + style="font-size:65.55731964px" + y="-384.24774" + x="803.21533" + id="tspan11428" + sodipodi:role="line">. . .</tspan></text> + <path + inkscape:connector-curvature="0" + id="path6065" + d="m 652.3366,182.89311 -440.94628,0" + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.60156703;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + inkscape:connector-curvature="0" + id="path6126" + d="m 653.44707,182.84133 0,536.93787" + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3.06535697;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + x="246.84982" + y="240.26208" + id="text6128" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6130" + x="246.84982" + y="240.26208">0</tspan></text> + <text + sodipodi:linespacing="125%" + id="text6132" + y="240.26208" + x="334.49939" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + xml:space="preserve"><tspan + y="240.26208" + x="334.49939" + id="tspan6134" + sodipodi:role="line">1</tspan></text> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + x="422.14896" + y="240.26208" + id="text6136" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6138" + x="422.14896" + y="240.26208">2</tspan></text> + <text + sodipodi:linespacing="125%" + id="text6140" + y="240.26208" + x="506.22101" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + xml:space="preserve"><tspan + y="240.26208" + x="506.22101" + id="tspan6142" + sodipodi:role="line">3</tspan></text> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + x="597.00092" + y="240.26208" + id="text6144" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6146" + x="597.00092" + y="240.26208">4</tspan></text> + <text + sodipodi:linespacing="125%" + id="text6148" + y="329.70044" + x="246.84982" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + xml:space="preserve"><tspan + y="329.70044" + x="246.84982" + id="tspan6150" + sodipodi:role="line">5</tspan></text> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + x="334.49939" + y="329.70044" + id="text6152" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6154" + x="334.49939" + y="329.70044">6</tspan></text> + <text + sodipodi:linespacing="125%" + id="text6156" + y="329.70044" + x="422.14896" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + xml:space="preserve"><tspan + y="329.70044" + x="422.14896" + id="tspan6158" + sodipodi:role="line">7</tspan></text> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + x="506.22101" + y="329.70044" + id="text6160" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6162" + x="506.22101" + y="329.70044">8</tspan></text> + <text + sodipodi:linespacing="125%" + id="text6164" + y="329.70044" + x="597.00092" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + xml:space="preserve"><tspan + y="329.70044" + x="597.00092" + id="tspan6166" + sodipodi:role="line">9</tspan></text> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + x="233.88127" + y="422.71631" + id="text6168" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6170" + x="233.88127" + y="422.71631">10</tspan></text> + <text + sodipodi:linespacing="125%" + id="text6172" + y="422.71631" + x="321.53082" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + xml:space="preserve"><tspan + y="422.71631" + x="321.53082" + id="tspan6174" + sodipodi:role="line">11</tspan></text> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + x="409.18039" + y="422.71631" + id="text6176" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6178" + x="409.18039" + y="422.71631">12</tspan></text> + <text + sodipodi:linespacing="125%" + id="text6180" + y="422.71631" + x="493.25244" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + xml:space="preserve"><tspan + y="422.71631" + x="493.25244" + id="tspan6182" + sodipodi:role="line">13</tspan></text> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + x="584.03235" + y="422.71631" + id="text6184" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6186" + x="584.03235" + y="422.71631">14</tspan></text> + <text + sodipodi:linespacing="125%" + id="text6188" + y="516.62659" + x="233.88127" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + xml:space="preserve"><tspan + y="516.62659" + x="233.88127" + id="tspan6190" + sodipodi:role="line">15</tspan></text> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + x="321.53082" + y="516.62659" + id="text6192" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6194" + x="321.53082" + y="516.62659">16</tspan></text> + <text + sodipodi:linespacing="125%" + id="text6196" + y="516.62659" + x="409.18039" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + xml:space="preserve"><tspan + y="516.62659" + x="409.18039" + id="tspan6198" + sodipodi:role="line">17</tspan></text> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + x="493.25244" + y="516.62659" + id="text6200" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6202" + x="493.25244" + y="516.62659">18</tspan></text> + <text + sodipodi:linespacing="125%" + id="text6204" + y="516.62659" + x="584.03235" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + xml:space="preserve"><tspan + y="516.62659" + x="584.03235" + id="tspan6206" + sodipodi:role="line">19</tspan></text> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + x="233.88127" + y="615.90314" + id="text6208" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6210" + x="233.88127" + y="615.90314">20</tspan></text> + <text + sodipodi:linespacing="125%" + id="text6212" + y="615.90314" + x="321.53082" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + xml:space="preserve"><tspan + y="615.90314" + x="321.53082" + id="tspan6214" + sodipodi:role="line">21</tspan></text> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + x="409.18039" + y="615.90314" + id="text6216" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6218" + x="409.18039" + y="615.90314">22</tspan></text> + <text + sodipodi:linespacing="125%" + id="text6220" + y="615.90314" + x="493.25244" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + xml:space="preserve"><tspan + y="615.90314" + x="493.25244" + id="tspan6222" + sodipodi:role="line">23</tspan></text> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + x="584.03235" + y="615.90314" + id="text6224" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6226" + x="584.03235" + y="615.90314">24</tspan></text> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.76099992;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#Arrow1Lstart)" + d="m 707.98996,104.47247 -496.59964,0" + id="path6228" + inkscape:connector-curvature="0" /> + <path + inkscape:connector-curvature="0" + id="path6572" + d="m 140.93101,679.12051 0,-496.59964" + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.76099992;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#marker6574)" /> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + x="671.63489" + y="70.839287" + id="text7312" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan7314" + x="671.63489" + y="70.839287">x</tspan></text> + <text + sodipodi:linespacing="125%" + id="text7316" + y="679.23169" + x="79.685501" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + xml:space="preserve"><tspan + y="679.23169" + x="79.685501" + id="tspan7318" + sodipodi:role="line">y</tspan></text> + <text + sodipodi:linespacing="125%" + id="text7342" + y="165.63599" + x="246.84982" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + xml:space="preserve"><tspan + y="165.63599" + x="246.84982" + id="tspan7344" + sodipodi:role="line">0</tspan></text> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + x="334.49939" + y="165.63599" + id="text7346" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan7348" + x="334.49939" + y="165.63599">1</tspan></text> + <text + sodipodi:linespacing="125%" + id="text7350" + y="165.63599" + x="422.14896" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + xml:space="preserve"><tspan + y="165.63599" + x="422.14896" + id="tspan7352" + sodipodi:role="line">2</tspan></text> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + x="506.22101" + y="165.63599" + id="text7354" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan7356" + x="506.22101" + y="165.63599">3</tspan></text> + <text + sodipodi:linespacing="125%" + id="text7358" + y="165.63599" + x="597.00092" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + xml:space="preserve"><tspan + y="165.63599" + x="597.00092" + id="tspan7360" + sodipodi:role="line">4</tspan></text> + <text + sodipodi:linespacing="125%" + id="text7382" + y="240.26208" + x="165.89948" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + xml:space="preserve"><tspan + y="240.26208" + x="165.89948" + id="tspan7384" + sodipodi:role="line">0</tspan></text> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + x="165.89948" + y="329.70044" + id="text7386" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan7388" + x="165.89948" + y="329.70044">1</tspan></text> + <text + sodipodi:linespacing="125%" + id="text7402" + y="423.29929" + x="165.89948" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + xml:space="preserve"><tspan + y="423.29929" + x="165.89948" + id="tspan7404" + sodipodi:role="line">2</tspan></text> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + x="165.89948" + y="518.10394" + id="text7406" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan7408" + x="165.89948" + y="518.10394">3</tspan></text> + <text + sodipodi:linespacing="125%" + id="text7410" + y="616.93329" + x="165.89948" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + xml:space="preserve"><tspan + y="616.93329" + x="165.89948" + id="tspan7412" + sodipodi:role="line">4</tspan></text> + </g> +</svg> diff --git a/labs/lab1-parallel-box-blur-filter/vert.svg b/labs/lab1-parallel-box-blur-filter/vert.svg new file mode 100755 index 0000000000000000000000000000000000000000..d20644e4b792f9e5caa0b676c31a6aa938360450 --- /dev/null +++ b/labs/lab1-parallel-box-blur-filter/vert.svg @@ -0,0 +1,462 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="210mm" + height="297mm" + viewBox="0 0 744.09448819 1052.3622047" + id="svg2" + version="1.1" + inkscape:version="0.91 r13725" + inkscape:export-filename="C:\cygwin\home\axel22\workspaces\scala\parprog\statements\scalashop\vertical.png" + inkscape:export-xdpi="32.263706" + inkscape:export-ydpi="32.263706" + sodipodi:docname="vert.svg"> + <defs + id="defs4"> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker13978" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path13980" /> + </marker> + <marker + inkscape:stockid="Arrow1Lend" + orient="auto" + refY="0.0" + refX="0.0" + id="marker13726" + style="overflow:visible;" + inkscape:isstock="true" + inkscape:collect="always"> + <path + id="path13728" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + transform="scale(0.8) rotate(180) translate(12.5,0)" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker13474" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend" + inkscape:collect="always"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path13476" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker13264" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path13266" /> + </marker> + <marker + inkscape:stockid="Arrow1Lend" + orient="auto" + refY="0.0" + refX="0.0" + id="marker12964" + style="overflow:visible;" + inkscape:isstock="true" + inkscape:collect="always"> + <path + id="path12966" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + transform="scale(0.8) rotate(180) translate(12.5,0)" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker12676" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend" + inkscape:collect="always"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path12678" /> + </marker> + <marker + inkscape:stockid="Arrow1Lend" + orient="auto" + refY="0.0" + refX="0.0" + id="marker12514" + style="overflow:visible;" + inkscape:isstock="true" + inkscape:collect="always"> + <path + id="path12516" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + transform="scale(0.8) rotate(180) translate(12.5,0)" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker11620" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path11622" /> + </marker> + <marker + inkscape:stockid="Arrow1Lend" + orient="auto" + refY="0.0" + refX="0.0" + id="marker11430" + style="overflow:visible;" + inkscape:isstock="true"> + <path + id="path11432" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + transform="scale(0.8) rotate(180) translate(12.5,0)" /> + </marker> + <marker + inkscape:stockid="Arrow1Lend" + orient="auto" + refY="0.0" + refX="0.0" + id="marker11220" + style="overflow:visible;" + inkscape:isstock="true"> + <path + id="path11222" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + transform="scale(0.8) rotate(180) translate(12.5,0)" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker8210" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path8212" /> + </marker> + <marker + inkscape:stockid="Arrow1Lend" + orient="auto" + refY="0.0" + refX="0.0" + id="marker8122" + style="overflow:visible;" + inkscape:isstock="true"> + <path + id="path8124" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + transform="scale(0.8) rotate(180) translate(12.5,0)" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker8004" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path8006" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker7904" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path7906" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker7810" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path7812" /> + </marker> + <marker + inkscape:isstock="true" + style="overflow:visible;" + id="marker5934" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="Arrow1Lend"> + <path + transform="scale(0.8) rotate(180) translate(12.5,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + id="path5936" /> + </marker> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="0.55904437" + inkscape:cx="358.49657" + inkscape:cy="390.35492" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:snap-nodes="false" + inkscape:snap-bbox="false" + inkscape:window-width="1600" + inkscape:window-height="877" + inkscape:window-x="-4" + inkscape:window-y="-4" + inkscape:window-maximized="1" /> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1"> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 569.48922,268.86138 0,514.28572" + id="path3342" + inkscape:connector-curvature="0" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 476.55518,268.86138 0,514.28572" + id="path3346" + inkscape:connector-curvature="0" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 390.18714,268.86138 0,514.28572" + id="path3350" + inkscape:connector-curvature="0" /> + <path + inkscape:connector-curvature="0" + id="path3352" + d="m 304.82925,268.86138 0,514.28572" + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.70941305;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 630.8714,268.92042 -419.48108,0" + id="path3354" + inkscape:connector-curvature="0" /> + <path + inkscape:connector-curvature="0" + id="path3356" + d="m 630.8714,371.95598 -419.48108,0" + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.70941305;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.70941305;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 630.8714,481.05245 -419.48108,0" + id="path3358" + inkscape:connector-curvature="0" /> + <path + inkscape:connector-curvature="0" + id="path3360" + d="m 630.8714,589.64385 -419.48108,0" + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.70941305;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.70941305;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 630.8714,703.28601 -419.48108,0" + id="path3362" + inkscape:connector-curvature="0" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 213.41044,268.86138 0,514.28572" + id="path3364" + inkscape:connector-curvature="0" /> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + x="686.88641" + y="549.71875" + id="text11422" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan11424" + x="686.88641" + y="549.71875" + style="font-size:70px">. . .</tspan></text> + <text + sodipodi:linespacing="125%" + id="text11426" + y="-410.28741" + x="820.15405" + style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + xml:space="preserve" + transform="matrix(0,1,-1,0,0,0)"><tspan + style="font-size:70px" + y="-410.28741" + x="820.15405" + id="tspan11428" + sodipodi:role="line">. . .</tspan></text> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.80425525;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker12514)" + d="m 247.27796,320.65086 c 44.2368,48.29938 61.77332,47.23254 94.62097,3.28287" + id="path12268" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + <path + sodipodi:nodetypes="cc" + inkscape:connector-curvature="0" + id="path12674" + d="m 343.09028,320.65086 c 44.2368,48.29938 61.77332,47.23254 94.62097,3.28287" + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.80425525;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker12676)" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.80425525;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker12964)" + d="m 438.58639,320.65086 c 44.2368,48.29938 61.77332,47.23254 94.62097,3.28287" + id="path12962" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + <path + sodipodi:nodetypes="cc" + inkscape:connector-curvature="0" + id="path13262" + d="m 532.49665,320.65086 c 44.2368,48.29938 61.77332,47.23254 94.62097,3.28287" + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.80425525;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker13264)" /> + <path + sodipodi:nodetypes="cc" + inkscape:connector-curvature="0" + id="path13466" + d="m 247.27796,421.71618 c 44.2368,48.29938 61.77332,47.23254 94.62097,3.28287" + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.80425525;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker13474)" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.80425525;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker12676)" + d="m 343.09028,421.71618 c 44.2368,48.29938 61.77332,47.23254 94.62097,3.28287" + id="path13468" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + <path + sodipodi:nodetypes="cc" + inkscape:connector-curvature="0" + id="path13470" + d="m 438.58639,421.71618 c 44.2368,48.29938 61.77332,47.23254 94.62097,3.28287" + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.80425525;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker12964)" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.80425525;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker13264)" + d="m 532.49665,421.71618 c 44.2368,48.29938 61.77332,47.23254 94.62097,3.28287" + id="path13472" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.80425525;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker13726)" + d="m 247.27796,532.61972 c 44.2368,48.29938 61.77332,47.23254 94.62097,3.28287" + id="path13718" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + <path + sodipodi:nodetypes="cc" + inkscape:connector-curvature="0" + id="path13720" + d="m 343.09028,532.61972 c 44.2368,48.29938 61.77332,47.23254 94.62097,3.28287" + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.80425525;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker12676)" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.80425525;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker12964)" + d="m 438.58639,532.61972 c 44.2368,48.29938 61.77332,47.23254 94.62097,3.28287" + id="path13722" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + <path + sodipodi:nodetypes="cc" + inkscape:connector-curvature="0" + id="path13724" + d="m 532.49665,532.61972 c 44.2368,48.29938 61.77332,47.23254 94.62097,3.28287" + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.80425525;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker13264)" /> + <path + sodipodi:nodetypes="cc" + inkscape:connector-curvature="0" + id="path13970" + d="m 247.27796,641.73449 c 44.2368,48.29938 61.77332,47.23254 94.62097,3.28287" + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.80425525;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker13978)" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.80425525;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker12676)" + d="m 343.09028,641.73449 c 44.2368,48.29938 61.77332,47.23254 94.62097,3.28287" + id="path13972" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + <path + sodipodi:nodetypes="cc" + inkscape:connector-curvature="0" + id="path13974" + d="m 438.58639,641.73449 c 44.2368,48.29938 61.77332,47.23254 94.62097,3.28287" + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.80425525;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker12964)" /> + <path + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.80425525;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker13264)" + d="m 532.49665,641.73449 c 44.2368,48.29938 61.77332,47.23254 94.62097,3.28287" + id="path13976" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + </g> +</svg> diff --git a/labs/lab1-parallel-box-blur-filter/vertical.png b/labs/lab1-parallel-box-blur-filter/vertical.png new file mode 100755 index 0000000000000000000000000000000000000000..02c71ab3fb1bb6783dd0e756c85a855d7353f36f Binary files /dev/null and b/labs/lab1-parallel-box-blur-filter/vertical.png differ diff --git a/labs/tools-setup.md b/labs/tools-setup.md new file mode 100644 index 0000000000000000000000000000000000000000..ab8682c7fc59fa07c86570220c455c1247207825 --- /dev/null +++ b/labs/tools-setup.md @@ -0,0 +1,193 @@ +# Tools Setup + +## Note + +We recommend using Linux or macOS for this course, we also support Windows but +typically people have more trouble getting everything working correctly on +Windows and it's harder for us to help them since we don't use Windows +ourselves. + +**On Windows, if your username has spaces or special characters in it, the IDE might not +work properly. Please create a new user with a username containing only letters.** + +# Step 1: Create an account on gitlab.epfl.ch + +If you haven't already [log into gitlab](https://gitlab.epfl.ch/users/sign_in) +and fill in [this table](https://docs.google.com/spreadsheets/d/1rcq_UMgR6bAH-iK1L2I6WoClZtCqUoIOLqQO3NJKdgg) with your GASPAR and SCIPER number to initialize your GitLab repository for the course. Do this as soon as possible because it will take some time between the account creation and the lab submission system working for your account. + +## Step 2: Installing the Java Development Kit (JDK) and sbt via coursier + +We will use coursier to install the correct version of +Java as well as the sbt build tool: + +### On Linux + +```shell +curl -fLo cs https://git.io/coursier-cli-linux +``` +```shell +chmod +x cs +``` +```shell +./cs setup -y --jvm 8 --apps cs,sbt +``` + +### On macOS + +First, install the Homebrew package manager: +```shell +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" +``` +Use Homebrew to install coursier: +```scala +brew install coursier/formulas/coursier +``` +```shell +[ -f ~/.bash_profile ] && sudo chmod 0666 ~/.bash_profile +``` +```shell +cs setup -y --jvm 8 --apps sbt +``` + +### On Windows + +Download and install the [Visual C++ 2010 SP1 Redistributable Package](https://www.microsoft.com/en-us/download/details.aspx?id=13523). + +Open `cmd.exe` (and not powershell) + +First, make sure that you are not in the `System32` directory, instead you +should be in `C:\Users\yourusername`. If you are in `System32` you will need to +change directory to your user directory every time you start a terminal by +running: +```shell +cd %USERPROFILE% +``` + +Now assuming that you're in the correct directory you can run: + +```shell +bitsadmin /transfer cs-cli https://git.io/coursier-cli-windows-exe "%cd%\cs.exe" +``` +```shell +.\cs setup -y --jvm 8 --apps cs,sbt +``` + +(This command might cause your anti-virus to misidentify cs.exe as a virus, +please override that, that might require temporarily turning off your anti-virus +during this setup). + +If this command fails with `Error running powershell script`, use the following +alternative instructions (if the command didn't fail, continue to the next +step): + +1. Run `.\cs setup --jvm 8 --apps cs,sbt`, at every question answer "n" and + press Enter. +2. The last question should look like "Should we add `C:\...\bin` to your PATH?", + please copy the `C:\...\bin` part here. +3. Edit the Path environment variable and paste the path you just copied to it, see + https://www.architectryan.com/2018/08/31/how-to-change-environment-variables-on-windows-10/ + and make sure the path you're adding is the first entry in the Path environment + variable. +4. Start a **new** cmd.exe and continue with the rest of the instructions + +**In case of errors please ask on Discord or Gitlab issues for help, but don't +try to run commands as Administrator as this will likely cause further issues!** + +## Step 5: Installing git + +git is a version control system. + +### On Ubuntu and Debian + +```shell +sudo apt update && sudo apt install git +``` + +### On macOS + +```shell +brew install git +``` + +### On Windows + +Download and install git from [https://git-scm.com/downloads](https://git-scm.com/downloads). +Once git is installed, open a **new** terminal and run: + +```shell +git config --global core.autocrlf false +``` + +If this command worked it will not print anything. + +## Step 6: Installing Code + +Visual Studio Code is the IDE we strongly recommend using for this class (you are free to use any editor you want, but we won't don't have the resources to help you configure it for Scala). + +### On Linux + +See [https://code.visualstudio.com/docs/setup/linux](https://code.visualstudio.com/docs/setup/linux) + +### On macOS + +```shell +brew cask install visual-studio-code +``` + +### On Windows + +See [https://code.visualstudio.com/docs/setup/windows](https://code.visualstudio.com/docs/setup/windows). +Make sure that the checkbox "Add to PATH (available after restart)" in the +installer is checked. + +## Step 7: Installing the Scala support for Code + +Open a **new** terminal and run: +```scala +code --install-extension lampepfl.dotty-syntax +``` + +If you're on Windows and the command is not found, try closing and restarting +the terminal, if that doesn't work + +## Step 8: Generate a public/private SSH key pair + +To submit labs, you will need an SSH key. If you don't already have one, here's how to generate it: + +### Step 8.1: Installing OpenSSH + +#### On Ubuntu and Debian + +```shell +sudo apt update && sudo apt install openssh-client +``` + +#### On macOS + +Nothing to do, OpenSSH is pre-installed + +#### On Windows + +Follow the instructions under "Enable OpenSSH Client in Windows 10" on +[https://winaero.com/blog/enable-openssh-client-windows-10/](https://winaero.com/blog/enable-openssh-client-windows-10/) + +### Step 8.2: Generating the key pair + +Open a **new** terminal and run: + +```shell +ssh-keygen -t rsa -b 4096 -C "youremail@example.com" +``` + +The command will then ask for a location, which you can leave as the default. It will then also ask for a passphrase to encrypt your private key, which you may leave empty. If you don't, make sure to remember your passphrase! + +### Adding your public key on Gitlab + +To be able to push your code, you'll need to add the public part of your key on Gitlab: +- Go to [gitlab.epfl.ch](https://gitlab.epfl.ch), log in with your EPFL account +- Go to [gitlab.epfl.ch/profile/keys](https://gitlab.epfl.ch/profile/keys) and copy-paste the content of the `id_rsa.pub` file created by the `ssh-keygen` command you just ran (when the command was ran it printed the location where this file was saved). +- Press `Add key` + +## Step 9: Follow the example lab + +Time to do the [example lab](example-lab.md)! diff --git a/previous-exams/2015-midterm-solution-.pdf b/previous-exams/2015-midterm-solution-.pdf new file mode 100644 index 0000000000000000000000000000000000000000..9d3c70f6de625b9e3b5a5eca6b97947b2805dc41 Binary files /dev/null and b/previous-exams/2015-midterm-solution-.pdf differ diff --git a/previous-exams/2015-midterm.pdf b/previous-exams/2015-midterm.pdf new file mode 100644 index 0000000000000000000000000000000000000000..23f21555aa3bf7a7669cc79de54acda90aa19099 Binary files /dev/null and b/previous-exams/2015-midterm.pdf differ diff --git a/previous-exams/2016-final-solutions.pdf b/previous-exams/2016-final-solutions.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8e60022aef7b0d25179ca1b4dca4f1338c16619d Binary files /dev/null and b/previous-exams/2016-final-solutions.pdf differ diff --git a/previous-exams/2016-final.pdf b/previous-exams/2016-final.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c13bc385e9713d3b01485ec0a22bb58ddaece0d5 Binary files /dev/null and b/previous-exams/2016-final.pdf differ diff --git a/previous-exams/2016-midterm-solutions.pdf b/previous-exams/2016-midterm-solutions.pdf new file mode 100644 index 0000000000000000000000000000000000000000..22237321a68102b97970ebe1f9f9a51b2a25792c Binary files /dev/null and b/previous-exams/2016-midterm-solutions.pdf differ diff --git a/previous-exams/2016-midterm.pdf b/previous-exams/2016-midterm.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0b83f5a93befc1b6e5bdc2bc42e805de5f9052bc Binary files /dev/null and b/previous-exams/2016-midterm.pdf differ diff --git a/previous-exams/2017-final-solutions.pdf b/previous-exams/2017-final-solutions.pdf new file mode 100644 index 0000000000000000000000000000000000000000..336c0869de172b028299532162c5239085fa1f08 Binary files /dev/null and b/previous-exams/2017-final-solutions.pdf differ diff --git a/previous-exams/2017-final.pdf b/previous-exams/2017-final.pdf new file mode 100644 index 0000000000000000000000000000000000000000..477dd837c75874d8c02897571d192bbaf9678479 Binary files /dev/null and b/previous-exams/2017-final.pdf differ diff --git a/previous-exams/2017-midterm-solutions.pdf b/previous-exams/2017-midterm-solutions.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b02c50f258d5bca20b19882e239db4b7608d486e Binary files /dev/null and b/previous-exams/2017-midterm-solutions.pdf differ diff --git a/previous-exams/2017-midterm.pdf b/previous-exams/2017-midterm.pdf new file mode 100644 index 0000000000000000000000000000000000000000..aa1cbf26b9840f9c89513545e83211f9116cb8b3 Binary files /dev/null and b/previous-exams/2017-midterm.pdf differ diff --git a/previous-exams/2018-final-solutions.pdf b/previous-exams/2018-final-solutions.pdf new file mode 100644 index 0000000000000000000000000000000000000000..5742cab8f4c696feb10ff93c67a3ac43831cec03 Binary files /dev/null and b/previous-exams/2018-final-solutions.pdf differ diff --git a/previous-exams/2018-final.pdf b/previous-exams/2018-final.pdf new file mode 100644 index 0000000000000000000000000000000000000000..be1016c8c9e62dcf1233c52372d8729ebab4c3f7 Binary files /dev/null and b/previous-exams/2018-final.pdf differ diff --git a/previous-exams/2019-final-solutions.pdf b/previous-exams/2019-final-solutions.pdf new file mode 100644 index 0000000000000000000000000000000000000000..6029535ca8448952d37c40af628c06bd445254b9 Binary files /dev/null and b/previous-exams/2019-final-solutions.pdf differ diff --git a/previous-exams/2019-final.pdf b/previous-exams/2019-final.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c08c74faf5121f78e58254848321ff2bf729bb04 Binary files /dev/null and b/previous-exams/2019-final.pdf differ diff --git a/previous-exams/2019-midterm-solutions.pdf b/previous-exams/2019-midterm-solutions.pdf new file mode 100644 index 0000000000000000000000000000000000000000..a311ee467b7fcd4dfbf6cdb0f367dcebc6bba366 Binary files /dev/null and b/previous-exams/2019-midterm-solutions.pdf differ diff --git a/previous-exams/2019-midterm.pdf b/previous-exams/2019-midterm.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d64aac32c34858734b9f7a8005986e38759ccfa1 Binary files /dev/null and b/previous-exams/2019-midterm.pdf differ diff --git a/previous-exams/2020-final-solution.pdf b/previous-exams/2020-final-solution.pdf new file mode 100644 index 0000000000000000000000000000000000000000..9872cc3273525b79c1cfd3d71cd70a6ec6541e45 Binary files /dev/null and b/previous-exams/2020-final-solution.pdf differ diff --git a/previous-exams/2020-final.pdf b/previous-exams/2020-final.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2d70a411e7f0294dda265eb9d13ae2f0355dbde1 Binary files /dev/null and b/previous-exams/2020-final.pdf differ diff --git a/slides/week1-parallelism-1.pdf b/slides/week1-parallelism-1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..56e4442b6eb4cc788ea3676132109123bb59fc1b Binary files /dev/null and b/slides/week1-parallelism-1.pdf differ diff --git a/slides/week10-actors-1.pdf b/slides/week10-actors-1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..012559fb2903d07b3079e05ad68d0da3f0deb8b6 Binary files /dev/null and b/slides/week10-actors-1.pdf differ diff --git a/slides/week11-actors-2.pdf b/slides/week11-actors-2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..7b7d074bd9fa0681e906a23e3feeabf799bf1677 Binary files /dev/null and b/slides/week11-actors-2.pdf differ diff --git a/slides/week12-spark-1.pdf b/slides/week12-spark-1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2f7c8682fcd193eacd5b3678dc977ede30de0e03 Binary files /dev/null and b/slides/week12-spark-1.pdf differ diff --git a/slides/week13-spark-2.pdf b/slides/week13-spark-2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..9dc91e4e13c88de7039718a0ccc2bb6508ae3cd9 Binary files /dev/null and b/slides/week13-spark-2.pdf differ diff --git a/slides/week14-spark-3.pdf b/slides/week14-spark-3.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0147df7009a8e7603e1fcaf872e608fa9a357d63 Binary files /dev/null and b/slides/week14-spark-3.pdf differ diff --git a/slides/week2-parallelism-2.pdf b/slides/week2-parallelism-2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..ec63745c1edbdeedb6ec9c8ef0fdf7695ccd6968 Binary files /dev/null and b/slides/week2-parallelism-2.pdf differ diff --git a/slides/week3-parallelism-3.pdf b/slides/week3-parallelism-3.pdf new file mode 100644 index 0000000000000000000000000000000000000000..7aa5015469bdf8e24c57d95e7b43413441040566 Binary files /dev/null and b/slides/week3-parallelism-3.pdf differ diff --git a/slides/week4-parallelism-4.pdf b/slides/week4-parallelism-4.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c110144f6c75672831a5db8056bc392c58145a03 Binary files /dev/null and b/slides/week4-parallelism-4.pdf differ diff --git a/slides/week5-concurrency-1.pdf b/slides/week5-concurrency-1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8ddafe891408180df20b90df3d8fed0a795d3f93 Binary files /dev/null and b/slides/week5-concurrency-1.pdf differ diff --git a/slides/week6-concurrency-2.pdf b/slides/week6-concurrency-2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..06948bb834291976d21bb838efd0ce64989e5ba6 Binary files /dev/null and b/slides/week6-concurrency-2.pdf differ diff --git a/slides/week7-concurrency-3.pdf b/slides/week7-concurrency-3.pdf new file mode 100644 index 0000000000000000000000000000000000000000..404fba36a04bbe723b4a662bd72fad76501d9ba0 Binary files /dev/null and b/slides/week7-concurrency-3.pdf differ