You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
3.8 KiB
128 lines
3.8 KiB
4 years ago
|
#include <tuple>
|
||
|
#include <functional>
|
||
|
#include <cfloat>
|
||
|
|
||
4 years ago
|
#include <shuffle3.h>
|
||
4 years ago
|
#include <panic.h>
|
||
4 years ago
|
#include <map.h>
|
||
|
#include <reinterpret.h>
|
||
|
#include <shuffle.hpp>
|
||
|
|
||
|
#include <work.h>
|
||
4 years ago
|
#include <debug.h>
|
||
4 years ago
|
|
||
|
template<typename T, typename Fn>
|
||
|
std::tuple<T, T> minmax_t(const span<T>& array, Fn keep)
|
||
|
{
|
||
|
T highest;
|
||
4 years ago
|
T lowest;
|
||
4 years ago
|
bool init=false;
|
||
4 years ago
|
D_dprintf("minmax_t: %p (%lu)", array.as_ptr(), array.size());
|
||
4 years ago
|
for(std::size_t i=0;i<array.size();i++)
|
||
|
{
|
||
|
if(!keep(array[i])) continue;
|
||
|
|
||
4 years ago
|
auto item = array[i];
|
||
4 years ago
|
if(!init) {
|
||
|
init = true;
|
||
|
lowest = highest = item;
|
||
|
}
|
||
4 years ago
|
else if(item < lowest) lowest = item;
|
||
|
else if(item > highest) highest = item;
|
||
4 years ago
|
}
|
||
4 years ago
|
//fmt::print("MMX {}, {}\n", lowest, highest);
|
||
4 years ago
|
return {lowest, highest};
|
||
|
}
|
||
|
|
||
|
template<typename T>
|
||
|
inline std::tuple<T, T> minmax_t(const span<T>& array)
|
||
|
{
|
||
|
return minmax_t(array, [](T _val) { return true; });
|
||
|
}
|
||
4 years ago
|
|
||
4 years ago
|
namespace work
|
||
4 years ago
|
{
|
||
4 years ago
|
/// Shuffle or unshuffle in place
|
||
|
template<bool unshuffle>
|
||
|
int xshuffle_ip(const char* file)
|
||
|
{
|
||
4 years ago
|
mm::mmap map(file);
|
||
|
|
||
|
if constexpr(unshuffle)
|
||
|
{
|
||
|
auto [byte_l, byte_h] = minmax_t(map.as_span().reinterpret<std::int8_t>());
|
||
4 years ago
|
D_dprintf("MMX res (s8): %d -- %d", byte_l, byte_h);
|
||
4 years ago
|
rng::drng drng((std::int32_t) ((0xfffa << 16) | (byte_l<<7) | byte_h ));
|
||
|
rng::unshuffle(drng, map.as_span());
|
||
|
|
||
|
auto [float_l, float_h] = minmax_t(map.as_span().reinterpret<float>(), [](float f) -> bool { return !( (f!=f) || f < -FLT_MAX || f > FLT_MAX); });
|
||
4 years ago
|
D_dprintf("MMX res (f32): %f -- %f", float_l, float_h);
|
||
4 years ago
|
rng::frng frng(float_l, float_h);
|
||
|
rng::unshuffle(frng, map.as_span().reinterpret<float>());
|
||
|
|
||
|
auto [long_l, long_h] = minmax_t(map.as_span().reinterpret<std::int64_t>());
|
||
4 years ago
|
D_dprintf("MMX res (u64): %ld -- %ld", long_l, long_h);
|
||
4 years ago
|
rng::xoroshiro128plus xorng(*(const std::uint64_t*)&long_l, *(const std::uint64_t*)&long_h);
|
||
|
rng::unshuffle(xorng, map.as_span().reinterpret<std::int64_t>());
|
||
|
} else {
|
||
|
auto [long_l, long_h] = minmax_t(map.as_span().reinterpret<std::int64_t>());
|
||
4 years ago
|
D_dprintf("MMX res (u64): %ld -- %ld", long_l, long_h);
|
||
4 years ago
|
rng::xoroshiro128plus xorng(*(const std::uint64_t*)&long_l, *(const std::uint64_t*)&long_h);
|
||
|
rng::shuffle(xorng, map.as_span().reinterpret<std::int64_t>());
|
||
|
|
||
|
auto [float_l, float_h] = minmax_t(map.as_span().reinterpret<float>(), [](float f) -> bool { return !( (f!=f) || f < -FLT_MAX || f > FLT_MAX); });
|
||
4 years ago
|
D_dprintf("MMX res (f32): %f -- %f", float_l, float_h);
|
||
4 years ago
|
rng::frng frng(float_l, float_h);
|
||
|
rng::shuffle(frng, map.as_span().reinterpret<float>());
|
||
|
|
||
|
auto [byte_l, byte_h] = minmax_t(map.as_span().reinterpret<std::int8_t>());
|
||
4 years ago
|
D_dprintf("MMX res (s8): %d -- %d", byte_l, byte_h);
|
||
4 years ago
|
rng::drng drng((std::int32_t) ((0xfffa << 16) | (byte_l<<7) | byte_h ));
|
||
|
rng::shuffle(drng, map.as_span());
|
||
|
}
|
||
|
|
||
4 years ago
|
return 0;
|
||
|
}
|
||
|
|
||
|
/// Shuffle or unshuffle out of place
|
||
|
template<bool unshuffle>
|
||
|
int xshuffle_op(const char* ifile, const char* ofile, bool is_buffered)
|
||
|
{
|
||
4 years ago
|
|
||
|
if constexpr(unshuffle)
|
||
|
{
|
||
|
|
||
|
} else {
|
||
|
|
||
|
}
|
||
|
panic("Unimplemented");
|
||
4 years ago
|
return 0;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
int help()
|
||
|
{
|
||
|
//Print help then exit
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
extern "C" int do_work(const work_args_t args)
|
||
|
{
|
||
|
using A = decltype(args.op);
|
||
|
switch (args.op) {
|
||
|
case A::OP_SHUFFLE_IP: return work::xshuffle_ip<false >(args.data.op_shuffle_ip.file);
|
||
|
case A::OP_SHUFFLE_OP: return work::xshuffle_op<false >(args.data.op_shuffle_op.ifile,
|
||
|
args.data.op_shuffle_op.ofile,
|
||
|
args.data.op_shuffle_op.buffered == WORK_BO_BUFFERED);
|
||
|
case A::OP_UNSHUFFLE_IP: return work::xshuffle_ip<true >(args.data.op_unshuffle_ip.file);
|
||
|
case A::OP_UNSHUFFLE_OP: return work::xshuffle_op<true>(args.data.op_unshuffle_op.ifile,
|
||
|
args.data.op_unshuffle_op.ofile,
|
||
|
args.data.op_unshuffle_op.buffered == WORK_BO_BUFFERED);
|
||
|
case A::OP_HELP: return help();
|
||
|
|
||
|
default: panic("Unknown op %d", (int)args.op);
|
||
|
}
|
||
4 years ago
|
return 0;
|
||
|
}
|