/*!
 * \file
 * \brief   Distributed sort implementation
 *
 * \author
 *    Christos Choutouridis AEM:8997
 *    <cchoutou@ece.auth.gr>
 */
#include "utils.hpp"
#include "distsort.hpp"


bool isActive(mpi_id_t node, size_t nodes) {
    if (!((nodes > 0) &&
          (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!

    return (node >= 0) && (node < static_cast<mpi_id_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));
    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 + stat_bit))
                 | (depth << (stage_bits + step_bits + stat_bit));
    return tag;
}
