/* * 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 #include #include #include #include "tests.h" #ifdef START_KERNEL_LAPLACE #include #include #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