191 lines
4.5 KiB
C
191 lines
4.5 KiB
C
/*
|
|
|
|
This program is part of the TACLeBench benchmark suite.
|
|
Version V 2.0
|
|
|
|
Name: ludcmp
|
|
|
|
Author: Sung-Soo Lim
|
|
|
|
Function: Simultaneous linear equations by LU decomposition.
|
|
|
|
Source: SNU-RT Benchmark Suite, via MRTC
|
|
http://www.mrtc.mdh.se/projects/wcet/wcet_bench/ludcmp/ludcmp.c
|
|
|
|
Changes: Moved initialization into separate function.
|
|
|
|
License: May be used, modified, and re-distributed freely, but
|
|
the SNU-RT Benchmark Suite must be acknowledged
|
|
|
|
*/
|
|
|
|
/*
|
|
This program is derived from the SNU-RT Benchmark Suite for Worst
|
|
Case Timing Analysis by Sung-Soo Lim
|
|
|
|
III-4. ludcmp.c : Simultaneous Linear Equations by LU Decomposition
|
|
(from the book C Programming for EEs by Hyun Soon Ahn)
|
|
*/
|
|
|
|
/*
|
|
Forward declaration of functions
|
|
*/
|
|
|
|
// Wasm loop bounds
|
|
|
|
|
|
|
|
|
|
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
|
|
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
|
|
|
|
__attribute__((always_inline)) static inline void ludcmp_init(void);
|
|
__attribute__((always_inline)) static inline int ludcmp_return(void);
|
|
__attribute__((always_inline)) static inline int ludcmp_test(int n, double eps);
|
|
__attribute__((noinline)) __attribute__((export_name("entrypoint")))
|
|
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
|
|
ludcmp_main(void);
|
|
__attribute__((noinline)) __attribute__((export_name("main")))
|
|
__attribute__((noinline)) __attribute__((export_name("main"))) int
|
|
main(void);
|
|
|
|
double ludcmp_a[50][50], ludcmp_b[50], ludcmp_x[50];
|
|
int ludcmp_chkerr;
|
|
|
|
__attribute__((always_inline)) static inline void
|
|
ludcmp_init(void) {
|
|
int i, j, n = 5;
|
|
double w;
|
|
volatile int x = 0;
|
|
|
|
__pragma_loopbound(6, 6);
|
|
for (i = 0; i <= n; i++) {
|
|
w = 0;
|
|
__pragma_loopbound(6, 6);
|
|
for (j = 0; j <= n; j++) {
|
|
ludcmp_a[i][j] = (i + 1) + (j + 1);
|
|
|
|
if (i == j)
|
|
ludcmp_a[i][j] *= 10;
|
|
w += ludcmp_a[i][j];
|
|
|
|
if (x)
|
|
ludcmp_a[i][j] += x;
|
|
}
|
|
|
|
ludcmp_b[i] = w;
|
|
if (x)
|
|
ludcmp_b[i] += x;
|
|
}
|
|
}
|
|
|
|
__attribute__((always_inline)) static inline int
|
|
ludcmp_return(void) {
|
|
int i, n = 5;
|
|
double checksum = ludcmp_chkerr;
|
|
|
|
__pragma_loopbound(6, 6);
|
|
for (i = 0; i <= n; i++)
|
|
checksum += ludcmp_x[i];
|
|
|
|
/* allow rounding errors for the checksum */
|
|
checksum -= 6.0;
|
|
return ((checksum < 0.000001 && checksum > -0.000001) ? 0 : -1);
|
|
}
|
|
|
|
__attribute__((always_inline)) static inline double
|
|
ludcmp_fabs(double n) {
|
|
double f;
|
|
|
|
if (n >= 0)
|
|
f = n;
|
|
else
|
|
f = -n;
|
|
|
|
return f;
|
|
}
|
|
|
|
__attribute__((always_inline)) static inline int
|
|
ludcmp_test(int n, double eps) {
|
|
int i, j, k;
|
|
double w, y[100];
|
|
|
|
if (n > 99 || eps <= 0)
|
|
return (999);
|
|
|
|
__pragma_loopbound(5, 5);
|
|
for (i = 0; i < n; i++) {
|
|
if (ludcmp_fabs(ludcmp_a[i][i]) <= eps)
|
|
return (1);
|
|
|
|
__pragma_loopbound(1, 5);
|
|
for (j = i + 1; j <= n; j++) {
|
|
w = ludcmp_a[j][i];
|
|
|
|
if (i != 0) {
|
|
__pragma_loopbound(1, 4);
|
|
for (k = 0; k < i; k++)
|
|
w -= ludcmp_a[j][k] * ludcmp_a[k][i];
|
|
}
|
|
|
|
ludcmp_a[j][i] = w / ludcmp_a[i][i];
|
|
}
|
|
|
|
__pragma_loopbound(1, 5);
|
|
for (j = i + 1; j <= n; j++) {
|
|
w = ludcmp_a[i + 1][j];
|
|
|
|
__pragma_loopbound(1, 5);
|
|
for (k = 0; k <= i; k++)
|
|
w -= ludcmp_a[i + 1][k] * ludcmp_a[k][j];
|
|
|
|
ludcmp_a[i + 1][j] = w;
|
|
}
|
|
}
|
|
|
|
y[0] = ludcmp_b[0];
|
|
|
|
__pragma_loopbound(5, 5);
|
|
for (i = 1; i <= n; i++) {
|
|
w = ludcmp_b[i];
|
|
|
|
__pragma_loopbound(1, 5);
|
|
for (j = 0; j < i; j++)
|
|
w -= ludcmp_a[i][j] * y[j];
|
|
|
|
y[i] = w;
|
|
}
|
|
|
|
ludcmp_x[n] = y[n] / ludcmp_a[n][n];
|
|
|
|
__pragma_loopbound(5, 5);
|
|
for (i = n - 1; i >= 0; i--) {
|
|
w = y[i];
|
|
|
|
__pragma_loopbound(1, 5);
|
|
for (j = i + 1; j <= n; j++)
|
|
w -= ludcmp_a[i][j] * ludcmp_x[j];
|
|
|
|
ludcmp_x[i] = w / ludcmp_a[i][i];
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
__attribute__((noinline)) __attribute__((export_name("entrypoint")))
|
|
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
|
|
ludcmp_main(void) {
|
|
int n = 5;
|
|
double eps = 1;
|
|
ludcmp_chkerr = ludcmp_test(n, eps);
|
|
}
|
|
|
|
__attribute__((noinline)) __attribute__((export_name("main")))
|
|
__attribute__((noinline)) __attribute__((export_name("main"))) int
|
|
main(void) {
|
|
ludcmp_init();
|
|
ludcmp_main();
|
|
|
|
return (ludcmp_return());
|
|
}
|