ported over working martrix multiplication
This commit is contained in:
16
Tests/isa/CPrograms/Benchmarks/Matrixmul/build.sh
Normal file
16
Tests/isa/CPrograms/Benchmarks/Matrixmul/build.sh
Normal file
@@ -0,0 +1,16 @@
|
||||
scp ../../start.S home-1:/home/akilan/cheri/output/sdk/bin/
|
||||
# scp main.c home-1:/home/akilan/cheri/output/sdk/bin/
|
||||
scp ../../malloc.c home-1:/home/akilan/cheri/output/sdk/bin/
|
||||
scp ../../malloc_test.c home-1:/home/akilan/cheri/output/sdk/bin/
|
||||
scp ../../link.ld home-1:/home/akilan/cheri/output/sdk/bin/
|
||||
|
||||
scp matrixmul.c home-1:/home/akilan/cheri/output/sdk/bin/
|
||||
|
||||
# ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./clang --target=riscv64-unknown-elf -march=rv64gcxcheri -mabi=lp64d -nostdlib -nostartfiles -fno-builtin-malloc -mcmodel=medany -Wl,-Ttext=0x80000000 -o testC start.S malloc.c memaccess.c'
|
||||
ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./clang --target=riscv64-unknown-elf -march=rv64gcxcheri -mabi=lp64d -DDEFINE_MALLOC -DDEFINE_FREE -nostdlib -nostartfiles -fno-builtin-malloc -mcmodel=medany -T link.ld -o testC start.S matrixmul.c malloc.c malloc_test.c'
|
||||
|
||||
# ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./llvm-objdump -d testC'
|
||||
|
||||
scp home-1:/home/akilan/cheri/output/sdk/bin/testC ../../../
|
||||
|
||||
|
||||
215
Tests/isa/CPrograms/Benchmarks/Matrixmul/matrixmul.c
Normal file
215
Tests/isa/CPrograms/Benchmarks/Matrixmul/matrixmul.c
Normal file
@@ -0,0 +1,215 @@
|
||||
// Source: https://github.com/ivanbgd/Matrix-Multiplication-MatMul-C/blob/master/matmul_1d_seq.c
|
||||
#define MATMUL_1D
|
||||
#ifdef MATMUL_1D
|
||||
|
||||
/* Matrices are represented as 1-D arrays in memory.
|
||||
* That means they are contiguous in memory.
|
||||
* Minimum dimension is 1, not 0, and internal dimensions must match. */
|
||||
|
||||
// #include <math.h>
|
||||
// #include <omp.h>
|
||||
// #include <stdio.h>
|
||||
// #include <stdlib.h>
|
||||
// #include <string.h>
|
||||
// #include <time.h>
|
||||
#include <cheriintrin.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void free(void * __capability ptr);
|
||||
void * __capability malloc(size_t size);
|
||||
|
||||
/* Initializes vector or matrix, sequentially, with indices. */
|
||||
void init_seq(double * __capability a, const unsigned n_rows_a, const unsigned n_cols_a) {
|
||||
for (size_t i = 0; i < n_rows_a; i++) {
|
||||
for (size_t j = 0; j < n_cols_a; j++) {
|
||||
a[i*n_cols_a + j] = 2.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static unsigned int seed = 123456789; // must be initialized somehow
|
||||
|
||||
// unsigned int rand_test(void)
|
||||
// {
|
||||
// seed = (1103515245 * seed + 12345);
|
||||
// return (seed >> 16) & 0x7FFF; // 15-bit result
|
||||
// }
|
||||
|
||||
// /* Initializes vector or matrix, randomly. */
|
||||
// void init_rand(double *a, const unsigned n_rows_a, const unsigned n_cols_a) {
|
||||
// for (size_t i = 0; i < n_rows_a; i++) {
|
||||
// for (size_t j = 0; j < n_cols_a; j++) {
|
||||
// a[i*n_cols_a + j] = rand_test() / 32767.0;
|
||||
// // rand_test() / (double)RAND_MAX;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
/* Takes and returns a new matrix, t, which is a transpose of the original one, m.
|
||||
It's also flat in memory, i.e., 1-D, but it should be looked at as a transpose
|
||||
of m, meaning, n_rows_t == n_cols_m, and n_cols_t == n_rows_m.
|
||||
The original matrix m stays intact. */
|
||||
double __capability * transpose(const double __capability *m, const unsigned n_rows_m, const unsigned n_cols_m, double __capability *t) {
|
||||
for (size_t i = 0; i < n_rows_m; i++) {
|
||||
for (size_t j = 0; j < n_cols_m; j++) {
|
||||
t[j*n_rows_m + i] = m[i*n_cols_m + j];
|
||||
}
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Dot product of two arrays, or matrix product
|
||||
* Allocates and returns an array.
|
||||
* This variant doesn't transpose matrix b, and it's a lot slower. */
|
||||
double * __capability dot_simple(const double * __capability a, const unsigned n_rows_a, const unsigned n_cols_a,\
|
||||
const double * __capability b, const unsigned n_rows_b, const unsigned n_cols_b) {
|
||||
|
||||
if (n_cols_a != n_rows_b) {
|
||||
// printf("#columns A must be equal to #rows B!\n");
|
||||
// system("pause");
|
||||
// exit(-2);
|
||||
}
|
||||
|
||||
double *__capability c = malloc(n_rows_a * n_cols_b * sizeof(*c));
|
||||
if (c == NULL) {
|
||||
// printf("Couldn't allocate memory!\n");
|
||||
// system("pause");
|
||||
// exit(-1);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < n_rows_a; i++) {
|
||||
for (size_t k = 0; k < n_cols_b; k++) {
|
||||
double sum = 0.0;
|
||||
for (size_t j = 0; j < n_cols_a; j++) {
|
||||
sum += a[i*n_cols_a + j] * b[j*n_cols_b + k];
|
||||
}
|
||||
c[i*n_cols_b + k] = sum;
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/* Dot product of two arrays, or matrix product
|
||||
* Allocates and returns an array.
|
||||
* This variant transposes matrix b, and it's a lot faster. */
|
||||
double * __capability dot(const double __capability *a, const unsigned n_rows_a, const unsigned n_cols_a, \
|
||||
const double * __capability b, const unsigned n_rows_b, const unsigned n_cols_b) {
|
||||
|
||||
if (n_cols_a != n_rows_b) {
|
||||
// printf("#columns A must be equal to #rows B!\n");
|
||||
// system("pause");
|
||||
// exit(-2);
|
||||
}
|
||||
|
||||
double * __capability bt = malloc(n_rows_b * n_cols_b * sizeof(*b));
|
||||
|
||||
double * __capability c = malloc(n_rows_a * n_cols_b * sizeof(*c));
|
||||
|
||||
if ((c == NULL) || (bt == NULL)) {
|
||||
// printf("Couldn't allocate memory!\n");
|
||||
// system("pause");
|
||||
// exit(-1);
|
||||
}
|
||||
|
||||
bt = transpose(b, n_rows_b, n_cols_b, bt);
|
||||
|
||||
for (size_t i = 0; i < n_rows_a; i++) {
|
||||
for (size_t k = 0; k < n_cols_b; k++) {
|
||||
double sum = 0.0;
|
||||
for (size_t j = 0; j < n_cols_a; j++) {
|
||||
sum += a[i*n_cols_a + j] * bt[k*n_rows_b + j];
|
||||
}
|
||||
c[i*n_cols_b + k] = sum;
|
||||
}
|
||||
}
|
||||
|
||||
free(bt);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/* Prints vector, or matrix. */
|
||||
// void print(const double *a, const unsigned n_rows_a, const unsigned n_cols_a) {
|
||||
// for (size_t i = 0; i < n_rows_a; i++) {
|
||||
// for (size_t j = 0; j < n_cols_a; j++) {
|
||||
// printf("%8.3f ", a[i*n_cols_a + j]);
|
||||
// }
|
||||
// printf("\n");
|
||||
// }
|
||||
// printf("\n");
|
||||
// }
|
||||
|
||||
int main(void) {
|
||||
/* Intializes random number generator */
|
||||
// time_t t;
|
||||
// srand((unsigned)time(&t));
|
||||
// srand(0);
|
||||
|
||||
/* For measuring time */
|
||||
double t0, t1;
|
||||
|
||||
const unsigned scale = 14;
|
||||
const unsigned n_rows_a = 4 * scale;
|
||||
const unsigned n_cols_a = 3 * scale;
|
||||
const unsigned n_rows_b = 3 * scale;
|
||||
const unsigned n_cols_b = 2 * scale;
|
||||
|
||||
double __capability *a = malloc(n_rows_a * n_cols_a * sizeof(*a));
|
||||
double __capability *b = malloc(n_rows_b * n_cols_b * sizeof(*b));
|
||||
double __capability *c = NULL;
|
||||
double __capability *d = NULL;
|
||||
|
||||
if (!a || !b) {
|
||||
// printf("Couldn't allocate memory!\n");
|
||||
while(1);
|
||||
// system("pause");
|
||||
// exit(-1);
|
||||
}
|
||||
|
||||
// init_rand(a, n_rows_a, n_cols_a);
|
||||
// init_rand(b, n_rows_b, n_cols_b);
|
||||
|
||||
init_seq(a, n_rows_a, n_cols_a);
|
||||
init_seq(b, n_rows_b, n_cols_b);
|
||||
|
||||
// for (size_t i = 0; i < n_rows_a; i++) {
|
||||
// for (size_t j = 0; j < n_cols_a; j++) {
|
||||
// a[i*n_cols_a + j] = i*n_cols_a + j;
|
||||
// }
|
||||
// }
|
||||
|
||||
// t0 = omp_get_wtime();
|
||||
c = dot_simple(a, n_rows_a, n_cols_a, b, n_rows_b, n_cols_b);
|
||||
// t1 = omp_get_wtime();
|
||||
// printf("Dot Simple: Elapsed time %.3f s\n", t1 - t0);
|
||||
|
||||
// // t0 = omp_get_wtime();
|
||||
d = dot(a, n_rows_a, n_cols_a, b, n_rows_b, n_cols_b);
|
||||
// t1 = omp_get_wtime();
|
||||
// printf("Dot: Elapsed time %.3f s\n", t1 - t0);
|
||||
|
||||
// if (scale == 1) {
|
||||
// // printf("Matrix A:\n");
|
||||
// // print(a, n_rows_a, n_cols_a);
|
||||
// // // printf("Matrix B:\n");
|
||||
// // print(b, n_rows_b, n_cols_b);
|
||||
// // // printf("Matrix C:\n");
|
||||
// // print(c, n_rows_a, n_cols_b);
|
||||
// // // printf("Matrix D:\n");
|
||||
// // print(d, n_rows_a, n_cols_b);
|
||||
// }
|
||||
|
||||
free(a);
|
||||
free(b);
|
||||
free(c);
|
||||
free(d);
|
||||
|
||||
// system("pause");
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
#endif // MATMUL_1D
|
||||
@@ -27,10 +27,10 @@ All rights reserved.
|
||||
|
||||
#define NPAD 7
|
||||
#define MIN_WSS sizeof(struct l)
|
||||
#define MAX_WSS 32 //2^32
|
||||
#define MAX_WSS 64 //2^32
|
||||
|
||||
void free(void * __capability ptr);
|
||||
void * __capability malloc(size_t size);
|
||||
void free_test(void * __capability ptr);
|
||||
void * __capability malloc_test(size_t size);
|
||||
|
||||
|
||||
// struct l{
|
||||
@@ -278,7 +278,7 @@ void * walk(void * __capability param)
|
||||
|
||||
// printf("%d,%ld,%ld,%ld\n",data->thread_index,data->working_set_size, end-start, data->working_set_size/sizeof(struct l));
|
||||
|
||||
free(data);
|
||||
free_test(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -298,7 +298,7 @@ int main(void)
|
||||
|
||||
// pthread_t threads[NTHREADS];
|
||||
|
||||
root=malloc(MAX_WSS/sizeof(struct l) * sizeof(struct l));
|
||||
root=malloc_test(MAX_WSS/sizeof(struct l) * sizeof(struct l));
|
||||
|
||||
for(working_set_size=MIN_WSS;working_set_size<MAX_WSS;working_set_size=working_set_size<<1)
|
||||
{
|
||||
@@ -331,7 +331,7 @@ int main(void)
|
||||
// for(i=0;i<NTHREADS;i++)
|
||||
// pthread_join(threads[i],NULL);
|
||||
// #else
|
||||
tdata = malloc(sizeof(struct thread_start_data));
|
||||
tdata = malloc_test(sizeof(struct thread_start_data));
|
||||
tdata->thread_index=0;
|
||||
tdata->root=root;
|
||||
tdata->working_set_size=working_set_size;
|
||||
@@ -348,7 +348,7 @@ int main(void)
|
||||
// printf("-----------------------------------------------");
|
||||
|
||||
|
||||
free(root);
|
||||
free_test(root);
|
||||
// root = NULL;
|
||||
|
||||
// while(1);
|
||||
|
||||
@@ -7,7 +7,7 @@ scp ../../link.ld home-1:/home/akilan/cheri/output/sdk/bin/
|
||||
scp richards.c home-1:/home/akilan/cheri/output/sdk/bin/
|
||||
|
||||
# ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./clang --target=riscv64-unknown-elf -march=rv64gcxcheri -mabi=lp64d -nostdlib -nostartfiles -fno-builtin-malloc -mcmodel=medany -Wl,-Ttext=0x80000000 -o testC start.S malloc.c memaccess.c'
|
||||
ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./clang --target=riscv64-unknown-elf -march=rv64gcxcheri -mabi=lp64d -DDEFINE_MALLOC -DDEFINE_FREE -nostdlib -nostartfiles -fno-builtin-malloc -mcmodel=medany -T link.ld -o testC start.S richards.c malloc.c malloc_test.c'
|
||||
ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./clang --target=riscv64-unknown-elf -march=rv64gcxcheri -mabi=lp64d -DDEFINE_MALLOC -DDEFINE_FREE -nostartfiles -fno-builtin-malloc -mcmodel=medany -T link.ld -o testC start.S richards.c malloc.c malloc_test.c'
|
||||
|
||||
# ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./llvm-objdump -d testC'
|
||||
|
||||
|
||||
495
Tests/isa/CPrograms/Benchmarks/barnes/barnes.c
Normal file
495
Tests/isa/CPrograms/Benchmarks/barnes/barnes.c
Normal file
@@ -0,0 +1,495 @@
|
||||
/*
|
||||
* File: barnes_hut.c
|
||||
* --------------
|
||||
* Implements the Barnes Hut algorithm for n-body
|
||||
* simulation with galaxy-like initial conditions.
|
||||
* Uses OpenGl and GLUT for graphics. Written by:
|
||||
* Joel Backsell, Kim Torberntsson & Alexander Bilock.
|
||||
* Source: https://github.com/KimTorberntsson/Barnes-Hut/blob/master/barnes_hut.c
|
||||
*/
|
||||
|
||||
// #include <stdlib.h>
|
||||
// #include <math.h>
|
||||
// #include <stdio.h>
|
||||
// #include <math.h>
|
||||
// #include <time.h>
|
||||
// #include <GLUT/glut.h>
|
||||
|
||||
#include <cheriintrin.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "barnes_hut.h"
|
||||
// #include "graphics.h"
|
||||
|
||||
// void free(void *ptr);
|
||||
// void *malloc(size_t size);
|
||||
|
||||
void free(void * __capability ptr);
|
||||
void * __capability malloc(size_t size);
|
||||
|
||||
//Some constants and global variables
|
||||
int N = 10;
|
||||
const double L = 1, W = 1, dt = 1e-3, alpha = 0.25, V = 50, epsilon = 1e-1, grav = 0.04; //grav should be 100/N
|
||||
double __capability *x;
|
||||
double __capability *y;
|
||||
double __capability *u;
|
||||
double __capability *v;
|
||||
double __capability *force_x;
|
||||
double __capability *force_y;
|
||||
double __capability *mass;
|
||||
struct node_t __capability *root;
|
||||
|
||||
// -------- Modified by Akilan ----------
|
||||
|
||||
double my_sqrt(double x) {
|
||||
if (x <= 0) return 0;
|
||||
|
||||
double guess = x;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
guess = 0.5 * (guess + x / guess);
|
||||
}
|
||||
return guess;
|
||||
}
|
||||
|
||||
#define PI 3.141592653589793
|
||||
|
||||
double wrap_angle(double x) {
|
||||
while (x > PI) x -= 2*PI;
|
||||
while (x < -PI) x += 2*PI;
|
||||
return x;
|
||||
}
|
||||
|
||||
double my_sin(double x) {
|
||||
x = wrap_angle(x);
|
||||
|
||||
double x2 = x * x;
|
||||
return x
|
||||
- (x * x2) / 6
|
||||
+ (x * x2 * x2) / 120
|
||||
- (x * x2 * x2 * x2) / 5040;
|
||||
}
|
||||
|
||||
double my_cos(double x) {
|
||||
x = wrap_angle(x);
|
||||
|
||||
double x2 = x * x;
|
||||
return 1
|
||||
- x2 / 2
|
||||
+ (x2 * x2) / 24
|
||||
- (x2 * x2 * x2) / 720;
|
||||
}
|
||||
|
||||
// --------------------------------------
|
||||
|
||||
// -------- Modified by Akilan ----------
|
||||
|
||||
static unsigned int seed = 123456789; // must be initialized somehow
|
||||
|
||||
unsigned int rand_test(void)
|
||||
{
|
||||
seed = (1103515245 * seed + 12345);
|
||||
return (seed >> 16) & 0x7FFF; // 15-bit result
|
||||
}
|
||||
|
||||
// ---------------------------------------
|
||||
|
||||
/*
|
||||
* Function for producing a random number between two double values
|
||||
*/
|
||||
double frand(double xmin, double xmax) {
|
||||
return xmin + (xmax-xmin)*rand_test()/32767;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prints the time between two clocks in seconds
|
||||
*/
|
||||
// void print_time(clock_t s, clock_t e)
|
||||
// {
|
||||
// printf("Time: %f seconds\n", (double)(e-s)/CLOCKS_PER_SEC);
|
||||
// }
|
||||
|
||||
/*
|
||||
* This function is called every time GLUT refreshes the display.
|
||||
*/
|
||||
// void display(void) {
|
||||
// //Do a time step
|
||||
// time_step();
|
||||
|
||||
// //Draw points
|
||||
// drawPoints(x, y, N);
|
||||
// }
|
||||
|
||||
/*
|
||||
* Updates the positions of the particles of a time step.
|
||||
*/
|
||||
void time_step(void) {
|
||||
//Allocate memory for root
|
||||
root = malloc(sizeof(struct node_t));
|
||||
set_node(root);
|
||||
root->min_x = 0; root->max_x = 1; root->min_y = 0; root->max_y = 1;
|
||||
|
||||
//Put particles in tree
|
||||
for(int i = 0; i < N; i++) {
|
||||
put_particle_in_tree(i, root);
|
||||
}
|
||||
|
||||
//Calculate mass and center of mass
|
||||
calculate_mass(root);
|
||||
calculate_center_of_mass_x(root);
|
||||
calculate_center_of_mass_y(root);
|
||||
|
||||
//Calculate forces
|
||||
update_forces();
|
||||
|
||||
//Update velocities and positions
|
||||
for(int i = 0; i < N; i++) {
|
||||
double ax = force_x[i]/mass[i];
|
||||
double ay = force_y[i]/mass[i];
|
||||
u[i] += ax*dt;
|
||||
v[i] += ay*dt;
|
||||
x[i] += u[i]*dt;
|
||||
y[i] += v[i]*dt;
|
||||
|
||||
/* This of course doesn't make any sense physically,
|
||||
* but makes sure that the particles stay within the
|
||||
* bounds. Normally the particles won't leave the
|
||||
* area anyway.
|
||||
*/
|
||||
bounce(&x[i], &y[i], &u[i], &v[i]);
|
||||
}
|
||||
|
||||
//Free memory
|
||||
free_node(root);
|
||||
free(root);
|
||||
}
|
||||
|
||||
/*
|
||||
* If a particle moves beyond any of the boundaries then bounce it back
|
||||
*/
|
||||
void bounce(double __capability *x, double __capability *y, double __capability *u, double __capability *v) {
|
||||
double W = 1.0f, H = 1.0f;
|
||||
if(*x > W) {
|
||||
*x = 2*W - *x;
|
||||
*u = -*u;
|
||||
}
|
||||
|
||||
if(*x < 0) {
|
||||
*x = -*x;
|
||||
*u = -*u;
|
||||
}
|
||||
|
||||
if(*y > H) {
|
||||
*y = 2*H - *y;
|
||||
*v = -*v;
|
||||
}
|
||||
|
||||
if(*y < 0) {
|
||||
*y = -*y;
|
||||
*v = -*v;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Puts a particle recursively in the Barnes Hut quad-tree.
|
||||
*/
|
||||
void put_particle_in_tree(int new_particle, struct node_t __capability *node) {
|
||||
//If no particle is assigned to the node
|
||||
if(!node->has_particle) {
|
||||
node->particle = new_particle;
|
||||
node->has_particle = 1;
|
||||
}
|
||||
//If the node has no children
|
||||
else if(!node->has_children) {
|
||||
//Allocate and initiate children
|
||||
node->children = malloc(4*sizeof(struct node_t));
|
||||
for(int i = 0; i < 4; i++) {
|
||||
set_node(&node->children[i]);
|
||||
}
|
||||
|
||||
//Set boundaries for the children
|
||||
node->children[0].min_x = node->min_x; node->children[0].max_x = (node->min_x + node->max_x)/2;
|
||||
node->children[0].min_y = node->min_y; node->children[0].max_y = (node->min_y + node->max_y)/2;
|
||||
|
||||
node->children[1].min_x = (node->min_x + node->max_x)/2; node->children[1].max_x = node->max_x;
|
||||
node->children[1].min_y = node->min_y; node->children[1].max_y = (node->min_y + node->max_y)/2;
|
||||
|
||||
node->children[2].min_x = node->min_x; node->children[2].max_x = (node->min_x + node->max_x)/2;
|
||||
node->children[2].min_y = (node->min_y + node->max_y)/2; node->children[2].max_y = node->max_y;
|
||||
|
||||
node->children[3].min_x = (node->min_x + node->max_x)/2; node->children[3].max_x = node->max_x;
|
||||
node->children[3].min_y = (node->min_y + node->max_y)/2; node->children[3].max_y = node->max_y;
|
||||
|
||||
//Put old particle into the appropriate child
|
||||
place_particle(node->particle, node);
|
||||
|
||||
//Put new particle into the appropriate child
|
||||
place_particle(new_particle, node);
|
||||
|
||||
//It now has children
|
||||
node->has_children = 1;
|
||||
}
|
||||
//Add the new particle to the appropriate children
|
||||
else {
|
||||
//Put new particle into the appropriate child
|
||||
place_particle(new_particle, node);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Puts a particle in the right child of a node with children.
|
||||
*/
|
||||
void place_particle(int particle, struct node_t __capability *node) {
|
||||
if(x[particle] <= (node->min_x + node->max_x)/2 && y[particle] <= (node->min_y + node->max_y)/2) {
|
||||
put_particle_in_tree(particle, &node->children[0]);
|
||||
} else if(x[particle] > (node->min_x + node->max_x)/2 && y[particle] < (node->min_y + node->max_y)/2) {
|
||||
put_particle_in_tree(particle, &node->children[1]);
|
||||
} else if(x[particle] < (node->min_x + node->max_x)/2 && y[particle] > (node->min_y + node->max_y)/2) {
|
||||
put_particle_in_tree(particle, &node->children[2]);
|
||||
} else {
|
||||
put_particle_in_tree(particle, &node->children[3]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets initial values for a new node
|
||||
*/
|
||||
void set_node(struct node_t __capability *node) {
|
||||
node->has_particle = 0;
|
||||
node->has_children = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Frees memory for a node and its children recursively.
|
||||
*/
|
||||
void free_node(struct node_t __capability *node){
|
||||
if(node->has_children){
|
||||
free_node(&node->children[0]);
|
||||
free_node(&node->children[1]);
|
||||
free_node(&node->children[2]);
|
||||
free_node(&node->children[3]);
|
||||
free(node->children);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Displays the boundaries of the tree using OpenGL and GLUT.
|
||||
* Used for debugging purposes.
|
||||
*/
|
||||
// void display_tree(struct node_t *node) {
|
||||
// drawRect(node->min_x, node->max_x, node->min_y, node->max_y);
|
||||
// if(node->has_children == 1) {
|
||||
// for(int i = 0; i < 4; i++) {
|
||||
// display_tree(&node->children[i]);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
/*
|
||||
* Calculates the total mass for the node. It recursively updates the mass
|
||||
* of itself and all of its children.
|
||||
*/
|
||||
double calculate_mass(struct node_t __capability *node) {
|
||||
if(!node->has_particle) {
|
||||
node->total_mass = 0;
|
||||
} else if(!node->has_children) {
|
||||
node->total_mass = mass[node->particle];
|
||||
} else {
|
||||
node->total_mass = 0;
|
||||
for(int i = 0; i < 4; i++) {
|
||||
node->total_mass += calculate_mass(&node->children[i]);
|
||||
}
|
||||
}
|
||||
return node->total_mass;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculates the x-position of the centre of mass for the
|
||||
* node. It recursively updates the position of itself and
|
||||
* all of its children.
|
||||
*/
|
||||
double calculate_center_of_mass_x(struct node_t __capability *node) {
|
||||
if(!node->has_children) {
|
||||
node->c_x = x[node->particle];
|
||||
} else {
|
||||
node->c_x = 0;
|
||||
double m_tot = 0;
|
||||
for(int i = 0; i < 4; i++) {
|
||||
if(node->children[i].has_particle) {
|
||||
node->c_x += node->children[i].total_mass*calculate_center_of_mass_x(&node->children[i]);
|
||||
m_tot += node->children[i].total_mass;
|
||||
}
|
||||
}
|
||||
node->c_x /= m_tot;
|
||||
}
|
||||
return node->c_x;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculates the y-position of the centre of mass for the
|
||||
* node. It recursively updates the position of itself and
|
||||
* all of its children.
|
||||
*/
|
||||
double calculate_center_of_mass_y(struct node_t __capability *node) {
|
||||
if(!node->has_children) {
|
||||
node->c_y = y[node->particle];
|
||||
} else {
|
||||
node->c_y = 0;
|
||||
double m_tot = 0;
|
||||
for(int i = 0; i < 4; i++) {
|
||||
if(node->children[i].has_particle) {
|
||||
node->c_y += node->children[i].total_mass*calculate_center_of_mass_y(&node->children[i]);
|
||||
m_tot += node->children[i].total_mass;
|
||||
}
|
||||
}
|
||||
node->c_y /= m_tot;
|
||||
}
|
||||
return node->c_y;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculates the forces in a time step of all particles in
|
||||
* the simulation using the Barnes Hut quad tree.
|
||||
*/
|
||||
void update_forces(){
|
||||
for(int i = 0; i < N; i++) {
|
||||
force_x[i] = 0;
|
||||
force_y[i] = 0;
|
||||
update_forces_help(i, root);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Help function for calculating the forces recursively
|
||||
* using the Barnes Hut quad tree.
|
||||
*/
|
||||
void update_forces_help(int particle, struct node_t __capability *node) {
|
||||
//The node is a leaf node with a particle and not the particle itself
|
||||
if(!node->has_children && node->has_particle && node->particle != particle) {
|
||||
double r = my_sqrt((x[particle] - node->c_x)*(x[particle] - node->c_x) + (y[particle] - node->c_y)*(y[particle] - node->c_y));
|
||||
calculate_force(particle, node, r);
|
||||
}
|
||||
//The node has children
|
||||
else if(node->has_children) {
|
||||
//Calculate r and theta
|
||||
double r = my_sqrt((x[particle] - node->c_x)*(x[particle] - node->c_x) + (y[particle] - node->c_y)*(y[particle] - node->c_y));
|
||||
double theta = (node->max_x - node->min_x)/r;
|
||||
|
||||
/* If the distance to the node's centre of mass is far enough, calculate the force,
|
||||
* otherwise traverse further down the tree
|
||||
*/
|
||||
if(theta < 0.5){
|
||||
calculate_force(particle, node, r);
|
||||
} else {
|
||||
update_forces_help(particle, &node->children[0]);
|
||||
update_forces_help(particle, &node->children[1]);
|
||||
update_forces_help(particle, &node->children[2]);
|
||||
update_forces_help(particle, &node->children[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculates and updates the force of a particle from a node.
|
||||
*/
|
||||
void calculate_force(int particle, struct node_t __capability *node, double r){
|
||||
double temp = -grav*mass[particle]*node->total_mass/((r + epsilon)*(r + epsilon)*(r + epsilon));
|
||||
force_x[particle] += (x[particle] - node->c_x)*temp;
|
||||
force_y[particle] += (y[particle] - node->c_y)*temp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Main function.
|
||||
*/
|
||||
int main(void) {
|
||||
|
||||
//The first arguments sets if the graphics should be used
|
||||
// int graphics = 1;
|
||||
// if (argc > 1) {
|
||||
// graphics = atoi(argv[1]);
|
||||
// }
|
||||
|
||||
//The second argument sets the number of time steps
|
||||
// int time_steps = 1;
|
||||
// if (argc > 2) {
|
||||
// time_steps = atoi(argv[2]);
|
||||
// }
|
||||
|
||||
//Initiate memory for the vectors
|
||||
// x = (double __capability *)malloc(N*sizeof(double));
|
||||
// y = (double __capability *)malloc(N*sizeof(double));
|
||||
// u = (double __capability *)malloc(N*sizeof(double));
|
||||
// v = (double __capability *)malloc(N*sizeof(double));
|
||||
// // -------- Modified by Akilan ----------
|
||||
// force_x = (double __capability *)malloc(N*sizeof(double));
|
||||
// force_y = (double __capability *)malloc(N*sizeof(double));
|
||||
// // --------------------------------------
|
||||
// mass = (double __capability *)malloc(N*sizeof(double));
|
||||
|
||||
//Set the initial values
|
||||
// for(int i = 0; i < N; i++) {
|
||||
// mass[i] = 1;
|
||||
// double R = frand(0, L/4);
|
||||
// double theta = frand(0, 2*M_PI);
|
||||
// x[i] = L/2 + R*my_cos(theta);
|
||||
// y[i] = W/2 + alpha*R*my_sin(theta);
|
||||
// double R_prim = my_sqrt(pow(x[i] - L/2, 2) + pow(y[i] - W/2, 2));
|
||||
// u[i] = -V*R_prim*my_sin(theta);
|
||||
// v[i] = V*R_prim*my_cos(theta);
|
||||
// }
|
||||
// for (int i = 0; i < N; i++) {
|
||||
// mass[i] = 1;
|
||||
|
||||
// double R = frand(0, L/4);
|
||||
// double theta = frand(0, 2*PI);
|
||||
|
||||
// double c = my_cos(theta);
|
||||
// double s = my_sin(theta);
|
||||
|
||||
// x[i] = L/2 + R * c;
|
||||
// y[i] = W/2 + alpha * R * s;
|
||||
|
||||
// double dx = x[i] - L/2;
|
||||
// double dy = y[i] - W/2;
|
||||
|
||||
// double R_prim = my_sqrt(dx*dx + dy*dy);
|
||||
|
||||
// u[i] = -V * R_prim * s;
|
||||
// v[i] = V * R_prim * c;
|
||||
// }
|
||||
|
||||
/* Run the GLUT display function if the graphics mode is on.
|
||||
* Otherwise just run the simulations without graphics
|
||||
*/
|
||||
// if (graphics) {
|
||||
// // Initialize the graphics routines
|
||||
// graphicsInit(&argc, argv, display);
|
||||
|
||||
// //Used for the display window
|
||||
// glutMainLoop();
|
||||
// } else {
|
||||
//Begin taking time
|
||||
// long start = clock();
|
||||
|
||||
//The main loop
|
||||
// for(int i = 0; i < time_steps; i++) {
|
||||
// time_step();
|
||||
// }
|
||||
|
||||
//Stop taking time and print elapsed time
|
||||
// long stop = clock();
|
||||
// print_time(start, stop);
|
||||
// }
|
||||
|
||||
//Free memory
|
||||
// free(x);
|
||||
// free(y);
|
||||
// free(u);
|
||||
// free(v);
|
||||
// free(force_x);
|
||||
// free(force_y);
|
||||
// free(mass);
|
||||
|
||||
return 0;
|
||||
}
|
||||
92
Tests/isa/CPrograms/Benchmarks/barnes/barnes_hut.h
Normal file
92
Tests/isa/CPrograms/Benchmarks/barnes/barnes_hut.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* File: barnes_hut.h
|
||||
* --------------
|
||||
* Header file for barnes_hut.c
|
||||
* Written by:
|
||||
* Joel Backsell, Kim Torberntsson & Alexander Bilock.
|
||||
*/
|
||||
|
||||
#ifndef Barnes_Hut_barnes_hut_h
|
||||
#define Barnes_Hut_barnes_hut_h
|
||||
|
||||
/*
|
||||
* Struct that represents a node of the Barnes Hut quad tree.
|
||||
*/
|
||||
struct node_t {
|
||||
int particle;
|
||||
int has_particle;
|
||||
int has_children;
|
||||
double min_x, max_x, min_y, max_y, total_mass, c_x, c_y;
|
||||
|
||||
struct node_t __capability *children;
|
||||
};
|
||||
|
||||
//Function for producing a random number between two double values.
|
||||
double frand(double xmin, double xmax);
|
||||
|
||||
//Prints the time between two clocks in seconds
|
||||
// void print_time(clock_t s, clock_t e);
|
||||
|
||||
//OpenGL method for displaying the particles
|
||||
// void display(void);
|
||||
|
||||
//Calculates the positions of a time step
|
||||
// void time_step(void);
|
||||
|
||||
//If a particle moves beyond any of the boundaries then bounce it back
|
||||
// void bounce(double *x, double *y, double *u, double *v);
|
||||
|
||||
// //Functions for handling the placement of particles in the tree
|
||||
// void put_particle_in_tree(int new_particle, struct node_t *node);
|
||||
// void place_particle(int particle, struct node_t *node);
|
||||
// void set_node(struct node_t *node);
|
||||
// void free_node(struct node_t *node);
|
||||
// void display_tree(struct node_t *node);
|
||||
|
||||
// //Functions for calculating the mass and centre of mass of the tree
|
||||
// double calculate_mass(struct node_t *node);
|
||||
// double calculate_center_of_mass_x(struct node_t *node);
|
||||
// double calculate_center_of_mass_y(struct node_t *node);
|
||||
|
||||
// //Functions for the force calculations
|
||||
// void update_forces();
|
||||
// void update_forces_help(int particle, struct node_t *node);
|
||||
// void calculate_force(int particle, struct node_t *node, double r);
|
||||
|
||||
void bounce(double __capability *x,
|
||||
double __capability *y,
|
||||
double __capability *u,
|
||||
double __capability *v);
|
||||
|
||||
/* Tree functions */
|
||||
void put_particle_in_tree(int new_particle,
|
||||
struct node_t __capability *node);
|
||||
|
||||
void place_particle(int particle,
|
||||
struct node_t __capability *node);
|
||||
|
||||
void set_node(struct node_t __capability *node);
|
||||
|
||||
void free_node(struct node_t __capability *node);
|
||||
|
||||
void display_tree(struct node_t __capability *node);
|
||||
|
||||
/* Mass / COM */
|
||||
double calculate_mass(struct node_t __capability *node);
|
||||
|
||||
double calculate_center_of_mass_x(struct node_t __capability *node);
|
||||
|
||||
double calculate_center_of_mass_y(struct node_t __capability *node);
|
||||
|
||||
/* Forces */
|
||||
void update_forces(void);
|
||||
|
||||
void update_forces_help(int particle,
|
||||
struct node_t __capability *node);
|
||||
|
||||
void calculate_force(int particle,
|
||||
struct node_t __capability *node,
|
||||
double r);
|
||||
|
||||
|
||||
#endif
|
||||
17
Tests/isa/CPrograms/Benchmarks/barnes/build.sh
Normal file
17
Tests/isa/CPrograms/Benchmarks/barnes/build.sh
Normal file
@@ -0,0 +1,17 @@
|
||||
scp ../../start.S home-1:/home/akilan/cheri/output/sdk/bin/
|
||||
# scp main.c home-1:/home/akilan/cheri/output/sdk/bin/
|
||||
scp ../../malloc.c home-1:/home/akilan/cheri/output/sdk/bin/
|
||||
scp ../../malloc_test.c home-1:/home/akilan/cheri/output/sdk/bin/
|
||||
scp ../../link.ld home-1:/home/akilan/cheri/output/sdk/bin/
|
||||
|
||||
scp barnes.c home-1:/home/akilan/cheri/output/sdk/bin/
|
||||
scp barnes_hut.h home-1:/home/akilan/cheri/output/sdk/bin/
|
||||
|
||||
# ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./clang --target=riscv64-unknown-elf -march=rv64gcxcheri -mabi=lp64d -nostdlib -nostartfiles -fno-builtin-malloc -mcmodel=medany -Wl,-Ttext=0x80000000 -o testC start.S malloc.c memaccess.c'
|
||||
ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./clang --target=riscv64-unknown-elf -march=rv64gcxcheri -mabi=lp64d -DDEFINE_MALLOC -DDEFINE_FREE -nostdlib -nostartfiles -fno-builtin-malloc -mcmodel=medany -T link.ld -o testC start.S barnes.c malloc.c malloc_test.c'
|
||||
|
||||
# ssh home-1 'cd /home/akilan/cheri/output/sdk/bin/ && ./llvm-objdump -d testC'
|
||||
|
||||
scp home-1:/home/akilan/cheri/output/sdk/bin/testC ../../../
|
||||
|
||||
|
||||
@@ -15,5 +15,8 @@ SECTIONS
|
||||
_end = .;
|
||||
|
||||
__malloc_start = .;
|
||||
. = . + 512;
|
||||
. = . + 0x100000;
|
||||
|
||||
/* End of uninitalized data segement */
|
||||
_end = .;
|
||||
}
|
||||
@@ -53,11 +53,13 @@ static inline void * __capability add_delta(void * __capability cap, int offset)
|
||||
// Malloc wrapper
|
||||
void * __capability malloc(size_t size) {
|
||||
|
||||
void *raw = tiny_malloc(size);
|
||||
uintptr_t raw = (uintptr_t)tiny_malloc(size);
|
||||
|
||||
void *__capability cap = (void *__capability)raw;
|
||||
// void *__capability cap = (void *__capability)raw;
|
||||
void *__capability cap = cheri_ddc_get();
|
||||
|
||||
cap = cheri_bounds_set(cap, size);
|
||||
// // Set address from raw pointer
|
||||
cap = cheri_address_set(cap, raw);
|
||||
|
||||
int delta = 12;
|
||||
|
||||
@@ -65,6 +67,10 @@ void * __capability malloc(size_t size) {
|
||||
|
||||
cap = add_delta(cap, delta);
|
||||
|
||||
size_t aligned = cheri_representable_length(size);
|
||||
|
||||
cap = cheri_bounds_set(cap, aligned);
|
||||
|
||||
// // Align to 8 bytes (important for capability safety)
|
||||
// size = (size + 7) & ~7;
|
||||
|
||||
|
||||
BIN
Tests/isa/testC
BIN
Tests/isa/testC
Binary file not shown.
5795
builds/RV64ACDFIMSUxCHERI_Toooba_bluesim/test
Normal file
5795
builds/RV64ACDFIMSUxCHERI_Toooba_bluesim/test
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user