Skip to content
Snippets Groups Projects
Verified Commit bb39fae2 authored by Sankalp Gambhir's avatar Sankalp Gambhir
Browse files

Update convolution solution

parent bbe14e29
No related branches found
No related tags found
No related merge requests found
Pipeline #157663 failed
...@@ -16,13 +16,30 @@ def sequentialConvolve( ...@@ -16,13 +16,30 @@ def sequentialConvolve(
from: Int, from: Int,
until: Int until: Int
): Unit = { ): Unit = {
// Approach A, as described in the clarification announcement for this
// exercise, where we treat `from` and `until` as indices on `output`
// instead of `input` as in the given code.
var iOutput = from var iOutput = from
while iOutput < until do while iOutput < until do
var iKernel = math.max(0, iOutput - input.length + 1) var iKernel = math.max(0, iOutput - input.length + 1)
while iKernel < kernel.length && iKernel <= iOutput do while iKernel < kernel.length && iKernel <= iOutput do
// `output` is only ever written to between the indices `from` and
// `until`, the range of `iOutput`. The indices for `input` and
// `kernel` are computed accordingly.
output(iOutput) += input(iOutput - iKernel) * kernel(iKernel) output(iOutput) += input(iOutput - iKernel) * kernel(iKernel)
iKernel += 1 iKernel += 1
iOutput += 1 iOutput += 1
// ALTERNATE SOLUTION: Approach B, as described in the clarification
// announcement for this exercise, which is unchanged from the given
// code, i.e. we treat `from` and `until` as indices on `input`.
var iInput = from
while iInput < until do
var iKernel = 0
while iKernel < kernel.length do
output(iInput + iKernel) += input(iInput) * kernel(iKernel)
iKernel += 1
iInput += 1
} }
def parallelConvolve( def parallelConvolve(
...@@ -32,7 +49,12 @@ def parallelConvolve( ...@@ -32,7 +49,12 @@ def parallelConvolve(
from: Int, from: Int,
until: Int, until: Int,
threshold: Int threshold: Int
): Unit = ): Unit =
// Approach A, as described in the clarification announcement for this
// exercise, where we treat `from` and `until` as indices on `output`
// instead of `input` as in the given code. This does not require us to
// change anything in this function. Only receives full credit if used
// together with Approach A for `sequentialConvolve`.
if (until - from) <= threshold then if (until - from) <= threshold then
sequentialConvolve(input, kernel, output, from, until) sequentialConvolve(input, kernel, output, from, until)
else else
...@@ -42,6 +64,31 @@ def parallelConvolve( ...@@ -42,6 +64,31 @@ def parallelConvolve(
parallelConvolve(input, kernel, output, mid, until, threshold) parallelConvolve(input, kernel, output, mid, until, threshold)
) )
// ALTERNATE SOLUTION: Approach B, as described in the clarification
// announcement for this exercise, where we treat `from` and `until` as
// indices on `input` as in the given code. This requires up to leave a
// gap in the parallel calls to be filled in sequentially as described
// below. Only receives full credit if used together with Approach B for
// `sequentialConvolve`.
if (until - from) <= threshold then
sequentialConvolve(input, kernel, output, from, until)
else
val mid = from + (until - from) / 2
val gap = numContributeTo(input, kernel, output, mid)
// Leave a gap large enough that accesses to `output` from the first
// parallel call will not overlap with accesses from the second. This
// gap is of size equal to the number of elements of `input` that will
// contribute to the computation of the result at the lowest index of
// `output` in the second parallel call, namely, at index `mid`.
// However, we are careful not to access indices lower than `from`.
val gapBeforeMid = Math.max(from, mid - gap + 1)
parallel(
parallelConvolve(input, kernel, output, from, gapBeforeMid, threshold),
parallelConvolve(input, kernel, output, mid, until, threshold)
)
// Fill in the gap after the two parallel calls above have finished.
parallelConvolve(input, kernel, output, gapBeforeMid, mid, threshold)
object Original_WithOutputRace: object Original_WithOutputRace:
def sequentialConvolve( def sequentialConvolve(
...@@ -50,15 +97,13 @@ object Original_WithOutputRace: ...@@ -50,15 +97,13 @@ object Original_WithOutputRace:
output: Array[Int], output: Array[Int],
from: Int, from: Int,
until: Int): Unit = until: Int): Unit =
var iOutput = from var iInput = from
while iOutput < until do while iInput < until do
var iKernel = 0 var iKernel = 0
while iKernel < kernel.length do while iKernel < kernel.length do
val iInput = iOutput - iKernel output(iInput + iKernel) += input(iInput) * kernel(iKernel)
if 0 <= iInput && iInput < input.length then
output(iOutput) += input(iInput) * kernel(iKernel)
iKernel += 1 iKernel += 1
iOutput += 1 iInput += 1
def parallelConvolve( def parallelConvolve(
input: Array[Int], input: Array[Int],
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment