Skip to content

Commit

Permalink
Improve runtime implementation of 'diagonal'.
Browse files Browse the repository at this point in the history
- Rewrote runtime functions for 'diagonal' to handle all kinds of array
  expressions, and not only array literals.

Belonging to [master]:
  - OpenModelica/OMCompiler#2954
  • Loading branch information
perost authored and OpenModelica-Hudson committed Mar 1, 2019
1 parent cc9ae78 commit 0470a5b
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 51 deletions.
8 changes: 3 additions & 5 deletions Compiler/Template/CodegenCFunctions.tpl
Expand Up @@ -5922,13 +5922,11 @@ simple_alloc_1d_base_array(&<%tvar%>, <%nElts%>, <%tvardata%>);
let &preExp += 'identity_alloc_<%arr_tp_str%>(<%var1%>, &<%tvar%>);<%\n%>'
tvar
case CALL(path=IDENT(name="diagonal"), expLst={A as ARRAY(__)}) then
case CALL(path=IDENT(name="diagonal"), expLst={A}) then
let var1 = daeExpAsLValue(A, context, &preExp, &varDecls, &auxFunction)
let arr_tp_str = expTypeFromExpArray(A)
let tvar = tempDecl(arr_tp_str, &varDecls)
let params = (A.array |> e =>
daeExp(e, context, &preExp, &varDecls, &auxFunction)
;separator=", ")
let &preExp += 'diagonal_alloc_<%arr_tp_str%>(&<%tvar%>, <%listLength(A.array)%>, <%params%>);<%\n%>'
let &preExp += 'diagonal_alloc_<%arr_tp_str%>(&<%var1%>, &<%tvar%>);<%\n%>'
tvar
case CALL(path=IDENT(name="String"), expLst={s, format}) then
Expand Down
47 changes: 24 additions & 23 deletions SimulationRuntime/c/util/integer_array.c
Expand Up @@ -1388,49 +1388,50 @@ void identity_alloc_integer_array(int n,integer_array_t* dest)
identity_integer_array(n,dest);
}

void diagonal_integer_array(const integer_array_t * v,integer_array_t* dest)
static void diagonal_integer_array_impl(const integer_array_t *v, integer_array_t* dest)
{
size_t i;
size_t j;
size_t n;

/* Assert that v is a vector */
omc_assert_macro(v->ndims == 1);

/* Assert that dest is a nxn matrix */
n = v->dim_size[0];
omc_assert_macro(dest->ndims == 2);
omc_assert_macro((dest->dim_size[0] == n) && (dest->dim_size[1] == n));

for(i = 0; i < (n * n); ++i) {
integer_set(dest, i, 0);
}
j = 0;
for(i = 0; i < n; ++i) {
integer_set(dest, j, integer_get(*v, i));
j += n+1;
j += n + 1;
}
}

void diagonal_alloc_integer_array(integer_array_t* dest, int ndims, ...)
void diagonal_integer_array(const integer_array_t * v,integer_array_t* dest)
{
size_t i;
size_t j;
va_list ap;
size_t n;

alloc_integer_array(dest,2,ndims,ndims);
/* Assert that v is a vector */
omc_assert_macro(v->ndims == 1);

for(i = 0; i < (ndims * ndims); ++i) {
integer_set(dest, i, 0);
}
/* Assert that dest is a nxn matrix */
n = v->dim_size[0];
omc_assert_macro(dest->ndims == 2);
omc_assert_macro((dest->dim_size[0] == n) && (dest->dim_size[1] == n));

va_start(ap,ndims);
j = 0;
for(i = 0; i < ndims; ++i) {
integer_set(dest, j, va_arg(ap, modelica_integer));
j += ndims+1;
}
va_end(ap);
diagonal_integer_array_impl(v, dest);
}

void diagonal_alloc_integer_array(const integer_array_t* v, integer_array_t* dest)
{
size_t n;

/* Assert that v is a vector */
omc_assert_macro(v->ndims == 1);

/* Allocate a n*n matrix and fill it. */
n = v->dim_size[0];
alloc_integer_array(dest, 2, n, n);
diagonal_integer_array_impl(v, dest);
}

