Skip to content

Commit 855fd9c

Browse files
committed
refactors to ParallelProg/w2
1 parent 5869bda commit 855fd9c

File tree

9 files changed

+110
-168
lines changed

9 files changed

+110
-168
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
course := "parprog1"
22
assignment := "reductions"
33

4-
scalaVersion := "3.0.0"
4+
scalaVersion := "3.4.2"
55
scalacOptions ++= Seq("-language:implicitConversions", "-deprecation")
66
libraryDependencies ++= Seq(
7-
("com.storm-enroute" %% "scalameter-core" % "0.21")
8-
.cross(CrossVersion.for3Use2_13),
9-
"org.scala-lang.modules" %% "scala-parallel-collections" % "1.0.3",
10-
"org.scalameta" %% "munit" % "0.7.26" % Test
7+
("com.storm-enroute" %% "scalameter-core" % "0.21").cross(CrossVersion.for3Use2_13),
8+
"org.scala-lang.modules" %% "scala-parallel-collections" % "1.0.4",
9+
"org.scalameta" %% "munit" % "1.0.0" % Test
1110
)
1211

1312
testFrameworks += new TestFramework("munit.Framework")
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
sbt.version=1.5.0
1+
sbt.version=1.10.0

courses/ParallelProg/w2/reductions/src/main/scala/reductions/Interfaces.scala

+23-11
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,38 @@ package reductions
22

33
// Interfaces used by the grading infrastructure. Do not change signatures
44
// or your submission will fail with a NoSuchMethodError.
5-
65
trait LineOfSightInterface:
76
def lineOfSight(input: Array[Float], output: Array[Float]): Unit
87
def upsweepSequential(input: Array[Float], from: Int, until: Int): Float
98
def upsweep(input: Array[Float], from: Int, end: Int, threshold: Int): Tree
10-
def downsweepSequential(input: Array[Float], output: Array[Float],
11-
startingAngle: Float, from: Int, until: Int): Unit
12-
def downsweep(input: Array[Float], output: Array[Float],
13-
startingAngle: Float, tree: Tree): Unit
14-
def parLineOfSight(input: Array[Float], output: Array[Float],
15-
threshold: Int): Unit
9+
def downsweepSequential(
10+
input: Array[Float],
11+
output: Array[Float],
12+
startingAngle: Float,
13+
from: Int,
14+
until: Int
15+
): Unit
16+
def downsweep(
17+
input: Array[Float],
18+
output: Array[Float],
19+
startingAngle: Float,
20+
tree: Tree
21+
): Unit
22+
def parLineOfSight(input: Array[Float], output: Array[Float], threshold: Int): Unit
1623

1724
trait ParallelCountChangeInterface:
1825
def countChange(money: Int, coins: List[Int]): Int
19-
def parCountChange(money: Int, coins: List[Int],
20-
threshold: (Int, List[Int]) => Boolean): Int
26+
def parCountChange(
27+
money: Int,
28+
coins: List[Int],
29+
threshold: (Int, List[Int]) => Boolean
30+
): Int
2131
def moneyThreshold(startingMoney: Int): (Int, List[Int]) => Boolean
2232
def totalCoinsThreshold(totalCoins: Int): (Int, List[Int]) => Boolean
23-
def combinedThreshold(startingMoney: Int, allCoins: List[Int])
24-
: (Int, List[Int]) => Boolean
33+
def combinedThreshold(
34+
startingMoney: Int,
35+
allCoins: List[Int]
36+
): (Int, List[Int]) => Boolean
2537

2638
trait ParallelParenthesesBalancingInterface:
2739
def balance(chars: Array[Char]): Boolean

courses/ParallelProg/w2/reductions/src/main/scala/reductions/LineOfSight.scala

+11-16
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,24 @@ package reductions
33
import org.scalameter.*
44

55
object LineOfSightRunner:
6-
76
val standardConfig = config(
87
Key.exec.minWarmupRuns := 40,
98
Key.exec.maxWarmupRuns := 80,
109
Key.exec.benchRuns := 100,
1110
Key.verbose := false
12-
) withWarmer (Warmer.Default())
11+
).withWarmer(Warmer.Default())
1312

14-
def main(args: Array[String]): Unit =
13+
def main: Unit =
1514
val length = 10000000
1615
val input = (0 until length).map(_ % 100 * 1.0f).toArray
1716
val output = new Array[Float](length + 1)
18-
val seqtime = standardConfig.measure(LineOfSight.lineOfSight(input, output))
1917

18+
val seqtime = standardConfig.measure(LineOfSight.lineOfSight(input, output))
2019
println(s"sequential time: $seqtime")
2120

2221
val partime = standardConfig.measure(LineOfSight.parLineOfSight(input, output, 10000))
23-
2422
println(s"parallel time: $partime")
23+
2524
println(s"speedup: ${seqtime.value / partime.value}")
2625

2726
enum Tree(val maxPrevious: Float):
@@ -30,7 +29,6 @@ enum Tree(val maxPrevious: Float):
3029
extends Tree(maxPrevious)
3130

