-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
104 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
#include <iostream> | ||
#include <string> | ||
#include <random> | ||
|
||
#include <parlay/io.h> | ||
#include <parlay/primitives.h> | ||
#include <parlay/random.h> | ||
#include <parlay/sequence.h> | ||
|
||
#include "counting_sort.h" | ||
|
||
// ************************************************************** | ||
// Driver | ||
// ************************************************************** | ||
int main(int argc, char* argv[]) { | ||
auto usage = "Usage: counting_sort <n>"; | ||
if (argc != 2) std::cout << usage << std::endl; | ||
else { | ||
long n; | ||
try { n = std::stol(argv[1]); } | ||
catch (...) { std::cout << usage << std::endl; return 1; } | ||
|
||
long num_buckets = 256; | ||
long num_partitions = std::min<long>(1000l, n / (256 * 16) + 1); | ||
|
||
parlay::random_generator gen; | ||
std::uniform_int_distribution<long> dis(0, num_buckets - 1); | ||
|
||
// generate random long values | ||
auto data = parlay::tabulate(n, [&] (long i) { | ||
auto r = gen[i]; | ||
return dis(r);}); | ||
|
||
parlay::internal::timer t("Time"); | ||
parlay::sequence<long> result; | ||
for (int i=0; i < 5; i++) { | ||
result = data; | ||
t.start(); | ||
result = counting_sort(data, data, num_buckets, num_partitions); | ||
t.next("counting_sort"); | ||
} | ||
|
||
auto first_ten = result.head(10); | ||
auto last_ten = result.tail(10); | ||
std::cout << "first 10 elements: " << parlay::to_chars(first_ten) << std::endl; | ||
std::cout << "last 10 elements: " << parlay::to_chars(last_ten) << std::endl; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
#include <algorithm> | ||
#include <functional> | ||
|
||
#include <parlay/parallel.h> | ||
#include <parlay/sequence.h> | ||
#include <parlay/primitives.h> | ||
|
||
template <typename T, typename Keys> | ||
parlay::sequence<T> counting_sort(const parlay::sequence<T>& in, const Keys& keys, | ||
long num_buckets, long num_parts) { | ||
long n = in.size(); | ||
long part_size = (n - 1)/num_parts + 1; | ||
|
||
auto all_counts = parlay::tabulate(num_parts, [&] (long i) { | ||
long start = i * part_size; | ||
long end = std::min<long>(start + part_size, n); | ||
parlay::sequence<int> local_counts(num_buckets, 0); | ||
for (size_t j = start; j < end; j++) local_counts[keys[j]]++; | ||
return local_counts;}, 1); | ||
|
||
// need to transpose the counts for the scan | ||
auto counts = parlay::sequence<int>::uninitialized(num_buckets * num_parts); | ||
parlay::parallel_for(0, num_buckets, [&] (long i) { | ||
for (size_t j = 0; j < num_parts; j++) | ||
counts[i* num_parts + j] = all_counts[j][i];}, 1); | ||
all_counts.clear(); | ||
|
||
// scan for offsets for all buckets | ||
parlay::scan_inplace(counts); | ||
|
||
auto out = parlay::sequence<T>::uninitialized(n); | ||
|
||
// go back over partitions to place in final location | ||
parlay::parallel_for(0, num_parts, [&] (long i) { | ||
long start = i * part_size; | ||
long end = std::min<long>(start + part_size, n); | ||
parlay::sequence<int> local_offsets(num_buckets, 0); | ||
|
||
// transpose back | ||
for (int j = 0; j < num_buckets; j++) | ||
local_offsets[j] = counts[num_parts * j + i]; | ||
|
||
// copy to output | ||
for (size_t j = start; j < end; j++) { | ||
int k = local_offsets[keys[j]]++; | ||
__builtin_prefetch (((char*) &out[k]) + 64); | ||
out[k] = in[j]; | ||
}}, 1); | ||
return out; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters