HW2: A validator added and small changes

This commit is contained in:
2024-12-31 12:54:58 +02:00
parent 9dd3eb737f
commit 36de8d94fc
7 changed files with 131 additions and 66 deletions
+59 -5
View File
@@ -43,6 +43,9 @@ bool get_options(int argc, char* argv[]){
status = false;
}
}
else if (arg == "--validation") {
session.validation = true;
}
else if (arg == "--ndebug") {
session.ndebug = true;
}
@@ -54,14 +57,16 @@ bool get_options(int argc, char* argv[]){
}
else if (arg == "-h" || arg == "--help") {
std::cout << "distbitonic/distbubbletonic - A distributed bitonic sort\n\n";
std::cout << "distbitonic -q <> [--ndebug] [-v]\n";
std::cout << "distbitonic -q <N> [--validation] [--ndebug] [-v]\n";
std::cout << "distbitonic -h\n";
std::cout << "distbubbletonic -q <> [--ndebug] [-v]\n";
std::cout << "distbubbletonic -q <N> [--validation] [--ndebug] [-v]\n";
std::cout << "distbubbletonic -h\n";
std::cout << '\n';
std::cout << "Options:\n\n";
std::cout << " -q | --array-size <size>\n";
std::cout << " Selects the array size according to size = 2^q\n\n";
std::cout << " -q | --array-size <N>\n";
std::cout << " Selects the array size according to size = 2^N\n\n";
std::cout << " --validation\n";
std::cout << " Request a full validation at the end, performed by process rank 0\n\n";
std::cout << " --ndebug\n";
std::cout << " Skip debug breakpoint when on debug build.\n\n";
std::cout << " -t | --timing\n";
@@ -87,6 +92,48 @@ bool get_options(int argc, char* argv[]){
return status;
}
/*!
* A simple validator for the entire distributed process
*
* @tparam ShadowedDataT A Shadowed buffer type with random access iterator.
*
* @param data [ShadowedDataT] The local to MPI process
* @param Processes [mpi_id_t] The total number of MPI processes
* @param rank [mpi_id_t] The current process id
*
* @return [bool] True if all are sorted and in total ascending order
*/
template<typename ShadowedDataT>
bool validator(ShadowedDataT& data, mpi_id_t Processes, mpi_id_t rank) {
using value_t = typename ShadowedDataT::value_type;
bool ret = true; // Have faith!
// Local results
value_t lmin = data.front();
value_t lmax = data.back();
value_t lsort = static_cast<value_t>(std::is_sorted(data.begin(), data.end()));
// Gather min/max/sort to rank 0
std::vector<value_t> mins(Processes);
std::vector<value_t> maxes(Processes);
std::vector<value_t> sorts(Processes);
MPI_Datatype datatype = MPI_TypeMapper<value_t>::getType();
MPI_Gather(&lmin, 1, datatype, mins.data(), 1, datatype, 0, MPI_COMM_WORLD);
MPI_Gather(&lmax, 1, datatype, maxes.data(), 1, datatype, 0, MPI_COMM_WORLD);
MPI_Gather(&lsort, 1, datatype, sorts.data(), 1, datatype, 0, MPI_COMM_WORLD);
// Check all results
if (rank == 0) {
for (mpi_id_t r = 1; r < Processes; ++r) {
if (sorts[r] == 0)
ret = false;
if (maxes[r - 1] > mins[r])
ret = false;
}
}
return ret;
}
#if !defined TESTING
int main(int argc, char* argv[]) try {
@@ -146,7 +193,14 @@ int main(int argc, char* argv[]) try {
std::string timeMsg = "rank " + std::to_string(mpi.rank());
timer.print_dt(timeMsg.c_str());
std::cout << "[Data]: Rank " << mpi.rank() << ": [" << +Data.front() << " .. " << +Data.back() << "]" << std::endl;
if (session.validation) {
// If requested, we have the chance to fail!
if (mpi.rank() == 0)
std::cout << "Results validation ...";
bool val = validator(Data, mpi.size(), mpi.rank());
if (mpi.rank() == 0)
std::cout << ((val) ? "\x1B[32m [PASS] \x1B[0m\n" : " \x1B[32m [FAIL] \x1B[0m\n");
}
mpi.finalize();
return 0;
}