3231
object LineOfSight extends LineOfSightInterface:
33-
3432
def lineOfSight(input: Array[Float], output: Array[Float]): Unit = // TODO
3533
output(0) = 0
3634
var maximum: Float = 0
@@ -40,23 +38,20 @@ object LineOfSight extends LineOfSightInterface:
4038
output(i) = maximum
4139
i = i + 1
4240

43-
/** Traverses the specified part of the array and returns the maximum angle.
44-
*/
45-
def upsweepSequential(input: Array[Float], from: Int, until: Int): Float =
46-
var maximum: Float = 0 // TODO
41+
/* Traverses the specified part of the array and returns the maximum angle. */
42+
def upsweepSequential(input: Array[Float], from: Int, until: Int): Float = // TODO
43+
var maximum: Float = 0
4744
var i: Int = from
4845
while i < until do
4946
maximum = math.max(maximum, input(i) / i)
5047
i = i + 1
5148
maximum
5249

5350
/** Traverses the part of the array starting at `from` and until `end`, and returns the
54-
* reduction tree for that part of the array.
55-
*
56-
* The reduction tree is a `Tree.Leaf` if the length of the specified part of the array
57-
* is smaller or equal to `threshold`, and a `Tree.Node` otherwise. If the specified
58-
* part of the array is longer than `threshold`, then the work is divided and done
59-
* recursively in parallel.
51+
* reduction tree for that part of the array. The reduction tree is a `Tree.Leaf` if
52+
* the length of the specified part of the array is smaller or equal to `threshold`,
53+
* and a `Tree.Node` otherwise. If the specified part of the array is longer than
54+
* `threshold`, then the work is divided and done recursively in parallel.
6055
*/
6156
def upsweep(input: Array[Float], from: Int, end: Int, threshold: Int): Tree = // TODO
6257
if end - from <= threshold then // if I use < only, I get stackOverFlow

courses/ParallelProg/w2/reductions/src/main/scala/reductions/ParallelCountChange.scala

+9-19
Original file line numberDiff line numberDiff line change
@@ -11,31 +11,24 @@ object ParallelCountChangeRunner:
1111
Key.exec.maxWarmupRuns := 40,
1212
Key.exec.benchRuns := 80,
1313
Key.verbose := false
14-
) withWarmer (Warmer.Default())
14+
).withWarmer(Warmer.Default())
1515

16-
def main(args: Array[String]): Unit =
16+
def main: Unit =
1717
val amount = 250
1818
val coins = List(1, 2, 5, 10, 20, 50)
19-
val seqtime = standardConfig measure {
19+
val seqtime = standardConfig.measure:
2020
seqResult = ParallelCountChange.countChange(amount, coins)
21-
}
22-
2321
println(s"sequential result = $seqResult")
2422
println(s"sequential count time: $seqtime")
2523

2624
def measureParallelCountChange(threshold: => ParallelCountChange.Threshold): Unit =
2725
try
28-
val fjtime = standardConfig measure {
26+
val fjtime = standardConfig.measure:
2927
parResult = ParallelCountChange.parCountChange(amount, coins, threshold)
30-
}
31-
3228
println(s"parallel result = $parResult")
3329
println(s"parallel count time: $fjtime")
3430
println(s"speedup: ${seqtime.value / fjtime.value}")
35-
36-
catch
37-
case e: NotImplementedError =>
38-
println("Not implemented.")
31+
catch case e: NotImplementedError => println("Not implemented.")
3932

4033
println("\n# Using moneyThreshold\n")
4134
measureParallelCountChange(ParallelCountChange.moneyThreshold(amount))
@@ -47,7 +40,6 @@ object ParallelCountChangeRunner:
4740
measureParallelCountChange(ParallelCountChange.combinedThreshold(amount, coins))
4841

4942
object ParallelCountChange extends ParallelCountChangeInterface:
50-
5143
/** Returns the number of ways change can be made from the specified list of coins for
5244
* the specified amount of money.
5345
*/
@@ -56,18 +48,16 @@ object ParallelCountChange extends ParallelCountChangeInterface:
5648
case 0 => 1
5749
case _ =>
5850
coins match
59-
case Nil => 0
60-
case head :: tail =>
61-
countChange(money - head, coins) + countChange(money, tail)
51+
case Nil => 0
52+
case head :: tail => countChange(money - head, coins) + countChange(money, tail)
6253

6354
type Threshold = (Int, List[Int]) => Boolean
6455

6556
/** In parallel, counts the number of ways change can be made from the specified list of
6657
* coins for the specified amount of money.
6758
*/
68-
def parCountChange(money: Int, coins: List[Int], threshold: Threshold): Int =
69-
if threshold(money, coins) // TODO
70-
then countChange(money, coins)
59+
def parCountChange(money: Int, coins: List[Int], threshold: Threshold): Int = // TODO
60+
if threshold(money, coins) then countChange(money, coins)
7161
else
7262
money match
7363
case m if m < 0 => 0

courses/ParallelProg/w2/reductions/src/main/scala/reductions/ParallelParenthesesBalancing.scala

