From 1eb964362326b2c0a85896ec96a2000a8fd29b63 Mon Sep 17 00:00:00 2001 From: i-evi Date: Thu, 24 Sep 2020 17:30:36 +0800 Subject: [PATCH] basic fn --- src/cc_array.c | 15 +++--- src/cc_basic.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++-- src/cc_basic.h | 3 ++ src/cc_tensor.c | 11 ++++ src/cc_tensor.h | 3 ++ 5 files changed, 153 insertions(+), 10 deletions(-) diff --git a/src/cc_array.c b/src/cc_array.c index 99fcc35..5708cf4 100644 --- a/src/cc_array.c +++ b/src/cc_array.c @@ -395,6 +395,8 @@ void cc_array_mean(const void *arr, int arrlen, void *x, int dt) #define PRINT_ARRAY_CASE(_DT, _dt) \ case _DT: \ fprintf(fp, pat, *((_dt*)a + i)); \ + if (i < (arrlen - 1)) \ + fputc(' ', fp); \ break; void cc_print_array(const void *a, int arrlen, int dt, void *stream) { @@ -403,26 +405,26 @@ void cc_print_array(const void *a, int arrlen, int dt, void *stream) FILE *fp = stream ? (FILE*)stream : stdout; switch (dt) { case CC_FLOAT32: - pat = "%f "; + pat = "%f"; break; case CC_FLOAT64: - pat = "%lf "; + pat = "%lf"; break; case CC_UINT8: case CC_UINT16: case CC_UINT32: - pat = "%d "; + pat = "%d"; break; case CC_UINT64: - pat = "%ld "; + pat = "%ld"; break; case CC_INT8: case CC_INT16: case CC_INT32: - pat = "%d "; + pat = "%d"; break; case CC_INT64: - pat = "%ld "; + pat = "%ld"; break; default: utlog_format(UTLOG_ERR, @@ -447,5 +449,4 @@ void cc_print_array(const void *a, int arrlen, int dt, void *stream) break; } } - printf("\n"); } diff --git a/src/cc_basic.c b/src/cc_basic.c index 3518a61..aa24a57 100644 --- a/src/cc_basic.c +++ b/src/cc_basic.c @@ -131,12 +131,137 @@ int cc_tsrcmp_by_shape(const cc_tensor_t *a, const cc_tensor_t *b) return 0; } +cc_tensor_t *cc_tensor_stack(cc_tensor_t **tsr, + cc_int32 ntsr, cc_int32 axis, const char *name) +{ + cc_tensor_t *yield; + cc_int32 *shape; + cc_int32 i, dim, size, umem, ymem; + cc_int32 ncp = 0, nstp = 0; + cc_int32 off = 0, unit = 1; + dim = cc_tensor_dimension(tsr[0]); + cc_assert_ptr(shape = + (cc_int32*)calloc(dim + 2, sizeof(cc_int32))); + if (dim == axis) { /* axis <= dim */ + off = 1; + shape[0] = 1; + } + memcpy(shape + off, + tsr[0]->shape, dim * sizeof(cc_int32)); + shape[dim + off - 1 - axis] *= ntsr; + cc_assert_ptr(yield = + cc_create_tensor(shape, *tsr[0]->dtype, name)); + for (i = 0; i < axis; ++i) { + unit *= tsr[0]->shape[dim - i - 1]; + } + size = cc_dtype_size(*tsr[0]->dtype); + ymem = list_getlen(yield->container, CC_TENSOR_DATA); + umem = unit * size; + i = 0; + do { + memcpy(yield->data + ncp, + tsr[i++]->data + nstp, umem); + ncp += umem; + if (i == ntsr) { + i = 0; + nstp += umem; + } + } while (ncp != ymem); + free(shape); + return yield; +} + +static void _cc_print_tensor_indent(int n) +{ + FILE *ostream = (FILE*)utlog_get_ostream(); + while (n--) + fputc(' ', ostream); +} + +#define CC_PRINT_TENSOR_PROC \ + i = 0, fidt = 0, cidt = 0; \ + do { \ + while (sops[i]) { \ + if (fidt) { \ + _cc_print_tensor_indent(cidt); \ + fidt = 0; \ + } \ + fputc('[', ostream); \ + cidt++; \ + i++; \ + } \ + fputc('[', ostream); \ + cc_print_array(tensor->data + npt, lelem, \ + *tensor->dtype, ostream); \ + fputc(']', ostream); \ + npt += lsize; \ + if (i - 1 < 0) { \ + fputc('\n', ostream); \ + _cc_print_tensor_indent(cidt); \ + break; \ + } \ + sops[i - 1]--; \ + if (sops[i - 1]) { \ + fputc('\n', ostream); \ + _cc_print_tensor_indent(cidt); \ + } else { \ + fputc(']', ostream); \ + cidt--; \ + fidt++; \ + i = i - 2; \ + if (i < 0) { \ + fputc('\n', ostream); \ + break; \ + } \ + if (sops[i]) { \ + sops[i]--; \ + if (sops[i]) { \ + for (j = ++i; j < (dim - 1); ++j) \ + sops[j] = sbak[j]; \ + } else { \ + fputc(']', ostream); \ + cidt--; \ + fidt++; \ + while (i > 0) { \ + if (--sops[--i]) { \ + for (j = ++i; j < (dim - 1); ++j) \ + sops[j] = sbak[j]; \ + break; \ + } else { \ + fputc(']', ostream); \ + cidt--; \ + fidt++; \ + } \ + } \ + } \ + } \ + fputc('\n', ostream); \ + } \ + } while (sops[0]); + void cc_print_tensor(const cc_tensor_t *tensor) { + cc_int32 *sops, *sbak; + int fidt, cidt; + cc_int32 i, j, dim, lelem, lsize, esize, ssize, npt = 0; + FILE *ostream = (FILE*)utlog_get_ostream(); + dim = cc_tensor_dimension(tensor); + esize = cc_dtype_size(*tensor->dtype); + lelem = tensor->shape[dim - 1]; + lsize = lelem * esize; + ssize = (dim + 1) * sizeof(cc_int32); + cc_assert_ptr(sops = + (cc_int32*)calloc(dim + 1, sizeof(cc_int32))); + cc_assert_ptr(sbak = + (cc_int32*)calloc(dim + 1, sizeof(cc_int32))); + memcpy(sops, tensor->shape, ssize); + memcpy(sbak, tensor->shape, ssize); + sops[dim - 1] = 0; + sbak[dim - 1] = 0; cc_print_tensor_property(tensor); - cc_print_array(tensor->data, - cc_tensor_elements(tensor), *tensor->dtype, - utlog_get_ostream()); + CC_PRINT_TENSOR_PROC; + free(sops); + free(sbak); } void cc_set_tensor(cc_tensor_t *tensor, void *v) diff --git a/src/cc_basic.h b/src/cc_basic.h index 612f764..7fc6377 100644 --- a/src/cc_basic.h +++ b/src/cc_basic.h @@ -24,6 +24,9 @@ cc_tensor_t *cc_tensor_reshape( int cc_tsrcmp_by_shape(const cc_tensor_t *a, const cc_tensor_t *b); +cc_tensor_t *cc_tensor_stack(cc_tensor_t **tsr, + cc_int32 ntsr, cc_int32 axis, const char *name); + void cc_print_tensor(const cc_tensor_t *tensor); void cc_set_tensor(cc_tensor_t *tensor, void *v); diff --git a/src/cc_tensor.c b/src/cc_tensor.c index c40422c..86f7c4b 100644 --- a/src/cc_tensor.c +++ b/src/cc_tensor.c @@ -114,6 +114,17 @@ cc_tensor_t *cc_load_bin(const char *filename, return tensor; } +cc_tensor_t *cc_tensor_from_array(void *arr, + const cc_int32 *shape, cc_dtype dtype, const char *name) +{ + cc_int32 memsize; + cc_tensor_t *tensor; + cc_assert_ptr(tensor = cc_create_tensor(shape, dtype, name)); + memsize = list_getlen(tensor->container, CC_TENSOR_DATA); + memcpy(tensor->data, arr, memsize); + return tensor; +} + void cc_save_tensor(const cc_tensor_t *tensor, const char *filename) { list_export(tensor->container, filename); diff --git a/src/cc_tensor.h b/src/cc_tensor.h index 9a70775..1e7942b 100644 --- a/src/cc_tensor.h +++ b/src/cc_tensor.h @@ -39,6 +39,9 @@ cc_tensor_t *cc_load_tensor(const char *filename); cc_tensor_t *cc_load_bin(const char *filename, const cc_int32 *shape, cc_dtype dtype, const char *name); +cc_tensor_t *cc_tensor_from_array(void *arr, + const cc_int32 *shape, cc_dtype dtype, const char *name); + void cc_save_tensor(const cc_tensor_t *tensor, const char *filename); void cc_free_tensor(cc_tensor_t *tensor);