use the new SIMD sorting wrappers

This commit is contained in:
Ahmet Inan 2024-03-05 09:41:04 +01:00
commit b038399c90
3 changed files with 21 additions and 40 deletions

View file

@ -7,6 +7,7 @@ Copyright 2020 Ahmet Inan <inan@aicodix.de>
#pragma once #pragma once
#include "simd.hh" #include "simd.hh"
#include "sort.hh"
namespace CODE { namespace CODE {
@ -105,7 +106,7 @@ template <int WIDTH>
struct PolarHelper<SIMD<int8_t, WIDTH>> struct PolarHelper<SIMD<int8_t, WIDTH>>
{ {
typedef SIMD<int8_t, WIDTH> TYPE; typedef SIMD<int8_t, WIDTH> TYPE;
typedef int PATH; typedef int32_t PATH;
typedef SIMD<uint8_t, WIDTH> MAP; typedef SIMD<uint8_t, WIDTH> MAP;
static TYPE one() static TYPE one()
{ {
@ -156,7 +157,7 @@ struct PolarHelper<SIMD<int8_t, WIDTH>>
template <> template <>
struct PolarHelper<int8_t> struct PolarHelper<int8_t>
{ {
typedef int PATH; typedef int32_t PATH;
static int8_t one() static int8_t one()
{ {
return 1; return 1;

View file

@ -6,7 +6,6 @@ Copyright 2020 Ahmet Inan <inan@aicodix.de>
#pragma once #pragma once
#include <algorithm>
#include "polar_helper.hh" #include "polar_helper.hh"
namespace CODE { namespace CODE {
@ -53,32 +52,23 @@ struct PolarListNode<TYPE, 0>
static MAP rate1(PATH *metric, TYPE *message, MAP *maps, int *count, TYPE *hard, TYPE *soft) static MAP rate1(PATH *metric, TYPE *message, MAP *maps, int *count, TYPE *hard, TYPE *soft)
{ {
TYPE sft = soft[1]; TYPE sft = soft[1];
PATH fork[2*TYPE::SIZE]; SIMD<PATH, 2*TYPE::SIZE> fork;
for (int k = 0; k < TYPE::SIZE; ++k) for (int k = 0; k < TYPE::SIZE; ++k)
fork[2*k] = fork[2*k+1] = metric[k]; fork.v[2*k] = fork.v[2*k+1] = metric[k];
for (int k = 0; k < TYPE::SIZE; ++k) for (int k = 0; k < TYPE::SIZE; ++k)
if (sft.v[k] < 0) if (sft.v[k] < 0)
fork[2*k] -= sft.v[k]; fork.v[2*k] -= sft.v[k];
else else
fork[2*k+1] += sft.v[k]; fork.v[2*k+1] += sft.v[k];
int perm[2*TYPE::SIZE]; auto perm = vorder(fork);
for (int k = 0; k < 2*TYPE::SIZE; ++k)
perm[k] = k;
#if 1
std::stable_sort(perm, perm+2*TYPE::SIZE, [fork](int a, int b){ return fork[a] < fork[b]; });
#else
std::partial_sort(perm, perm+TYPE::SIZE-1, perm+2*TYPE::SIZE, [fork](int a, int b){
return fork[a] < fork[b] ? true : fork[a] > fork[b] ? false : a < b;
});
#endif
for (int k = 0; k < TYPE::SIZE; ++k) for (int k = 0; k < TYPE::SIZE; ++k)
metric[k] = fork[perm[k]]; metric[k] = fork.v[perm.v[k]];
MAP map; MAP map;
for (int k = 0; k < TYPE::SIZE; ++k) for (int k = 0; k < TYPE::SIZE; ++k)
map.v[k] = perm[k] >> 1; map.v[k] = perm.v[k] >> 1;
TYPE hrd; TYPE hrd;
for (int k = 0; k < TYPE::SIZE; ++k) for (int k = 0; k < TYPE::SIZE; ++k)
hrd.v[k] = 1 - 2 * (perm[k] & 1); hrd.v[k] = 1 - 2 * (perm.v[k] & 1);
message[*count] = hrd; message[*count] = hrd;
maps[*count] = map; maps[*count] = map;
++*count; ++*count;

View file

@ -6,7 +6,6 @@ Copyright 2023 Ahmet Inan <inan@aicodix.de>
#pragma once #pragma once
#include <algorithm>
#include "polar_helper.hh" #include "polar_helper.hh"
namespace CODE { namespace CODE {
@ -101,41 +100,32 @@ struct PolarParityNode<TYPE, 0>
static MAP rate1(PATH *metric, TYPE *message, MAP *maps, int *index, TYPE *hard, TYPE *soft, TYPE *parity, int *count, int stride) static MAP rate1(PATH *metric, TYPE *message, MAP *maps, int *index, TYPE *hard, TYPE *soft, TYPE *parity, int *count, int stride)
{ {
TYPE sft = soft[1]; TYPE sft = soft[1];
PATH fork[2*TYPE::SIZE]; SIMD<PATH, 2*TYPE::SIZE> fork;
for (int k = 0; k < TYPE::SIZE; ++k) for (int k = 0; k < TYPE::SIZE; ++k)
fork[2*k] = fork[2*k+1] = metric[k]; fork.v[2*k] = fork.v[2*k+1] = metric[k];
for (int k = 0; k < TYPE::SIZE; ++k) for (int k = 0; k < TYPE::SIZE; ++k)
if (sft.v[k] < 0) if (sft.v[k] < 0)
fork[2*k] -= sft.v[k]; fork.v[2*k] -= sft.v[k];
else else
fork[2*k+1] += sft.v[k]; fork.v[2*k+1] += sft.v[k];
if (*count == 0) { if (*count == 0) {
TYPE chk = *parity; TYPE chk = *parity;
*parity = PH::one(); *parity = PH::one();
for (int k = 0; k < TYPE::SIZE; ++k) for (int k = 0; k < TYPE::SIZE; ++k)
if (chk.v[k] < 0) if (chk.v[k] < 0)
fork[2*k] = 1000; fork.v[2*k] = 1000;
else else
fork[2*k+1] = 1000; fork.v[2*k+1] = 1000;
} }
int perm[2*TYPE::SIZE]; auto perm = vorder(fork);
for (int k = 0; k < 2*TYPE::SIZE; ++k)
perm[k] = k;
#if 1
std::stable_sort(perm, perm+2*TYPE::SIZE, [fork](int a, int b){ return fork[a] < fork[b]; });
#else
std::partial_sort(perm, perm+TYPE::SIZE-1, perm+2*TYPE::SIZE, [fork](int a, int b){
return fork[a] < fork[b] ? true : fork[a] > fork[b] ? false : a < b;
});
#endif
for (int k = 0; k < TYPE::SIZE; ++k) for (int k = 0; k < TYPE::SIZE; ++k)
metric[k] = fork[perm[k]]; metric[k] = fork.v[perm.v[k]];
MAP map; MAP map;
for (int k = 0; k < TYPE::SIZE; ++k) for (int k = 0; k < TYPE::SIZE; ++k)
map.v[k] = perm[k] >> 1; map.v[k] = perm.v[k] >> 1;
TYPE hrd; TYPE hrd;
for (int k = 0; k < TYPE::SIZE; ++k) for (int k = 0; k < TYPE::SIZE; ++k)
hrd.v[k] = 1 - 2 * (perm[k] & 1); hrd.v[k] = 1 - 2 * (perm.v[k] & 1);
if (*count) { if (*count) {
message[*index] = hrd; message[*index] = hrd;
*parity = PH::qmul(vshuf(*parity, map), hrd); *parity = PH::qmul(vshuf(*parity, map), hrd);