using xvec related api in scheduler

This commit is contained in:
Rongsong Shen 2026-01-16 18:21:37 +08:00
parent 06209930f9
commit 924bc1517b
11 changed files with 689 additions and 70 deletions

View file

@ -77,6 +77,7 @@ libxce_test_src = ['testsuite/test.c',
'testsuite/test_group.c',
'testsuite/test_xlist.c',
'testsuite/test_limit.c',
'testsuite/test_xvec.c',
]
libxce_test_deps = [libxce_deps, unity_dep, libxce_dep]

View file

@ -20,6 +20,7 @@ extern void test_kvmgr(void);
extern void test_group(void);
extern void test_xlist(void);
extern void test_limit(void);
extern void test_xvec(void);
void setUp(void) { return; }
@ -105,6 +106,7 @@ int main(int argc, char* argv[])
TEST(test_group);
TEST(test_xlist);
TEST(test_limit);
TEST(test_xvec);
return UNITY_END();
}

View file

@ -0,0 +1,374 @@
#include <stdio.h>
#include <stdlib.h>
#include <unity/unity.h>
#include "utils.h"
#include "xvec.h"
static void test_xvec_init()
{
xvec_t v;
int rc;
rc = xvec_init(&v, 128, sizeof(int));
TEST_ASSERT_TRUE(rc >= 0);
TEST_ASSERT_TRUE(v.elsize == sizeof(int));
TEST_ASSERT_TRUE(v.count == 128);
TEST_ASSERT_TRUE(v.data != NULL);
xvec_fini(&v);
}
static void test_xvec_zero()
{
xvec_t v;
int rc, i;
rc = xvec_init(&v, 128, sizeof(int));
TEST_ASSERT_TRUE(rc >= 0);
rc = xvec_zero(&v);
TEST_ASSERT_TRUE(rc >= 0);
for (i = 0; i < 128; i++) {
int val = ((int*)v.data)[i];
TEST_ASSERT_TRUE(val == 0);
}
xvec_fini(&v);
return;
}
static void test_xvec_putget(void)
{
xvec_t v;
int rc, i;
rc = xvec_init(&v, 32, sizeof(int));
TEST_ASSERT_TRUE(rc >= 0);
for (i = 0; i < 32; i++) {
int val;
rc = xvec_put(&v, i, &i);
TEST_ASSERT_TRUE(rc >= 0);
rc = xvec_get(&v, i, &val);
TEST_ASSERT_TRUE(rc >= 0);
TEST_ASSERT_TRUE(i == val);
}
xvec_fini(&v);
}
static void test_xvec_resize(void)
{
xvec_t v;
int rc, i;
rc = xvec_init(&v, 32, sizeof(int));
TEST_ASSERT_TRUE(rc >= 0);
for (i = 0; i < 32; i++) {
int val;
rc = xvec_put(&v, i, &i);
TEST_ASSERT_TRUE(rc >= 0);
rc = xvec_get(&v, i, &val);
TEST_ASSERT_TRUE(rc >= 0);
TEST_ASSERT_TRUE(i == val);
}
rc = xvec_resize(&v, 64);
for (i = 0; i < 64; i++) {
int val;
rc = xvec_get(&v, i, &val);
TEST_ASSERT_TRUE(rc >= 0);
TEST_ASSERT_TRUE(((i < 32) && (val == i)) || ((i >= 32) && (val == 0)));
}
xvec_fini(&v);
}
static void test_xvec_int_add(void)
{
xvec_t v1, v2;
int rc, i;
rc = xvec_init(&v1, 16, sizeof(int));
TEST_ASSERT_TRUE(rc >= 0);
rc = xvec_init(&v2, 16, sizeof(int));
TEST_ASSERT_TRUE(rc >= 0);
for (i = 0; i < 16; i++) {
int val = i * i;
rc = xvec_put(&v1, i, &i);
TEST_ASSERT_TRUE(rc >= 0);
rc = xvec_put(&v2, i, &val);
TEST_ASSERT_TRUE(rc >= 0);
}
rc = xvec_op(&v1, &v2, XVEC_ADD_INT);
TEST_ASSERT_TRUE(rc >= 0);
for (i = 0; i < 16; i++) {
int val;
rc = xvec_get(&v1, i, &val);
TEST_ASSERT_TRUE(rc >= 0);
TEST_ASSERT_TRUE(val == i * i + i);
}
xvec_fini(&v2);
xvec_fini(&v1);
}
static void test_xvec_int_sub(void)
{
xvec_t v1, v2;
int rc, i;
rc = xvec_init(&v1, 16, sizeof(int));
TEST_ASSERT_TRUE(rc >= 0);
rc = xvec_init(&v2, 16, sizeof(int));
TEST_ASSERT_TRUE(rc >= 0);
for (i = 0; i < 16; i++) {
int val = i * i;
rc = xvec_put(&v1, i, &val);
TEST_ASSERT_TRUE(rc >= 0);
rc = xvec_put(&v2, i, &i);
TEST_ASSERT_TRUE(rc >= 0);
}
rc = xvec_op(&v1, &v2, XVEC_SUB_INT);
TEST_ASSERT_TRUE(rc >= 0);
for (i = 0; i < 16; i++) {
int val;
rc = xvec_get(&v1, i, &val);
TEST_ASSERT_TRUE(rc >= 0);
TEST_ASSERT_TRUE(val == i * i - i);
}
xvec_fini(&v2);
xvec_fini(&v1);
}
static void test_xvec_int_add2(void)
{
xvec_t v1, v2;
int rc, i;
rc = xvec_init(&v1, 16, sizeof(int));
TEST_ASSERT_TRUE(rc >= 0);
rc = xvec_init(&v2, 32, sizeof(int));
TEST_ASSERT_TRUE(rc >= 0);
for (i = 0; i < 32; i++) {
int val = i * i;
if (i < 16) {
rc = xvec_put(&v1, i, &i);
TEST_ASSERT_TRUE(rc >= 0);
}
rc = xvec_put(&v2, i, &val);
TEST_ASSERT_TRUE(rc >= 0);
}
rc = xvec_op(&v1, &v2, XVEC_ADD_INT);
TEST_ASSERT_TRUE(rc >= 0);
TEST_ASSERT_TRUE(v1.count == 32);
for (i = 0; i < 32; i++) {
int val;
rc = xvec_get(&v1, i, &val);
TEST_ASSERT_TRUE(rc >= 0);
TEST_ASSERT_TRUE(((i < 16) && (val == i * i + i))
|| ((i >= 16) && (val == i * i)));
}
xvec_fini(&v2);
xvec_fini(&v1);
}
static void test_xvec_int_sub2(void)
{
xvec_t v1, v2;
int rc, i;
rc = xvec_init(&v1, 16, sizeof(int));
TEST_ASSERT_TRUE(rc >= 0);
rc = xvec_init(&v2, 32, sizeof(int));
TEST_ASSERT_TRUE(rc >= 0);
for (i = 0; i < 32; i++) {
int val = i * i;
if (i < 16) {
rc = xvec_put(&v1, i, &val);
TEST_ASSERT_TRUE(rc >= 0);
}
rc = xvec_put(&v2, i, &i);
TEST_ASSERT_TRUE(rc >= 0);
}
rc = xvec_op(&v1, &v2, XVEC_SUB_INT);
TEST_ASSERT_TRUE(rc >= 0);
TEST_ASSERT_TRUE(v1.count == 32);
for (i = 0; i < 32; i++) {
int val;
rc = xvec_get(&v1, i, &val);
TEST_ASSERT_TRUE(rc >= 0);
TEST_ASSERT_TRUE(((i < 16) && (val == i * i - i))
|| ((i >= 16) && (val == -i)));
}
xvec_fini(&v2);
xvec_fini(&v1);
}
static void test_xvec_dup(void) {
xvec_t v1;
xvec_t *v2;
int i, rc;
rc = xvec_init(&v1, 16, sizeof(int));
TEST_ASSERT_TRUE(rc >= 0);
for(i = 0; i < 16; i ++) {
xvec_put(&v1, i, &i);
}
rc = xvec_dup(&v2, &v1);
TEST_ASSERT_TRUE(rc >= 0);
TEST_ASSERT_TRUE(v2 != NULL);
for(i = 0; i < 16; i ++) {
int val1, val2;
rc = xvec_get(&v1, i, &val1);
TEST_ASSERT_TRUE(rc >= 0);
rc = xvec_get(v2, i, &val2);
TEST_ASSERT_TRUE(rc >= 0);
TEST_ASSERT_TRUE(val1 == val2);
}
xvec_fini(v2);
free(v2);
xvec_fini(&v1);
}
static void test_xvec_idval_init(void) {
xvec_idval_t v;
int rc;
rc = xvec_idval_init(&v, 32);
TEST_ASSERT_TRUE(rc >= 0);
TEST_ASSERT_TRUE(v.count == 0);
TEST_ASSERT_TRUE(v.idxs.elsize == sizeof(int));
TEST_ASSERT_TRUE(v.vals.elsize == sizeof(float));
TEST_ASSERT_TRUE(v.idxs.count == 32);
TEST_ASSERT_TRUE(v.vals.count == 32);
xvec_idval_fini(&v);
}
static void test_xvec_idval_store(void) {
xvec_idval_t v;
int rc;
int i;
rc = xvec_idval_init(&v, 32);
TEST_ASSERT_TRUE(rc >= 0);
for(i = 0; i < 32; i ++) {
float val = (float)i*i;
rc = xvec_idval_store(&v, i, val);
TEST_ASSERT_TRUE(rc >= 0);
}
TEST_ASSERT_TRUE(v.count == 32);
for(i = 0; i < 32; i ++) {
int idx;
float val;
rc = xvec_get(&(v.idxs), i, &idx);
TEST_ASSERT_TRUE(rc >= 0);
TEST_ASSERT_TRUE(idx == i);
rc = xvec_get(&(v.vals), i, &val);
TEST_ASSERT_TRUE(rc >= 0);
TEST_ASSERT_TRUE((val - i*i < 0.001) && (i*i - val < 0.001));
}
xvec_idval_fini(&v);
}
static void test_xvec_idval_fill(void) {
xvec_t v1;
xvec_idval_t v2;
int rc;
int i;
rc = xvec_init(&v1, 32, sizeof(float));
TEST_ASSERT_TRUE(rc >= 0);
rc = xvec_idval_init(&v2, 4);
TEST_ASSERT_TRUE(rc >= 0);
for(i = 0; i < 32; i ++) {
float val = i*i;
rc = xvec_put(&v1, i, &val);
TEST_ASSERT_TRUE(rc >= 0);
}
for(i = 0; i < 4; i ++) {
int idx = 3 * i;
rc = xvec_idval_store_idx(&v2, idx);
TEST_ASSERT_TRUE(rc >= 0);
}
rc = xvec_fill_idval(&v2, &v1);
TEST_ASSERT_TRUE(rc >= 0);
for(i = 0; i < 4; i ++) {
float val;
rc = xvec_get(&(v2.vals), i, &val);
TEST_ASSERT_TRUE(rc >= 0);
TEST_ASSERT_TRUE(val == (float)(3*i)*(3*i));
}
xvec_idval_fini(&v2);
xvec_fini(&v1);
}
void test_xvec(void)
{
printf("\n>> xvec test\n\n");
RUN_TEST(test_xvec_init);
RUN_TEST(test_xvec_zero);
RUN_TEST(test_xvec_putget);
RUN_TEST(test_xvec_resize);
RUN_TEST(test_xvec_int_add);
RUN_TEST(test_xvec_int_sub);
RUN_TEST(test_xvec_int_add2);
RUN_TEST(test_xvec_int_sub2);
RUN_TEST(test_xvec_dup);
RUN_TEST(test_xvec_idval_init);
RUN_TEST(test_xvec_idval_store);
RUN_TEST(test_xvec_idval_fill);
}

