Skip to content

Commit

Permalink
Fixed issue with psetstr.
Browse files Browse the repository at this point in the history
Also added unit test for low-level string conversion functions.
  • Loading branch information
suiginsoft committed Feb 17, 2017
1 parent c50d06f commit 08a417b
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 19 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ check/alloc/query
check/alloc/valid
check/libcheck.a
check/p/negnot
check/p/strings
check/p/pcmp
check/p/pcopy
check/p/pmove
Expand Down
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,8 @@ CHECK_P := \
pmove \
pnorm \
pzero \
negnot
negnot \
strings

CHECK_Z := \
getset \
Expand Down
2 changes: 2 additions & 0 deletions TODO
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ Low-level Functions:
* create addua/subua to add in carry for larger ops?
* port remainder of division implementation to x86-64 assembly
* optimize pclz, almost always called on normalized input
* add ptrunc and reimplement ztrunc in terms of it
* get rid of bit-level truncation in prand_kiss, truncation only in zrand***

Integer Functions:

Expand Down
51 changes: 51 additions & 0 deletions check/p/strings.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#include "../check.h"
#include <stdio.h>
#include <stdlib.h>

static struct hebi_kiss kiss = HEBI_KISS_INIT;

/* packet buffers for stress test */
enum { MAX_PACKETS = 16 };
static hebi_packet x[MAX_PACKETS + 1];
static hebi_packet y[MAX_PACKETS + 1];
static hebi_packet z[MAX_PACKETS + 1];

/* room for all base 2 digits, optional radix prefix and null terminator */
enum { MAX_LENGTH = MAX_PACKETS * HEBI_PACKET_BIT + 2 + 1 };
static char str[MAX_LENGTH];

static void
stresstest(unsigned int flags)
{
size_t i, m, n, bits, len;
unsigned int base;

for (i = 0; i < MAX_PACKETS * HEBI_PACKET_BIT; i++) {
/* get next random value */
bits = i;
n = (bits + HEBI_PACKET_BIT - 1) / HEBI_PACKET_BIT;
if (n > 0) {
hebi_prand_kiss(x, n, bits, &kiss);
n = hebi_pnorm(x, n); /* TODO: fix prand */
}

/* test converting to string and back for each base */
for (base = 2; base <= 62 /* TODO: 63 & 64 */; base++) {
hebi_pcopy(z, x, n);
len = hebi_pgetstr(str, sizeof(str), z, n, base, flags);
assert(len > 0 && len < sizeof(str));

hebi_pzero(y, MAX_PACKETS + 1);
m = hebi_psetstr(y, MAX_PACKETS + 1, str, len, base, flags);
assert(m == n && hebi_pcmp(x, y, m) == 0);
}
}
}

int
main(int argc, char *argv[])
{
checkinit(argc, argv);
stresstest(HEBI_STR_CLASSIC_ALPHABET);
return 0;
}
39 changes: 21 additions & 18 deletions src/p/psetstr.c
Original file line number Diff line number Diff line change
Expand Up @@ -275,14 +275,14 @@ static const unsigned char classic36digitlut[256] = {
['K'] = 21, ['L'] = 22, ['M'] = 23, ['N'] = 24,
['O'] = 25, ['P'] = 26, ['Q'] = 27, ['R'] = 28,
['S'] = 29, ['T'] = 30, ['U'] = 31, ['V'] = 32,
['W'] = 33, ['Y'] = 34, ['X'] = 35, ['Z'] = 36,
['W'] = 33, ['X'] = 34, ['Y'] = 35, ['Z'] = 36,
['a'] = 11, ['b'] = 12, ['c'] = 13, ['d'] = 14,
['e'] = 15, ['f'] = 16, ['g'] = 17, ['h'] = 18,
['i'] = 19, ['j'] = 20, ['k'] = 21, ['l'] = 22,
['m'] = 23, ['n'] = 24, ['o'] = 25, ['p'] = 26,
['q'] = 27, ['r'] = 28, ['s'] = 29, ['t'] = 30,
['u'] = 31, ['v'] = 32, ['w'] = 33, ['y'] = 34,
['x'] = 35, ['z'] = 36
['u'] = 31, ['v'] = 32, ['w'] = 33, ['x'] = 34,
['y'] = 35, ['z'] = 36
};

static const unsigned char classic64digitlut[256] = {
Expand All @@ -294,14 +294,14 @@ static const unsigned char classic64digitlut[256] = {
['K'] = 21, ['L'] = 22, ['M'] = 23, ['N'] = 24,
['O'] = 25, ['P'] = 26, ['Q'] = 27, ['R'] = 28,
['S'] = 29, ['T'] = 30, ['U'] = 31, ['V'] = 32,
['W'] = 33, ['Y'] = 34, ['X'] = 35, ['Z'] = 36,
['W'] = 33, ['X'] = 34, ['Y'] = 35, ['Z'] = 36,
['a'] = 37, ['b'] = 38, ['c'] = 39, ['d'] = 40,
['e'] = 41, ['f'] = 42, ['g'] = 43, ['h'] = 44,
['i'] = 45, ['j'] = 46, ['k'] = 47, ['l'] = 48,
['m'] = 49, ['n'] = 50, ['o'] = 51, ['p'] = 52,
['q'] = 53, ['r'] = 54, ['s'] = 55, ['t'] = 56,
['u'] = 57, ['v'] = 58, ['w'] = 59, ['y'] = 60,
['x'] = 61, ['z'] = 62, ['$'] = 63, ['@'] = 64
['u'] = 57, ['v'] = 58, ['w'] = 59, ['x'] = 60,
['y'] = 61, ['z'] = 62, ['$'] = 63, ['@'] = 64
};

static inline unsigned int
Expand Down Expand Up @@ -382,8 +382,17 @@ outofspace(
}

#define ENSURE_SPACE_AVAILABLE(SIZE) \
if (UNLIKELY((SIZE) > n)) \
return outofspace((SIZE), str, cur, len, radix)
if (UNLIKELY((SIZE) > n)) \
return outofspace((SIZE), str, cur, len, radix)

#define PUSH_LIMB(VAL) \
MULTILINEBEGIN \
if (VAL) { \
size++; \
ENSURE_SPACE_AVAILABLE(size); \
hebi_psetu(r + size - 1, (VAL)); \
} \
MULTILINEEND

static size_t
readshift(
Expand Down Expand Up @@ -445,6 +454,7 @@ readmultiply(
const unsigned char *restrict digitlut )
{
uint64_t limb;
uint64_t overflow;
uint64_t scale;
uint64_t maxscale;
unsigned int digit;
Expand All @@ -471,21 +481,14 @@ readmultiply(
numdigits++;
}
if (size > 0) {
size++;
ENSURE_SPACE_AVAILABLE(size);
scale = maxscale;
if (numdigits != maxdigits)
scale = hebi_powu64__(radix, numdigits);
hebi_pmulu(r, r, scale, size - 1);
overflow = hebi_pmulu(r, r, scale, size);
PUSH_LIMB(overflow);
limb = hebi_paddu(r, r, limb, size);
}
if (limb) {
size++;
ENSURE_SPACE_AVAILABLE(size);
hebi_psetu(r + size - 1, limb);
} else {
size = hebi_pnorm(r, size);
}
PUSH_LIMB(limb);
} while (cur < len);

return size;
Expand Down

0 comments on commit 08a417b

Please sign in to comment.