## CS 662 Theory of Parallel Algorithms Solution Assignment 1

[To Lecture Notes Index]
San Diego State University -- This page last updated March 28, 1996, 1996

Barrier
Basic Idea
```var  N : int 	#size of Array
getarg( 1 , N )

sem signalWorker[0 : N -1 ] :=  ( [ N ] 0  )

var numberOfStages : int := int( ceil( log( N, 2 ) ) )

process  worker (  id  := 0 to N - 1 )

do  ( some condition) ->

# do one stage of real work here

# now for the barrier

var  stage : int
var  jump : int
fa  stage := 0 to (numberOfStages - 1 ) ->
jump := 2**stage
V( signalWorker[ ( id + jump ) mod N ] )
P( signalWorker[ id ] )
af
od

end worker
```

```var  N : int 	#size of Array
getarg( 1 , N )

sem ba[0 : N -1 ] :=  ( [ N ] 0  )

var s : int := int( ceil( log( N, 2 ) ) )

process  worker (  i  := 0 to N - 1 )

do  ( some condition) ->

# do one sn of real work here

# now for the barrier
var  sn : int
var  k : int
# do the stages
fa  sn := 0 to (s - 1 ) ->
k := 2**sn
V( ba[ ( i + k ) mod N ] )
P( ba[ i ] )
af
od

end worker

```

QuickSort
```op quickSort( unsorted[ 1: N],  startIndex,  endIndex : int )

op sortedArray( sorted[ 1 : N ] ,  startIndex,  endIndex : int )

var unsortedData[ 1 : N ]  : int :=  getDataToSort();
var sortedData[ 1 : N ]  : int
var numberNotYetSorted : int  := N

send  quickSort( unsortedData, 1,  N )

# Collect sorted sublists of data
do numberNotYetSorted > 0 ->
var partialSorted[ 1 : N ]  : int
var startIndex : int
var endIndex : int

receive sortedArray( partialSorted, startIndex , endIndex )

sortedData[ startIndex : endIndex ] :=
partialSorted[ startIndex : endIndex ]

numberNotYetSorted := numberNotYetSorted -
(endIndex - startIndex + 1)
od

# terminate workers
fa  index := 1 to NumberOfWorkers
send  quickSort( unsortedData, DoneSortingFlag ,
DoneSortingFlag  )
af

process worker(  id : = 1 to NumberOfWorkers )

var startIndex : int
var endIndex : int
var dataToSort[ 1 : N ]

do  true  ->
receive  quickSort( dataToSort, startIndex , endIndex )

# check if done sorting
if endIndex = DoneSortingFlag -> exit

# sort small lists directly
if  (endIndex - startIndex + 1 ) <= SmallSortSize ->
insertionSort( dataToSort, startIndex, endIndex )
send sortedArray( dataToSort, startIndex, endIndex )

# handle large list via parallelized quicksort
[] else
var splitIndex : int
splitIndex  =  partition( dataToSort, startIndex, endIndex )

send quickSort( dataToSort, startIndex, splitIndex - 1)
send sortedArray( dataToSort, splitIndex , splitIndex )
send quickSort( dataToSort, splitIndex + 1, endIndex )
fi
od

end worker

procedure partition 	#standard quicksort partition
```
Compare Exchange
```var N : int
var numberOfWorkers : int

var workerPortion : int  :=  ceil( N / numberOfWorkers )

op up[ 0 : numberOfWorkers + 1 ] ( element : int )
op down[ 0 : numberOfWorkers + 1 ] ( element : int )

op  rawData[1:numberOfWorkers ] ( unsorted[ 1: workerPortion ] : int )
op  sortedSublist( sorted[ 1: workerPortion ] : int, workerId : int )

process worker(  id : = 1 to NumberOfWorkers )

var  dataElements[ 1 : workerPortion ]

receive rawData[ id ]( dataElements )
sequentialQuickSort( dataElements )

# Exchange data with neighbors
fa iteration = 1 to ceil( N / 2 )

var  smallCandidate : int
var  largeCandidate : int

send      up[ id + 1 ]( dataElements[ ub( dataElements ) ] )
send      down[ id - 1 ]( dataElements[ lb( dataElements ) ] )

receive  up[ id ] ( smallCandidate)
receive  down[ id ] ( largeCandidate)

addCandidates( dataElements, smallCandidate , largeCandidate )
af

send sortedSublist( dataElements, id )
end
var unsortedData[ 1 : N ]  : int :=  getDataToSort();
var sortedData[ 1 : N ]  : int

#Send data to workers
int startIndex : int := 1
int workerId : int := 1

fa  endIndex = workerPortion  to N - 1 by numberOfWorkers  ->
send rawData[workerId ]( unsortedData[ startIndex : endIndex ] )
startIndex := endIndex + 1
workerId++
af

# Collect sorted data
fa  index = 1 to numberOfWorkers  ->
var sublist[ 1 : workerPortion  ]  : int
var workerId : int