310 lines
6.7 KiB
C
310 lines
6.7 KiB
C
/*
|
|
* Copyright 2010 Carsten Clauss, Pablo Reble, Stefan Lankes
|
|
* Chair for Operating Systems, RWTH Aachen University
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
* This file is part of MetalSVM.
|
|
*/
|
|
|
|
#include <metalsvm/stdlib.h>
|
|
#include <metalsvm/stdio.h>
|
|
#include <asm/irqflags.h>
|
|
#include <asm/svm.h>
|
|
|
|
#include "tests.h"
|
|
|
|
#ifdef START_KERNEL_LAPLACE
|
|
|
|
#include <asm/RCCE.h>
|
|
#include <asm/iRCCE.h>
|
|
|
|
#define _LAPLACE_SHMEM_
|
|
//#define _USE_GFX
|
|
|
|
#ifdef _LAPLACE_SHMEM_
|
|
#define SINGLE_CONNECT 1
|
|
#else
|
|
#define SINGLE_CONNECT 0
|
|
#endif
|
|
|
|
#ifdef _USE_GFX
|
|
#include "gfx_generic.h"
|
|
#include "gfx_client.h"
|
|
#endif
|
|
|
|
#define ABS(a) (((a) < 0) ? -(a) : (a))
|
|
#define MAX(a,b) (((a) < (b)) ? (b) : (a))
|
|
|
|
#define N 1022
|
|
#define M 510
|
|
|
|
#define TMAX (100*50)
|
|
|
|
//#define DATA volatile unsigned int
|
|
#define DATA volatile double
|
|
|
|
//#define FIX 1024
|
|
#define FIX 1
|
|
|
|
#define SVM_TYPE SVM_STRONG
|
|
//#define SVM_TYPE SVM_LAZYRELEASE
|
|
|
|
static inline double pow(double a, int b)
|
|
{
|
|
double base = a;
|
|
int i;
|
|
|
|
for (i = 1; i < b; ++i)
|
|
a *= base;
|
|
|
|
return a;
|
|
}
|
|
|
|
int laplace(void *arg)
|
|
{
|
|
//char* argv[] = {"/bin/laplace", "192.168.4.254", "12301", NULL};
|
|
//int argc = 3;
|
|
#ifdef _USE_GFX
|
|
uint32_t ret;
|
|
#endif
|
|
int t;
|
|
|
|
int i, I, j, J;
|
|
int my_rank;
|
|
int num_ranks;
|
|
|
|
int n;
|
|
int m;
|
|
|
|
DATA **NewValues;
|
|
DATA **OldValues;
|
|
|
|
DATA **tmp;
|
|
|
|
char **BufValues;
|
|
|
|
uint64_t start, end;
|
|
|
|
my_rank = RCCE_IAM;
|
|
num_ranks = RCCE_NP;
|
|
|
|
#ifdef _USE_GFX
|
|
kprintf("Laplace calls gfx_init\n");
|
|
ret = GFX_init("192.168.4.254" /*&argc */ , "5000" /*&argv */ , my_rank);
|
|
kprintf("gfx_init: %d\n", ret);
|
|
#endif
|
|
|
|
m = M;
|
|
J = 0;
|
|
|
|
n = N / num_ranks;
|
|
I = n * my_rank;
|
|
|
|
if (my_rank == num_ranks - 1)
|
|
n += N % num_ranks;
|
|
|
|
kprintf("(%d of %d) %d x %d / offsets: %d, %d / (%d x %d)\n", my_rank, num_ranks, N, M, I, J, n, m);
|
|
|
|
#ifdef _USE_GFX
|
|
if (my_rank == 0) {
|
|
for (i = 0; i < 256; i++) {
|
|
//set color index, r, g, b
|
|
if (i < 64)
|
|
GFX_set_rgb(i, 0, i * 256 / 64, 255);
|
|
else if (i < 128)
|
|
GFX_set_rgb(i, 0, 255, 255 - ((i - 64) * 256 / 64));
|
|
else if (i < 192)
|
|
GFX_set_rgb(i, (i - 128) * 256 / 64, 255, 0);
|
|
else if (i < 256)
|
|
GFX_set_rgb(i, 255, 255 - ((i - 192) * 256 / 64), 0);
|
|
}
|
|
// TODO: move draw area to center
|
|
//GFX_set_xy(150, 150);
|
|
GFX_set_hd(N, 0);
|
|
}
|
|
#endif
|
|
|
|
NewValues = (volatile DATA **)kmalloc((N + 2) * sizeof(DATA *));
|
|
#ifdef SVM_TYPE
|
|
NewValues[0] = (DATA *) svm_malloc((N + 2) * (M + 2) * sizeof(DATA), SVM_TYPE);
|
|
#else
|
|
NewValues[0] = (DATA *) kmalloc((N + 2) * (M + 2) * sizeof(DATA));
|
|
#endif
|
|
|
|
OldValues = (volatile DATA **)kmalloc((N + 2) * sizeof(DATA *));
|
|
#ifdef SVM_TYPE
|
|
OldValues[0] = (DATA *) svm_malloc((N + 2) * (M + 2) * sizeof(DATA), SVM_TYPE);
|
|
#else
|
|
OldValues[0] = (DATA *) kmalloc((N + 2) * (M + 2) * sizeof(DATA));
|
|
#endif
|
|
|
|
for (i = 1; i < N + 2; i++) {
|
|
NewValues[i] = NewValues[i - 1] + (M + 2);
|
|
OldValues[i] = OldValues[i - 1] + (M + 2);
|
|
}
|
|
|
|
BufValues = (char **)kmalloc((N) * sizeof(char *));
|
|
BufValues[0] = (char *)kmalloc((N) * (M) * sizeof(char));
|
|
|
|
for (i = 1; i < N; i++) {
|
|
BufValues[i] = BufValues[i - 1] + (M);
|
|
}
|
|
|
|
#ifdef SVM_TYPE
|
|
svm_barrier(SVM_TYPE);
|
|
#endif
|
|
|
|
kprintf("(%d) Memory allocated!\n", my_rank);
|
|
|
|
//while (1)
|
|
{
|
|
int height = N + 2;
|
|
int width = M + 2;
|
|
|
|
if (my_rank == 0) {
|
|
for (j = 0; j < m + 2; j++) {
|
|
double X = (((double)(J+j) / (double)width) * 5.0) - 2.5;
|
|
double Y = 0.0;
|
|
double Z = 0.0;
|
|
|
|
Z = pow((4 - (X + 1) * (X + 1) - 4 * Y * Y), 2) + pow(1.2 * (1 - X), 3) - 10;
|
|
if (Z < 0.0)
|
|
Z = 1.0;
|
|
else if (Z > 0.0)
|
|
Z = 0.0;
|
|
|
|
OldValues[0][J+j] = NewValues[0][J+j] = (DATA) ((Z) * 255.0) * FIX;
|
|
}
|
|
}
|
|
|
|
for (i = 1; i < n+1; i++) {
|
|
for (j = 0; j < m + 2; j++) {
|
|
double X = (((double)(J+j) / (double)width) * 5.0) - 2.5;
|
|
double Y = (((double)(I+i) / (double)height) * 5.0) - 2.5;
|
|
double Z = 0.0;
|
|
|
|
Z = pow((4 - (X + 1) * (X + 1) - 4 * Y * Y), 2) + pow(1.2 * (1 - X), 3) - 10;
|
|
if (Z < 0.0)
|
|
Z = 1.0;
|
|
else if (Z > 0.0)
|
|
Z = 0.0;
|
|
|
|
OldValues[I+i][J+j] = NewValues[I+i][J+j] = (DATA) ((Z) * 255.0) * FIX;
|
|
}
|
|
}
|
|
|
|
if (my_rank == num_ranks - 1) {
|
|
for (j = 0; j < m + 2; j++) {
|
|
double X = (((double)(J+j) / (double)width) * 5.0) - 2.5;
|
|
double Y = (((double)(I+n+1) / (double)height) * 5.0) - 2.5;
|
|
double Z = 0.0;
|
|
|
|
Z = pow((4 - (X + 1) * (X + 1) - 4 * Y * Y), 2) + pow(1.2 * (1 - X), 3) - 10;
|
|
if (Z < 0.0)
|
|
Z = 1.0;
|
|
else if (Z > 0.0)
|
|
Z = 0.0;
|
|
|
|
OldValues[I+n+1][J+j] = NewValues[I+n+1][J+j] = (DATA) ((Z) * 255.0) * FIX;
|
|
}
|
|
}
|
|
|
|
#ifdef SVM_TYPE
|
|
svm_barrier(SVM_TYPE);
|
|
#endif
|
|
|
|
kprintf("(%d) Arrays initialized!\n", my_rank);
|
|
|
|
start = rdtsc();
|
|
|
|
// START ITERATIONS LOOP
|
|
for (t = 0; t < TMAX; t++) {
|
|
|
|
//kprintf("(%d): o:%u n:%u \n",my_rank,(unsigned int)(OldValues[I+1][J+1]), (unsigned int)(NewValues[I+1][J+1]) );
|
|
//kprintf("(%d): t: %u\n", my_rank, t);
|
|
|
|
// over all collumns
|
|
for (i = 1; i < n + 1; i++) {
|
|
// over all rows
|
|
for (j = 1; j < m + 1; j++) {
|
|
NewValues[I + i][J + j] =
|
|
(OldValues[I + i - 1][J + j] +
|
|
OldValues[I + i + 1][J + j] +
|
|
OldValues[I + i][J + j - 1] +
|
|
OldValues[I + i][J + j + 1]) / 4;
|
|
}
|
|
}
|
|
|
|
tmp = NewValues;
|
|
NewValues = OldValues;
|
|
OldValues = tmp;
|
|
|
|
#ifdef SVM_TYPE
|
|
svm_barrier(SVM_TYPE);
|
|
#endif
|
|
|
|
#ifdef _USE_GFX
|
|
if ((my_rank == 0) && (t % 50 == 0)) {
|
|
int diff, res = 0;
|
|
|
|
for (i = 1; i < N + 1; i++) {
|
|
for (j = 1; j < M + 1; j++) {
|
|
|
|
diff = ABS(NewValues[i][j] - OldValues[i][j]);
|
|
if (diff > res)
|
|
res = diff;
|
|
|
|
BufValues[i - 1][j - 1] = (unsigned char)(NewValues[i][j] / FIX);
|
|
//GFX_draw_pixel(150+j, 150+my_rank*n+i, (unsigned char)NewValues[i+1][j+1]);
|
|
//GFX_update();
|
|
}
|
|
}
|
|
|
|
kprintf("Graphic UPDATE! (t=%d) residual:%u \n", t, res);
|
|
GFX_draw_data((char *)(BufValues[0]), (N) * (M));
|
|
GFX_update();
|
|
}
|
|
|
|
#ifdef SVM_TYPE
|
|
svm_barrier(SVM_TYPE);
|
|
#endif
|
|
#endif
|
|
// END ITERATIONS LOOP
|
|
}
|
|
|
|
#ifdef SVM_TYPE
|
|
svm_barrier(SVM_TYPE);
|
|
#endif
|
|
|
|
end = rdtsc();
|
|
|
|
kprintf("Calculation time: %llu ms (%llu ticks)\n", (end-start)/(1000ULL*get_cpu_frequency()), end-start);
|
|
|
|
#ifdef SVM_TYPE
|
|
svm_statistics();
|
|
#endif
|
|
}
|
|
|
|
kprintf("(%d) Algorithm completed!\n", my_rank);
|
|
|
|
// TODO: Freeing memory regions
|
|
|
|
#ifdef _USE_GFX
|
|
gfx_finalize();
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
#endif
|