mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			146 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Chapel
		
	
	
	
	
	
			
		
		
	
	
			146 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Chapel
		
	
	
	
	
	
//
 | 
						|
// An example of a parallel quick sort implementation that uses
 | 
						|
// "cobegin" to make each recursive call in parallel and "serial" to
 | 
						|
// limit the number of threads.
 | 
						|
//
 | 
						|
 | 
						|
use Random, Time; // for random number generation and the Timer class
 | 
						|
 | 
						|
var timer: Timer; // to time the sort
 | 
						|
 | 
						|
config var n: int = 2**15;      // the size of the array to be sorted
 | 
						|
config var thresh: int = 1;     // the recursive depth to serialize
 | 
						|
config var verbose: int = 0;    // print out this many elements in array
 | 
						|
config var timing: bool = true; // set timing to false to disable timer
 | 
						|
 | 
						|
var A: [1..n] real; // array of real numbers
 | 
						|
 | 
						|
//
 | 
						|
// initialize array with random numbers
 | 
						|
//
 | 
						|
fillRandom(A);
 | 
						|
 | 
						|
//
 | 
						|
// print out front of array if verbose flag is set
 | 
						|
//
 | 
						|
if verbose > 0 then
 | 
						|
  writeln("A[1..", verbose, "] = ", A[1..verbose]);
 | 
						|
 | 
						|
//
 | 
						|
// start timer, call parallel quick sort routine, stop timer
 | 
						|
//
 | 
						|
if timing then timer.start();
 | 
						|
pqsort(A, thresh);
 | 
						|
if timing then timer.stop();
 | 
						|
 | 
						|
//
 | 
						|
// report sort time
 | 
						|
//
 | 
						|
if timing then writeln("sorted in ", timer.elapsed(), " seconds");
 | 
						|
 | 
						|
//
 | 
						|
// print out front of array if verbose flag is set
 | 
						|
//   values should now be in sorted order
 | 
						|
//
 | 
						|
if verbose > 0 then
 | 
						|
  writeln("A[1..", verbose, "] = ", A[1..verbose]);
 | 
						|
 | 
						|
//
 | 
						|
// verify that array is sorted or halt
 | 
						|
//
 | 
						|
for i in 2..n do
 | 
						|
  if A(i) < A(i-1) then
 | 
						|
    halt("A(", i-1, ") == ", A(i-1), " > A(", i, ") == ", A(i));
 | 
						|
 | 
						|
writeln("verification success");
 | 
						|
 | 
						|
//
 | 
						|
// pqsort -- parallel quick sort
 | 
						|
//
 | 
						|
//   arr: generic 1D array of values (real, int, ...)
 | 
						|
//   thresh: number of recursive calls to make before serializing
 | 
						|
//   low: lower bound of array to start sort at, defaults to whole array
 | 
						|
//   high: upper bound of array to stop sort at, defaults to whole array
 | 
						|
//
 | 
						|
proc pqsort(arr: [],
 | 
						|
           thresh: int,
 | 
						|
           low: int = arr.domain.low,
 | 
						|
           high: int = arr.domain.high) where arr.rank == 1 {
 | 
						|
 | 
						|
  //
 | 
						|
  // base case: arr[low..high] is small enough to bubble sort
 | 
						|
  //
 | 
						|
  if high - low < 8 {
 | 
						|
    bubbleSort(arr, low, high);
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // determine pivot and partition arr[low..high]
 | 
						|
  //
 | 
						|
  const pivotVal = findPivot();
 | 
						|
  const pivotLoc = partition(pivotVal);
 | 
						|
 | 
						|
  //
 | 
						|
  // make recursive calls to parallel quick sort each unsorted half of
 | 
						|
  // the array; if thresh is 0 or less, start executing conquer tasks
 | 
						|
  // serially
 | 
						|
  //
 | 
						|
  serial thresh <= 0 do cobegin {
 | 
						|
    pqsort(arr, thresh-1, low, pivotLoc-1);
 | 
						|
    pqsort(arr, thresh-1, pivotLoc+1, high);
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // findPivot -- helper routine to find pivot value using simple
 | 
						|
  //              median-of-3 method, returns pivot value
 | 
						|
  //
 | 
						|
  proc findPivot() {
 | 
						|
    const mid = low + (high-low+1) / 2;
 | 
						|
 | 
						|
    if arr(mid) < arr(low) then arr(mid) <=> arr(low);
 | 
						|
    if arr(high) < arr(low) then arr(high) <=> arr(low);
 | 
						|
    if arr(high) < arr(mid) then arr(high) <=> arr(mid);
 | 
						|
 | 
						|
    const pivotVal = arr(mid);
 | 
						|
    arr(mid) = arr(high-1);
 | 
						|
    arr(high-1) = pivotVal;
 | 
						|
 | 
						|
    return pivotVal;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // partition -- helper routine to partition array such that all
 | 
						|
  //              values less than pivot are to its left and all
 | 
						|
  //              values greater than pivot are to its right, returns
 | 
						|
  //              pivot location
 | 
						|
  //
 | 
						|
  proc partition(pivotVal) {
 | 
						|
    var ilo = low, ihi = high-1;
 | 
						|
    while (ilo < ihi) {
 | 
						|
      do { ilo += 1; } while arr(ilo) < pivotVal;
 | 
						|
      do { ihi -= 1; } while pivotVal < arr(ihi);
 | 
						|
      if (ilo < ihi) {
 | 
						|
        arr(ilo) <=> arr(ihi);
 | 
						|
      }
 | 
						|
    }
 | 
						|
    arr(high-1) = arr(ilo);
 | 
						|
    arr(ilo) = pivotVal;
 | 
						|
    return ilo;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
//
 | 
						|
// bubbleSort -- bubble sort for base case of quick sort
 | 
						|
//
 | 
						|
//   arr: generic 1D array of values (real, int, ...)
 | 
						|
//   low: lower bound of array to start sort at
 | 
						|
//   high: upper bound of array to stop sort at
 | 
						|
//
 | 
						|
proc bubbleSort(arr: [], low: int, high: int) where arr.rank == 1 {
 | 
						|
  for i in low..high do
 | 
						|
    for j in low..high-1 do
 | 
						|
      if arr(j) > arr(j+1) then
 | 
						|
        arr(j) <=> arr(j+1);
 | 
						|
}
 |