View file

@ -268,3 +268,118 @@ int xvec_idval_store(xvec_idval_t* v, int idx, float val)
return v->count;
}
int xvec_idval_store_idx(xvec_idval_t* v, int idx)
{
int pos;
int rc;
if ((v == NULL) || (idx < 0)) {
return -EINVAL;
}
pos = v->count;
rc = xvec_put(&(v->idxs), pos, &idx);
if (rc < 0) {
return rc;
}
v->count = pos + 1;
return v->count;
}
int xvec_fill_idval(xvec_idval_t* v, xvec_t* src)
{
int i;
if ((v == NULL) || (src == NULL)) {
return -EINVAL;
}
if (v->count < 0) {
return -EINVAL;
}
if (src->elsize != sizeof(float)) {
return -EINVAL;
}
for (i = 0; i < v->count; i++) {
int idx = ((int*)v->idxs.data)[i];
float* vals = (float*)v->vals.data;
if (idx < 0) {
vals[i] = 0.0;
continue;
}
if (idx >= src->count) {
vals[i] = 0.0;
} else {
vals[i] = ((float*)src->data)[idx];
}
}
return v->count;
}
#define DEFINE_XVEC_IDVAL_OP(op) \
static inline int xvec_idval_##op(xvec_t* d, xvec_idval_t* v) \
{ \
int rc, maxidx; \
int i; \
\
maxidx = 0; \
for (i = 0; i < v->count; i++) { \
if (maxidx < ((int*)v->idxs.data)[i]) { \
maxidx = ((int*)v->idxs.data)[i]; \
} \
} \
\
rc = xvec_resize(d, maxidx + 1); \
if (rc < 0) { \
return rc; \
} \
\
for (i = 0; i < v->count; i++) { \
int idx = ((int*)v->idxs.data)[i]; \
\
if (idx < 0) { \
continue; \
} \
\
((float*)d->data)[idx] X_OP(op)((float*)v->vals.data)[i]; \
} \
\
return v->count; \
}
DEFINE_XVEC_IDVAL_OP(add)
DEFINE_XVEC_IDVAL_OP(sub)
int xvec_idval(xvec_t* d, xvec_idval_t* v, xvec_op_t op)
{
if ((d == NULL) || (v == NULL)) {
return -EINVAL;
}
if (d->elsize != sizeof(float)) {
return -EINVAL;
}
if ((v->idxs.elsize != sizeof(int)) || (v->vals.elsize != sizeof(float))) {
return -EINVAL;
}
switch (op) {
case XVEC_ADD_INT:
case XVEC_SUB_INT:
return -EINVAL;
case XVEC_ADD_FLOAT:
return xvec_idval_add(d, v);
case XVEC_SUB_FLOAT:
return xvec_idval_sub(d, v);
}
return -EINVAL;
}