HW2: RC4 - [Not tested] The final version

This commit is contained in:
2025-01-09 00:30:16 +02:00
parent 1b271de2a0
commit f849e8a309
7 changed files with 269 additions and 64 deletions
+7 -9
View File
@@ -10,13 +10,9 @@
#include "distsort.hpp"
//! Performance timers for each one of the "costly" functions
Timing TfullSort, Texchange, Tminmax, TelbowSort;
bool isActive(mpi_id_t node, size_t nodes) {
if (!((nodes > 0) &&
(nodes <= std::numeric_limits<mpi_id_t>::max()) ))
(nodes <= static_cast<size_t>(std::numeric_limits<mpi_id_t>::max())) ))
throw std::runtime_error("(isActive) Non-acceptable value of MPI Nodes\n");
// ^ Assert that mpi_id_t can hold nodes, and thus we can cast without data loss!
@@ -24,12 +20,14 @@ bool isActive(mpi_id_t node, size_t nodes) {
}
size_t tagGenerator(size_t depth, size_t step, size_t stage) {
auto stage_bits = static_cast<uint32_t>(std::log2(MAX_PIPELINE_SIZE));
auto step_bits = static_cast<uint32_t>(std::log2(MAX_MPI_SIZE));
auto stage_bits = static_cast<uint32_t>(std::log2(MAX_PIPELINE_SIZE));
auto step_bits = static_cast<uint32_t>(std::log2(MAX_MPI_SIZE));
uint32_t stat_bit = 1UL;
// ^ We use MPI_SIZE room for steps to fit the bubbletonic version
// [ depth | step | stage+stats ]
size_t tag = stage
| (step << stage_bits)
| (depth << (stage_bits + step_bits));
| (step << (stage_bits + stat_bit))
| (depth << (stage_bits + step_bits + stat_bit));
return tag;
}
+67 -24
View File
@@ -22,7 +22,36 @@ config_t config;
MPI_t<> mpi;
distBuffer_t Data;
Log logger;
Timing Ttotal;
distStat_t localStat, remoteStat;
//! Performance timers for each one of the "costly" functions
Timing Ttotal;
Timing TfullSort;
Timing Texchange;
Timing Tminmax;
Timing TelbowSort;
//! Init timing objects for extra rounds
void measurements_init() {
if (config.perf > 1) {
Ttotal.init(config.perf);
TfullSort.init(config.perf);
Texchange.init(config.perf);
Tminmax.init(config.perf);
TelbowSort.init(config.perf);
}
}
//! iterate ot the next round of measurements for all measurement objects
void measurements_next() {
if (config.perf > 1) {
Ttotal.next();
TfullSort.next();
Texchange.next();
Tminmax.next();
TelbowSort.next();
}
}
/*!
* A small command line argument parser
@@ -43,6 +72,9 @@ bool get_options(int argc, char* argv[]){
status = false;
}
}
else if (arg == "-e" || arg == "--exchange-opt") {
config.exchangeOpt = true;
}
else if (arg == "--pipeline") {
if (i+1 < argc) {
auto stages = atoi(argv[++i]);
@@ -59,7 +91,12 @@ bool get_options(int argc, char* argv[]){
config.validation = true;
}
else if (arg == "--perf") {
config.perf = true;
if (i+1 < argc) {
config.perf = atoi(argv[++i]);
}
else {
status = false;
}
}
else if (arg == "--ndebug") {
config.ndebug = true;
@@ -68,22 +105,25 @@ bool get_options(int argc, char* argv[]){
config.verbose = true;
}
else if (arg == "-h" || arg == "--help") {
std::cout << "distbitonic/distbubbletonic - A distributed bitonic sort\n\n";
std::cout << "distbitonic -q <N> [--pipeline N] [--validation] [--ndebug] [-v]\n";
std::cout << "distbitonic/distbubbletonic - A distributed sort utility\n\n";
std::cout << "distbitonic -q <N> [-e] [-p | --pipeline N] [--validation] [--perf] [--ndebug] [-v]\n";
std::cout << "distbitonic -h\n";
std::cout << "distbubbletonic -q <N> [--pipeline N] [--validation] [--ndebug] [-v]\n";
std::cout << "distbubbletonic -q <N> [-e] [-p | --pipeline N] [--validation] [--perf] [--ndebug] [-v]\n";
std::cout << "distbubbletonic -h\n";
std::cout << '\n';
std::cout << "Options:\n\n";
std::cout << " -q | --array-size <N>\n";
std::cout << " Selects the array size according to size = 2^N\n\n";
std::cout << " --pipeline <N>\n";
std::cout << " -e | --exchange-opt\n";
std::cout << " Request an MPI data exchange optimization \n\n";
std::cout << " -p <N> | --pipeline <N>\n";
std::cout << " Request a pipeline of <N> stages for exchange-minmax\n";
std::cout << " N must be power of 2 up to " << MAX_PIPELINE_SIZE << "\n\n";
std::cout << " --validation\n";
std::cout << " Request a full validation at the end, performed by process rank 0\n\n";
std::cout << " --perf\n";
std::cout << " Request performance timing measurements to stdout.\n\n";
std::cout << " --perf <N> \n";
std::cout << " Enable performance timing measurements and prints, and repeat\n";
std::cout << " the sorting <N> times to average the measurements\n\n";
std::cout << " --ndebug\n";
std::cout << " Skip debug breakpoint when on debug build.\n\n";
std::cout << " -v | --verbose\n";
@@ -167,8 +207,8 @@ int main(int argc, char* argv[]) try {
" Size: " << mpi.size() <<
logger.endl;
#if defined DEBUG
#if defined TESTING
#if defined DEBUG
#if defined TESTING
/*
* In case of a debug build we will wait here until sleep_wait
* will reset via debugger. In order to do that the user must attach
@@ -179,12 +219,12 @@ int main(int argc, char* argv[]) try {
* $> gdb <program> <PID2>
*/
volatile bool sleep_wait = false;
#else
#else
volatile bool sleep_wait = true;
#endif
#endif
while (sleep_wait && !config.ndebug)
sleep(1);
#endif
#endif
// Initialize local data
logger << "Initialize local array of " << config.arraySize << " elements" << logger.endl;
@@ -201,24 +241,27 @@ int main(int argc, char* argv[]) try {
// Run distributed sort
if (mpi.rank() == 0)
logger << "Starting distributed sorting ... ";
Ttotal.start();
measurements_init();
for (size_t it = 0 ; it < config.perf ; ++it) {
Ttotal.start();
#if CODE_VERSION == BUBBLETONIC
distBubbletonic(Data, mpi.size(), mpi.rank());
distBubbletonic(Data, mpi.size(), mpi.rank());
#else
distBitonic (Data, mpi.size(), mpi.rank());
distBitonic(Data, mpi.size(), mpi.rank());
#endif
Ttotal.stop();
Ttotal.stop();
measurements_next();
}
if (mpi.rank() == 0)
logger << " Done." << logger.endl;
// Print-outs and validation
if (config.perf) {
Ttotal.print_duration("Total ", mpi.rank());
TfullSort.print_duration("Full-Sort ", mpi.rank());
Texchange.print_duration("Exchange ", mpi.rank());
Tminmax.print_duration("Min-Max ", mpi.rank());
TelbowSort.print_duration("Elbow-Sort", mpi.rank());
if (config.perf > 1) {
Timing::print_duration(Ttotal.median(), "Total ", mpi.rank());
Timing::print_duration(TfullSort.median(), "Full-Sort ", mpi.rank());
Timing::print_duration(Texchange.median(), "Exchange ", mpi.rank());
Timing::print_duration(Texchange.median(), "Min-Max ", mpi.rank());
Timing::print_duration(TelbowSort.median(),"Elbow-Sort", mpi.rank());
}
if (config.validation) {
// If requested, we have the chance to fail!