SDSU 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

How about this?
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 )

process administrator
	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

end administrator

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 
xprocess administrator
	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

		receive sortedSublist( sublist, workerId )

		# determine location of sublist in sorted list
		var startIndex : int := (workerId - 1 )* workerPortion + 1
		var endIndex : int := startIndex + workerPortion  - 1

		sortedData[ startIndex  : endIndex ] := sublist 
	af
end

----------