+8-17
Original file line numberDiff line numberDiff line change
@@ -12,37 +12,30 @@ object ParallelParenthesesBalancingRunner:
1212
Key.exec.maxWarmupRuns := 80,
1313
Key.exec.benchRuns := 120,
1414
Key.verbose := false
15-
) withWarmer (Warmer.Default())
15+
).withWarmer(Warmer.Default())
1616

17-
def main(args: Array[String]): Unit =
17+
def main: Unit =
1818
val length = 100000000
1919
val threshold = 10000
20-
2120
val openParens = Array.fill(length / 4)('(')
2221
val closeParens = Array.fill(length / 4)(')')
23-
2422
val chars = openParens ++ closeParens ++ openParens ++ closeParens
2523
// val chars = new Array[Char](length)
2624

27-
val seqtime = standardConfig measure {
25+
val seqtime = standardConfig.measure:
2826
seqResult = ParallelParenthesesBalancing.balance(chars)
29-
}
30-
3127
println(s"sequential result = $seqResult")
3228
println(s"sequential balancing time: $seqtime")
3329

34-
val fjtime = standardConfig measure {
30+
val fjtime = standardConfig.measure:
3531
parResult = ParallelParenthesesBalancing.parBalance(chars, threshold)
36-
}
37-
3832
println(s"parallel result = $parResult")
3933
println(s"parallel balancing time: $fjtime")
34+
4035
println(s"speedup: ${seqtime.value / fjtime.value}")
4136

4237
object ParallelParenthesesBalancing extends ParallelParenthesesBalancingInterface:
43-
44-
/** Returns `true` iff the parentheses in the input `chars` are balanced.
45-
*/
38+
/* Returns `true` iff the parentheses in the input `chars` are balanced. */
4639
def balance(chars: Array[Char]): Boolean = // TODO
4740
@annotation.tailrec
4841
def helper(left: Int, right: Int, chars: Array[Char]): Boolean =
@@ -55,8 +48,7 @@ object ParallelParenthesesBalancing extends ParallelParenthesesBalancingInterfac
5548
case _ => helper(left, right, chars.tail)
5649
helper(0, 0, chars)
5750

58-
/** Returns `true` iff the parentheses in the input `chars` are balanced.
59-
*/
51+
/* Returns `true` iff the parentheses in the input `chars` are balanced. */
6052
def parBalance(chars: Array[Char], threshold: Int): Boolean = // TODO
6153
@annotation.tailrec
6254
def traverse(idx: Int, until: Int, arg1: Int, arg2: Int): (Int, Int) =
@@ -69,8 +61,7 @@ object ParallelParenthesesBalancing extends ParallelParenthesesBalancingInterfac
6961
case _ => traverse(idx + 1, until, arg1, arg2)
7062

7163
def reduce(from: Int, until: Int): (Int, Int) = // TODO
72-
if until - from <= threshold
73-
then traverse(from, until, 0, 0)
64+
if until - from <= threshold then traverse(from, until, 0, 0)
7465
else
7566
val mid: Int = (until - from) / 2 + from
7667
val ((l1, r1), (l2, r2)) = parallel(reduce(from, mid), reduce(mid, until))

courses/ParallelProg/w2/reductions/src/main/scala/reductions/common.scala

+11-8
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@ package reductions
22

33
import java.util.concurrent.*
44
import scala.util.DynamicVariable
5-
65
import org.scalameter.*
76

87
val forkJoinPool = ForkJoinPool()
98

109
abstract class TaskScheduler:
1110
def schedule[T](body: => T): ForkJoinTask[T]
1211
def parallel[A, B](taskA: => A, taskB: => B): (A, B) =
13-
val right = task { taskB }
12+
val right = task(taskB)
1413
val left = taskA
1514
(left, right.join())
1615

@@ -21,7 +20,7 @@ class DefaultTaskScheduler extends TaskScheduler:
2120

2221
Thread.currentThread match
2322
case wt: ForkJoinWorkerThread => t.fork()
24-
case _ => forkJoinPool.execute(t)
23+
case _ => forkJoinPool.execute(t)
2524
t
2625

2726
val scheduler = DynamicVariable[TaskScheduler](DefaultTaskScheduler())
@@ -31,10 +30,14 @@ def task[T](body: => T): ForkJoinTask[T] = scheduler.value.schedule(body)
3130
def parallel[A, B](taskA: => A, taskB: => B): (A, B) =
3231
scheduler.value.parallel(taskA, taskB)
3332

34-
def parallel[A, B, C, D](taskA: => A, taskB: => B,
35-
taskC: => C, taskD: => D): (A, B, C, D) =
36-
val ta = task { taskA }
37-
val tb = task { taskB }
38-
val tc = task { taskC }
33+
def parallel[A, B, C, D](
34+
taskA: => A,
35+
taskB: => B,
36+
taskC: => C,
37+
taskD: => D
38+
): (A, B, C, D) =
39+
val ta = task(taskA)
40+
val tb = task(taskB)
41+
val tc = task(taskC)
3942
val td = taskD
4043
(ta.join(), tb.join(), tc.join(), td)

0 commit comments

Comments
 (0)