Compare commits

...

3 Commits

Author SHA1 Message Date
thetek ecc2e0245e chore: update readme to incorporate `vec` library 2023-04-25 15:01:57 +02:00
thetek 554917ce56 test(vec): vec_add, vec_sub 2023-04-25 15:01:11 +02:00
thetek 69c6d1516a feat(vec): introduce vec library 2023-04-25 15:00:59 +02:00
4 changed files with 125 additions and 0 deletions

View File

@ -18,5 +18,6 @@ parameters and return values).
- `str`: A custom string type that stores length and capacity and associated
functions for interacting with it
- `test`: Simple unit testing library
- `vec`: Vectorized math operations
Note that some modules may depend on each other.

38
lib/inc/vec.h Normal file
View File

@ -0,0 +1,38 @@
#ifndef VEC_H_
#define VEC_H_
#include "common.h"
// helper macros
#define GET_FUNCTION_NAME(PREFIX, TYPE) _Generic((TYPE), \
u8*: PREFIX##_##u8, u16*: PREFIX##_##u16, \
u32*: PREFIX##_##u32, u64*: PREFIX##_##u64, \
i8*: PREFIX##_##i8, i16*: PREFIX##_##i16, \
i32*: PREFIX##_##i32, i64*: PREFIX##_##i64, \
f32*: PREFIX##_##f32, f64*: PREFIX##_##f64)
#define DECLARE_FUNCTIONS(MACRO) \
MACRO(u8); MACRO(u16); MACRO(u32); MACRO(u64); \
MACRO(i8); MACRO(i16); MACRO(i32); MACRO(i64); \
MACRO(f32); MACRO(f64)
#define DECLARE_VEC_ADD(TYPE) void vec_add_##TYPE (usize n, TYPE a[restrict n], const TYPE b[restrict n])
#define DECLARE_VEC_SUB(TYPE) void vec_sub_##TYPE (usize n, TYPE a[restrict n], const TYPE b[restrict n])
// exported macros
#define vec_add(n, a, b) GET_FUNCTION_NAME(vec_add, a)(n, a, b) /* vectorized addition - void vec_add<T>(usize n, T a[restrict n], const T b[restrict n]) */
#define vec_sub(n, a, b) GET_FUNCTION_NAME(vec_sub, a)(n, a, b) /* vectorized subtraction - void vec_sub<T>(usize n, T a[restrict n], const T b[restrict n]) */
// function declarations
DECLARE_FUNCTIONS(DECLARE_VEC_ADD);
DECLARE_FUNCTIONS(DECLARE_VEC_SUB);
// undefine helper macros
#undef __GET_FUNCTION_NAME
#undef __DECLARE_FUNCTIONS
#undef __DECLARE_VEC_ADD
#undef __DECLARE_VEC_SUB
#endif // VEC_H_

49
lib/vec.c Normal file
View File

@ -0,0 +1,49 @@
#include "vec.h"
#define IMPLEMENT_FUNCTIONS(MACRO) \
MACRO(u8) MACRO(u16) MACRO(u32) MACRO(u64) \
MACRO(i8) MACRO(i16) MACRO(i32) MACRO(i64) \
MACRO(f32) MACRO(f64)
/**
* vectorized addition. each element of vector `b` will be added to its
* counterpart element in vector `a` (i.e. `a[i] += b[i]`). the result will be
* stored in `a`
*
* @param a: first vector, result destination
* @param b: second vector
*
* @usage either through `vec_add_<type> (e.g. `vec_add_u32`), or through the
* generic macro `vec_add`
*/
#define IMPL_VEC_ADD(TYPE) \
void \
vec_add_##TYPE (usize n, TYPE a[restrict n], const TYPE b[restrict n]) \
{ \
usize i; \
for (i = 0; i < n; i++) \
a[i] += b[i]; \
}
/**
* vectorized subtraction. each element of vector `b` will be subtracted from
* its counterpart element in vector `a` (i.e. `a[i] -= b[i]`). the result will
* be stored in `a`
*
* @param a: first vector, result destination
* @param b: second vector
*
* @usage either through `vec_sub_<type> (e.g. `vec_sub_u32`), or through the
* generic macro `vec_sub`
*/
#define IMPL_VEC_SUB(TYPE) \
void \
vec_sub_##TYPE (usize n, TYPE a[restrict n], const TYPE b[restrict n]) \
{ \
usize i; \
for (i = 0; i < n; i++) \
a[i] -= b[i]; \
}
IMPLEMENT_FUNCTIONS(IMPL_VEC_ADD)
IMPLEMENT_FUNCTIONS(IMPL_VEC_SUB)

View File

@ -10,6 +10,7 @@
#include "common.h"
#include "str.h"
#include "test.h"
#include "vec.h"
test_results_t
test_cstr (void)
@ -105,6 +106,41 @@ test_str (void)
return test_group_get_results (&group);
}
test_results_t
test_vec (void)
{
test_group_t group;
i32 a[42], b[42], a_orig[42];
bool all_correct;
usize i;
group = test_group_new ();
for (i = 0; i < 42; i++) {
a[i] = a_orig[i] = (i32) rand_range (0, INT16_MAX);
b[i] = (i32) rand_range (0, INT16_MAX);
}
vec_add (42, a, b);
all_correct = true;
for (i = 0; i < 42; i++)
all_correct &= (a[i] == a_orig[i] + b[i]);
test_add (&group, test_assert (all_correct && "for all i: a[i] = a_orig[i] + b[i]"), "vec_add");
for (i = 0; i < 42; i++)
a[i] = a_orig[i];
vec_sub(42, a, b);
all_correct = true;
for (i = 0; i < 42; i++)
all_correct &= (a[i] == a_orig[i] - b[i]);
test_add (&group, test_assert (all_correct && "for all i: a[i] = a_orig[i] - b[i]"), "vec_sub");
return test_group_get_results (&group);
}
int
main (void)
{
@ -113,6 +149,7 @@ main (void)
suite = test_suite_new ();
test_suite_add (&suite, test_cstr);
test_suite_add (&suite, test_str);
test_suite_add (&suite, test_vec);
test_suite_run (&suite);
test_suite_free (&suite);