void fill_integer_array(integer_array_t* dest,modelica_integer s)
Expand Down
2 changes: 1 addition & 1 deletion SimulationRuntime/c/util/integer_array.h
Expand Up @@ -254,7 +254,7 @@ extern void identity_integer_array(int n, integer_array_t* dest);
extern void identity_alloc_integer_array(int n, integer_array_t* dest);

extern void diagonal_integer_array(const integer_array_t * v,integer_array_t* dest);
extern void diagonal_alloc_integer_array(integer_array_t* dest, int ndims, ...);
extern void diagonal_alloc_integer_array(const integer_array_t *v, integer_array_t* dest);
extern void fill_integer_array(integer_array_t* dest,modelica_integer s);
extern void linspace_integer_array(modelica_integer x1,modelica_integer x2,int n,
integer_array_t* dest);
Expand Down
45 changes: 24 additions & 21 deletions SimulationRuntime/c/util/real_array.c
Expand Up @@ -1368,49 +1368,52 @@ void identity_real_array(int n, real_array_t* dest)
}
}

void diagonal_real_array(const real_array_t * v,real_array_t* dest)
static void diagonal_real_array_impl(const real_array_t *v, real_array_t* dest)
{
size_t i;
size_t j;
size_t n;

/* Assert that v is a vector */
omc_assert_macro(v->ndims == 1);

/* Assert that dest is a nxn matrix */
n = v->dim_size[0];
omc_assert_macro(dest->ndims == 2);
omc_assert_macro((dest->dim_size[0] == n) && (dest->dim_size[1] == n));

for(i = 0; i < (n * n); ++i) {
real_set(dest, i, 0);
}
j = 0;
for(i = 0; i < n; ++i) {
real_set(dest, j, real_get(*v, i));
j += n+1;
j += n + 1;
}
}

void diagonal_alloc_real_array(real_array_t* dest, int ndims, ...)
void diagonal_real_array(const real_array_t * v,real_array_t* dest)
{
size_t i;
size_t j;
va_list ap;
size_t n;

alloc_real_array(dest,2,ndims,ndims);
/* Assert that v is a vector */
omc_assert_macro(v->ndims == 1);

for(i = 0; i < (ndims * ndims); ++i) {
real_set(dest, i, 0);
}
/* Assert that dest is a nxn matrix */
n = v->dim_size[0];
omc_assert_macro(dest->ndims == 2);
omc_assert_macro((dest->dim_size[0] == n) && (dest->dim_size[1] == n));

va_start(ap,ndims);
j = 0;
for(i = 0; i < ndims; ++i) {
real_set(dest, j, va_arg(ap, modelica_real));
j += ndims+1;
}
va_end(ap);
diagonal_real_array_impl(v, dest);
}

void diagonal_alloc_real_array(const real_array_t* v, real_array_t* dest)
{
size_t n;

/* Assert that v is a vector */
omc_assert_macro(v->ndims == 1);

/* Allocate a n*n matrix and fill it. */
n = v->dim_size[0];
alloc_real_array(dest, 2, n, n);
diagonal_real_array_impl(v, dest);
}

void fill_real_array(real_array_t* dest,modelica_real s)
Expand Down
2 changes: 1 addition & 1 deletion SimulationRuntime/c/util/real_array.h
Expand Up @@ -237,7 +237,7 @@ extern void outer_product_alloc_real_array(real_array_t* v1, real_array_t* v2, r
extern void outer_product_real_array(const real_array_t * v1,const real_array_t * v2, real_array_t* dest);
extern void identity_real_array(int n, real_array_t* dest);
extern void diagonal_real_array(const real_array_t * v,real_array_t* dest);
extern void diagonal_alloc_real_array(real_array_t* dest, int ndims, ...);
extern void diagonal_alloc_real_array(const real_array_t* v, real_array_t* dest);
extern void fill_real_array(real_array_t* dest,modelica_real s);
extern void linspace_real_array(modelica_real x1,modelica_real x2,int n,
real_array_t* dest);
Expand Down

0 comments on commit 0470a5b

Please sign in to comment.