HW2: Add an MPI wrapper for the basic functionality and update all types
This commit is contained in:
@@ -10,15 +10,9 @@
|
||||
#ifndef DISTBITONIC_H_
|
||||
#define DISTBITONIC_H_
|
||||
|
||||
#if !defined DEBUG
|
||||
#define NDEBUG
|
||||
#endif
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include "utils.hpp"
|
||||
|
||||
#include <vector>
|
||||
#if !defined TESTING
|
||||
#include <mpi.h>
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Enumerator for the different versions of the sorting method
|
||||
@@ -31,14 +25,6 @@ enum class SortMode {
|
||||
using Data_t = std::vector<uint8_t>;
|
||||
using AllData_t = std::vector<Data_t>;
|
||||
|
||||
struct mpi_t {
|
||||
size_t world_size{};
|
||||
size_t world_rank{};
|
||||
std::string processor_name {};
|
||||
};
|
||||
|
||||
extern mpi_t mpi;
|
||||
|
||||
/*
|
||||
* ============================== Sort utilities ==============================
|
||||
*/
|
||||
@@ -47,41 +33,41 @@ extern mpi_t mpi;
|
||||
* The primary function template of ascending(). It is DISABLED since , it is explicitly specialized
|
||||
* for each of the \c SortMode
|
||||
*/
|
||||
template <SortMode Mode> bool ascending(size_t, [[maybe_unused]] size_t) noexcept = delete;
|
||||
template <> bool ascending<SortMode::Bubbletonic>(size_t node, [[maybe_unused]] size_t depth) noexcept;
|
||||
template <> bool ascending<SortMode::Bitonic>(size_t node, size_t depth) noexcept;
|
||||
template <SortMode Mode> bool ascending(mpi_id_t, [[maybe_unused]] size_t) noexcept = delete;
|
||||
template <> bool ascending<SortMode::Bubbletonic>(mpi_id_t node, [[maybe_unused]] size_t depth) noexcept;
|
||||
template <> bool ascending<SortMode::Bitonic>(mpi_id_t node, size_t depth) noexcept;
|
||||
|
||||
/*!
|
||||
* The primary function template of partner(). It is DISABLED since , it is explicitly specialized
|
||||
* for each of the \c SortMode
|
||||
*/
|
||||
template <SortMode Mode> size_t partner(size_t, size_t) noexcept = delete;
|
||||
template <> size_t partner<SortMode::Bubbletonic>(size_t node, size_t step) noexcept;
|
||||
template <> size_t partner<SortMode::Bitonic>(size_t node, size_t step) noexcept;
|
||||
template <SortMode Mode> mpi_id_t partner(mpi_id_t, size_t) noexcept = delete;
|
||||
template <> mpi_id_t partner<SortMode::Bubbletonic>(mpi_id_t node, size_t step) noexcept;
|
||||
template <> mpi_id_t partner<SortMode::Bitonic>(mpi_id_t node, size_t step) noexcept;
|
||||
|
||||
/*!
|
||||
* The primary function template of keepsmall(). It is DISABLED since , it is explicitly specialized
|
||||
* The primary function template of keepSmall(). It is DISABLED since , it is explicitly specialized
|
||||
* for each of the \c SortMode
|
||||
*/
|
||||
template<SortMode Mode> bool keepsmall(size_t, size_t, [[maybe_unused]] size_t) noexcept = delete;
|
||||
template<> bool keepsmall<SortMode::Bubbletonic>(size_t node, size_t partner, [[maybe_unused]] size_t depth) noexcept;
|
||||
template<> bool keepsmall<SortMode::Bitonic>(size_t node, size_t partner, size_t depth) noexcept;
|
||||
template<SortMode Mode> bool keepSmall(mpi_id_t, mpi_id_t, [[maybe_unused]] size_t) noexcept = delete;
|
||||
template<> bool keepSmall<SortMode::Bubbletonic>(mpi_id_t node, mpi_id_t partner, [[maybe_unused]] size_t depth) noexcept;
|
||||
template<> bool keepSmall<SortMode::Bitonic>(mpi_id_t node, mpi_id_t partner, size_t depth) noexcept;
|
||||
|
||||
bool isActive(size_t node, size_t nodes) noexcept;
|
||||
bool isActive(mpi_id_t node, mpi_id_t nodes) noexcept;
|
||||
|
||||
/*
|
||||
* ============================== Data utilities ==============================
|
||||
*/
|
||||
void exchange(size_t node, size_t partner);
|
||||
void minmax(AllData_t& data, size_t node, size_t partner, bool keepsmall);
|
||||
void exchange(mpi_id_t node, mpi_id_t partner);
|
||||
void minmax(AllData_t& data, mpi_id_t node, mpi_id_t partner, bool keepsmall);
|
||||
|
||||
/*
|
||||
* ============================== Sort algorithms ==============================
|
||||
*/
|
||||
void bubbletonic_network(AllData_t& data, size_t nodes);
|
||||
void distbubbletonic(size_t P, AllData_t& data);
|
||||
void bubbletonic_network(AllData_t& data, mpi_id_t nodes);
|
||||
void distBubbletonic(mpi_id_t P, AllData_t& data);
|
||||
|
||||
void bitonic_network(AllData_t& data, size_t nodes, size_t depth);
|
||||
void distbitonic(size_t P, AllData_t& data);
|
||||
void bitonic_network(AllData_t& data, mpi_id_t nodes, mpi_id_t depth);
|
||||
void distBitonic(mpi_id_t P, AllData_t& data);
|
||||
|
||||
#endif //DISTBITONIC_H_
|
||||
|
||||
@@ -12,14 +12,68 @@
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
#include <unistd.h>
|
||||
#include <mpi.h>
|
||||
|
||||
#include "matrix.hpp"
|
||||
//#include "matrix.hpp"
|
||||
#include "config.h"
|
||||
|
||||
|
||||
template<typename TID = int>
|
||||
struct MPI_t {
|
||||
using ID_t = TID; // Export TID type (currently int defined by the standard)
|
||||
|
||||
void init(int *argc, char ***argv) {
|
||||
// Initialize the MPI environment
|
||||
MPI_Init(argc, argv);
|
||||
|
||||
// Get the number of processes
|
||||
int size_value, rank_value;
|
||||
size_ = static_cast<ID_t>(MPI_Comm_size(MPI_COMM_WORLD, &size_value));
|
||||
rank_ = static_cast<ID_t>(MPI_Comm_rank(MPI_COMM_WORLD, &rank_value));
|
||||
|
||||
// Get the name of the processor
|
||||
char processor_name[MPI_MAX_PROCESSOR_NAME];
|
||||
int name_len;
|
||||
MPI_Get_processor_name(processor_name, &name_len);
|
||||
name_ = std::string (processor_name, name_len);
|
||||
}
|
||||
|
||||
void finalize() {
|
||||
// Finalize the MPI environment.
|
||||
MPI_Finalize();
|
||||
}
|
||||
|
||||
bool exchange(ID_t partner, const void *send_data, void *recv_data, int data_count, MPI_Datatype datatype) {
|
||||
bool ret = true;
|
||||
MPI_Status status;
|
||||
MPI_Sendrecv(
|
||||
send_data, data_count, datatype, partner, 0,
|
||||
recv_data, data_count, datatype, partner, 0,
|
||||
MPI_COMM_WORLD, &status
|
||||
);
|
||||
if (status.MPI_ERROR != MPI_SUCCESS)
|
||||
ret = false;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Accessors
|
||||
[[nodiscard]] ID_t rank() const noexcept { return rank_; }
|
||||
[[nodiscard]] ID_t size() const noexcept { return size_; }
|
||||
[[nodiscard]] const std::string& name() const noexcept { return name_; }
|
||||
|
||||
private:
|
||||
ID_t rank_{};
|
||||
ID_t size_{};
|
||||
std::string name_{};
|
||||
};
|
||||
|
||||
extern MPI_t<> mpi;
|
||||
using mpi_id_t = MPI_t<>::ID_t;
|
||||
|
||||
/*!
|
||||
* A Logger for entire program.
|
||||
*/
|
||||
|
||||
struct Log {
|
||||
struct Endl {
|
||||
} endl; //!< a tag object to to use it as a new line request.
|
||||
|
||||
Reference in New Issue
Block a user