Commit 8ea0f2a2 authored by Nicolas Denoyelle's avatar Nicolas Denoyelle
Browse files

move init functions and correct wrong iteration scheme

parent 46076771
......@@ -3,6 +3,14 @@
#include "dev/excit.h"
#include "tleaf.h"
static int tleaf_init_with_it(excit_t it,
const ssize_t depth,
const ssize_t *arities,
const enum tleaf_it_policy_e policy,
const ssize_t *user_policy,
excit_t levels,
excit_t levels_inverse);
static int tleaf_it_alloc(excit_t it)
{
if (it == NULL || it->data == NULL)
......@@ -12,10 +20,11 @@ static int tleaf_it_alloc(excit_t it)
data_it->depth = 0;
data_it->arities = NULL;
data_it->order = NULL;
data_it->order_inverse = NULL;
data_it->buf = NULL;
data_it->order = NULL;
data_it->levels = NULL;
data_it->order_inverse = NULL;
data_it->levels_inverse = NULL;
return EXCIT_SUCCESS;
}
......@@ -24,17 +33,171 @@ static void tleaf_it_free(excit_t it)
struct tleaf_it_s *data_it = it->data;
free(data_it->arities);
free(data_it->order);
free(data_it->order_inverse);
free(data_it->buf);
free(data_it->order);
excit_free(data_it->levels);
free(data_it->order_inverse);
excit_free(data_it->levels_inverse);
}
static int tleaf_it_size(const excit_t it, ssize_t *size)
{
struct tleaf_it_s *data_it = it->data;
ssize_t i, s=1;
for(i = 0; i < data_it->depth; i++)
s *= data_it->arities[i];
*size = data_it->depth ? s : 0;
return EXCIT_SUCCESS;
}
static int tleaf_it_rewind(excit_t it)
{
struct tleaf_it_s *data_it = it->data;
return excit_rewind(data_it->levels);
}
static int tleaf_it_copy(excit_t dst_it, const excit_t src_it)
{
int err = EXCIT_SUCCESS;
struct tleaf_it_s *dst = dst_it->data;
struct tleaf_it_s *src = src_it->data;
/* dst is initialised, then wipe it */
if (dst->buf != NULL) {
free(dst->buf);
free(dst->arities);
free(dst->order);
free(dst->order_inverse);
excit_free(dst->levels);
excit_free(dst->levels_inverse);
}
/* dst is not initialized (anymore) */
excit_t levels = excit_dup(src->levels);
if (levels == NULL) {
err = -EXCIT_ENOMEM;
goto error;
}
excit_t levels_inverse = excit_dup(src->levels_inverse);
if (levels_inverse == NULL) {
err = -EXCIT_ENOMEM;
goto error_with_levels;
}
err = tleaf_init_with_it(dst_it, src->depth + 1, src->arities,
TLEAF_POLICY_USER, src->order, levels, levels_inverse);
if (err != EXCIT_SUCCESS)
goto error_with_levels_inverse;
return EXCIT_SUCCESS;
error_with_levels_inverse:
excit_free(levels_inverse);
error_with_levels:
excit_free(levels);
error:
return err;
}
static int tleaf_it_pos(const excit_t it, ssize_t *value)
{
struct tleaf_it_s *data_it = it->data;
return excit_pos(data_it->levels, value);
}
static ssize_t tleaf_it_value(struct tleaf_it_s *it)
{
ssize_t i, acc = 1, val = 0;
for (i = 0; i < it->depth; i++) {
val += acc * it->buf[i];
acc *= it->arities[it->order[i]];
}
return val;
}
int tleaf_it_nth(const excit_t it, ssize_t n, ssize_t *indexes)
{
struct tleaf_it_s *data_it = it->data;
int err = excit_nth(data_it->levels, n, data_it->buf);
if (err != EXCIT_SUCCESS)
return err;
*indexes = tleaf_it_value(data_it);
return EXCIT_SUCCESS;
}
int tleaf_it_peek(const excit_t it, ssize_t *value)
{
struct tleaf_it_s *data_it = it->data;
int err = excit_peek(data_it->levels, data_it->buf);
if (err != EXCIT_SUCCESS)
return err;
*value = tleaf_it_value(data_it);
return EXCIT_SUCCESS;
}
int tleaf_it_next(excit_t it, ssize_t *indexes)
{
struct tleaf_it_s *data_it = it->data;
int err = excit_next(data_it->levels, data_it->buf);
if (err != EXCIT_SUCCESS)
return err;
*indexes = tleaf_it_value(data_it);
return EXCIT_SUCCESS;
}
int tleaf_it_rank(const excit_t it, const ssize_t *indexes, ssize_t *n)
{
struct tleaf_it_s *data_it = it->data;
int err = excit_nth(data_it->levels_inverse, *indexes, data_it->buf);
if (err != EXCIT_SUCCESS)
return err;
ssize_t i, acc = 1, val = 0;
for (i = 0; i < data_it->depth; i++) {
val += acc * data_it->buf[i];
acc *= data_it->arities[data_it->order_inverse[i]];
}
*n = val;
return EXCIT_SUCCESS;
}
static int tleaf_add_level(excit_t levels, const ssize_t arity){
excit_t level = excit_alloc(EXCIT_RANGE);
if (level == NULL)
return -EXCIT_ENOMEM;
int err;
err = excit_range_init(level, 0, arity - 1, 1);
if (err != EXCIT_SUCCESS)
goto error;
err = excit_product_add(levels, level);
if (err != EXCIT_SUCCESS)
goto error;
error:
excit_free(level);
return err;
}
static int excit_tleaf_init_with_it(excit_t it,
const ssize_t depth,
const ssize_t *arities,
const enum tleaf_it_policy_e policy,
const ssize_t *user_policy, excit_t levels)
static int tleaf_init_with_it(excit_t it,
const ssize_t depth,
const ssize_t *arities,
const enum tleaf_it_policy_e policy,
const ssize_t *user_policy,
excit_t levels,
excit_t levels_inverse)
{
if (it == NULL || it->data == NULL)
return -EXCIT_EINVAL;
......@@ -53,11 +216,11 @@ static int excit_tleaf_init_with_it(excit_t it,
switch (policy) {
case TLEAF_POLICY_ROUND_ROBIN:
for (i = 0; i < data_it->depth; i++)
data_it->order[i] = data_it->depth - i - 1;
data_it->order[i] = i;
break;
case TLEAF_POLICY_SCATTER:
for (i = 0; i < data_it->depth; i++)
data_it->order[i] = i;
data_it->order[i] = data_it->depth - i - 1;
break;
case TLEAF_POLICY_USER:
for (i = 0; i < data_it->depth; i++)
......@@ -78,7 +241,7 @@ static int excit_tleaf_init_with_it(excit_t it,
for (i = 0; i < data_it->depth; i++)
data_it->order_inverse[data_it->order[i]] = i;
/* Set levels arity */
/* Set levels arity. */
data_it->arities = malloc(sizeof(*data_it->arities) * data_it->depth);
if (data_it->arities == NULL) {
err = -EXCIT_ENOMEM;
......@@ -101,29 +264,36 @@ static int excit_tleaf_init_with_it(excit_t it,
err = -EXCIT_ENOMEM;
goto error_with_buf;
}
for (i = 0; i < data_it->depth; i++) {
excit_t level = excit_alloc(EXCIT_RANGE);
if (level == NULL) {
err = -EXCIT_ENOMEM;
goto error_with_levels;
}
err = excit_range_init(level, 0, arities[i] - 1, 1);
if (err != EXCIT_SUCCESS)
goto error_with_levels;
err = excit_product_add(data_it->levels, level);
if (err != EXCIT_SUCCESS)
for (i = 0; i < data_it->depth; i++){
err = tleaf_add_level(levels, data_it->arities[data_it->order[i]]);
if(err != EXCIT_SUCCESS)
goto error_with_levels;
}
} else {
data_it->levels = levels;
}
if (levels_inverse == NULL) {
data_it->levels_inverse = excit_alloc(EXCIT_PRODUCT);
if (data_it->levels_inverse == NULL) {
err = -EXCIT_ENOMEM;
goto error_with_levels;
}
for (i = 0; i < data_it->depth; i++){
err = tleaf_add_level(levels_inverse, data_it->arities[data_it->order_inverse[i]]);
if(err != EXCIT_SUCCESS)
goto error_with_levels_inverse;
}
} else {
data_it->levels_inverse = levels_inverse;
}
return EXCIT_SUCCESS;
error_with_levels_inverse:
excit_free(data_it->levels_inverse);
data_it->levels_inverse = NULL;
error_with_levels:
excit_free(data_it->levels);
data_it->levels = NULL;
......@@ -149,124 +319,25 @@ int excit_tleaf_init(excit_t it,
const enum tleaf_it_policy_e policy,
const ssize_t *user_policy)
{
return excit_tleaf_init_with_it(it, depth, arities, policy, user_policy,
NULL);
}
static int tleaf_it_size(const excit_t it, ssize_t *size)
{
struct tleaf_it_s *data_it = it->data;
return excit_size(data_it->levels, size);
}
static int tleaf_it_rewind(excit_t it)
{
struct tleaf_it_s *data_it = it->data;
return excit_rewind(data_it->levels);
}
static int tleaf_it_copy(excit_t dst_it, const excit_t src_it)
{
int err = EXCIT_SUCCESS;
struct tleaf_it_s *dst = dst_it->data;
struct tleaf_it_s *src = src_it->data;
/* dst is initialised, then wipe it */
if (dst->buf != NULL) {
free(dst->buf);
free(dst->arities);
free(dst->order);
free(dst->order_inverse);
excit_free(dst->levels);
}
/* dst is not initialized (anymore) */
excit_t levels = excit_dup(src->levels);
if (levels == NULL) {
err = -EXCIT_ENOMEM;
goto error;
}
err = excit_tleaf_init_with_it(dst_it, src->depth + 1, src->arities,
TLEAF_POLICY_USER, src->order, levels);
if (err != EXCIT_SUCCESS)
goto error_with_levels;
return EXCIT_SUCCESS;
error_with_levels:
excit_free(levels);
error:
return err;
}
static int tleaf_it_pos(const excit_t it, ssize_t *value)
{
struct tleaf_it_s *data_it = it->data;
return excit_pos(data_it->levels, value);
}
static ssize_t tleaf_it_value(struct tleaf_it_s *it, const int inverse)
{
ssize_t i, acc = 1, val = 0;
ssize_t *order = inverse ? it->order_inverse : it->order;
for (i = 0; i < it->depth; i++) {
val += acc * it->buf[order[i]];
acc *= it->arities[order[i]];
}
return val;
}
int tleaf_it_nth(const excit_t it, ssize_t n, ssize_t *indexes)
{
struct tleaf_it_s *data_it = it->data;
int err = excit_nth(data_it->levels, n, data_it->buf);
if (err != EXCIT_SUCCESS)
return err;
*indexes = tleaf_it_value(data_it, 0);
return EXCIT_SUCCESS;
}
int tleaf_it_peek(const excit_t it, ssize_t *value)
{
struct tleaf_it_s *data_it = it->data;
int err = excit_peek(data_it->levels, data_it->buf);
if (err != EXCIT_SUCCESS)
return err;
*value = tleaf_it_value(data_it, 0);
return EXCIT_SUCCESS;
}
int tleaf_it_next(excit_t it, ssize_t *indexes)
{
struct tleaf_it_s *data_it = it->data;
int err = excit_next(data_it->levels, data_it->buf);
if (err != EXCIT_SUCCESS)
return err;
*indexes = tleaf_it_value(data_it, 0);
return EXCIT_SUCCESS;
return tleaf_init_with_it(it, depth, arities, policy, user_policy,
NULL, NULL);
}
int tleaf_it_rank(const excit_t it, const ssize_t *indexes, ssize_t *n)
{
struct tleaf_it_s *data_it = it->data;
int err = excit_nth(data_it->levels, *indexes, data_it->buf);
if (err != EXCIT_SUCCESS)
int tleaf_split_levels(excit_t levels, const ssize_t depth, const ssize_t n, excit_t** out){
*out = malloc(sizeof(**out) * n);
if (*out == NULL)
return -EXCIT_ENOMEM;
int err = excit_product_split_dim(levels, depth, n, *out);
if (err != EXCIT_SUCCESS){
free(*out);
*out = NULL;
return err;
*n = tleaf_it_value(data_it, 1);
}
return EXCIT_SUCCESS;
}
int tleaf_it_split(const excit_t it, const ssize_t level,
int tleaf_it_split(const excit_t it, const ssize_t depth,
const ssize_t n, excit_t *out)
{
ssize_t i;
......@@ -277,55 +348,42 @@ int tleaf_it_split(const excit_t it, const ssize_t level,
return -EXCIT_EINVAL;
struct tleaf_it_s *data_it = it->data;
if (data_it->arities[level] % n != 0)
if (data_it->arities[data_it->order[depth]] % n != 0)
return -EXCIT_EINVAL;
int err = EXCIT_SUCCESS;
excit_t *levels = malloc(sizeof(*levels) * n);
if (levels == NULL) {
err = -EXCIT_ENOMEM;
goto error;
}
int err;
excit_t *levels, *levels_inverse;
err = excit_product_split_dim(data_it->levels, level, n, levels);
err = tleaf_split_levels(data_it->levels, data_it->order[depth], n, &levels);
if(err != EXCIT_SUCCESS)
return err;
err = tleaf_split_levels(data_it->levels_inverse, data_it->order_inverse[depth], n, &levels_inverse);
if (err != EXCIT_SUCCESS)
goto error_with_levels;
ssize_t *arities = malloc(sizeof(*arities) * data_it->depth);
if (arities == NULL) {
err = -EXCIT_ENOMEM;
goto error_with_levels_initialized;
}
for (i = 0; i < data_it->depth; i++)
arities[i] = data_it->arities[i];
/* arities[level] /= n; */
for (i = 0; i < n; i++) {
err = excit_tleaf_init_with_it(out[i],
data_it->depth + 1,
arities,
TLEAF_POLICY_USER,
data_it->order, levels[i]);
err = tleaf_init_with_it(out[i],
data_it->depth + 1,
data_it->arities,
TLEAF_POLICY_USER,
data_it->order, levels[i], levels_inverse[i]);
if (err != EXCIT_SUCCESS)
goto error_with_arity;
goto error_with_levels_inverse;
}
free(levels);
free(arities);
free(levels_inverse);
return EXCIT_SUCCESS;
error_with_arity:
free(arities);
error_with_levels_initialized:
error_with_levels_inverse:
for (i = 0; i < n; i++)
excit_free(levels[i]);
excit_free(levels_inverse[i]);
free(levels_inverse);
error_with_levels:
for (i = 0; i < n; i++)
excit_free(levels[i]);
free(levels);
error:
return err;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment