add Laplace example and GFX code

This commit is contained in:
Stefan Lankes 2011-10-20 23:23:16 -07:00
parent c74ee965ca
commit ca1abe00f6
6 changed files with 707 additions and 1 deletions

View file

@ -1,4 +1,4 @@
C_source := tests.c echo.c netio.c
C_source := tests.c echo.c netio.c laplace.c gfx_client.c gfx_generic.c
MODULE := apps
include $(TOPDIR)/Makefile.inc

146
apps/gfx_client.c Normal file
View file

@ -0,0 +1,146 @@
/*
* Copyright 2011 Sarah Fischer, Nicolas Berr, Pablo Reble
* 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>
#ifdef CONFIG_LWIP
#include "gfx_client.h"
#include <lwip/sockets.h>
static int myrank;
static int sockfd;
#ifndef SINGLE_CONNECT
#define SINGLE_CONNECT 1
#endif
#define SINGLE_CONNECT_RANK 0
#define USE_GETHOSTBYNAME 0
//int gfx_init(int* pargc, char*** pargv, int rank){
int gfx_init(char* ip_str, char* port_str, int rank) {
char* hostname;
int port;
struct sockaddr_in serveraddr;
struct hostent *server;
//*pargc -=2;
myrank = rank;
#if SINGLE_CONNECT
// currently only rank 0 will connect to the gfx-server
if (rank != SINGLE_CONNECT_RANK) {
return 0;
}
#endif
/* hostname und port aus den parametern ermitteln) */
//kprintf("pargc: %d\n", *pargc);
hostname = ip_str; //(*pargv)[(*pargc)];
port = atoi(port_str); //atoi((*pargv)[(*pargc)+1]);
kprintf("gfx-client connecting to host: %s, port: %d\n", hostname, port);
/* socket erzeugen */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
return -1;
#if 1
/* Disable the Nagle (TCP No Delay) algorithm */
int flag = 1;
if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(flag)) < 0) {
kprintf("Couldn't setsockopt(TCP_NODELAY)\n");
return -1;
}
#endif
#if USE_GETHOSTBYNAME
/* dns eintrag vom server ermitteln */
serveraddr = gethostbyname(hostname);
if (server == NULL){
fprintf(stderr, "%s: no such host\n", hostname);
return -2;
}
#endif
/* adresse vom server ermitteln */
memset((char *) &serveraddr, 0x00, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
#if USE_GETHOSTBYNAME
bcopy((char *)server->h_addr, (char *)&serveraddr.sin_addr.s_addr, server->h_length);
#else
serveraddr.sin_addr.s_addr = inet_addr(hostname);
#endif
serveraddr.sin_port = htons(port);
/* verbindung herstellen */
if (connect(sockfd, (const struct sockaddr *) &serveraddr, sizeof(serveraddr)) < 0)
return -3;
return 0;
}
int gfx_send(char* buf, int size, int tag){
int ret, pos = 0;
uint32_t u32size, u32tag;
#if SINGLE_CONNECT
if (myrank != SINGLE_CONNECT_RANK)
return 0;
#endif
u32size = size;
u32tag = tag;
// printf("sending stuff....");
// printf("tag: %d, size: %d\n", tag, size);
// fflush(stdout);
ret = write(sockfd, &u32tag, sizeof(u32tag));
if (ret != sizeof(tag))
return -1;
ret = write(sockfd, &u32size, sizeof(u32size));
if (ret != sizeof(size))
return -2;
do{
ret = write(sockfd, &buf[pos], size-pos);
pos += ret;
} while (pos < size);
return 0;
}
int gfx_finalize(){
// uint32_t u32tag = (uint32_t)(-1);
uint32_t u32tag = 1111;
#if SINGLE_CONNECT
if (myrank == SINGLE_CONNECT_RANK) {
write(sockfd, &u32tag, sizeof(u32tag));
close(sockfd);
}
#endif
return 0;
}
#endif

50
apps/gfx_client.h Normal file
View file

@ -0,0 +1,50 @@
/*
* Copyright 2011 Sarah Fischer, Nicolas Berr, Pablo Reble
* 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.
*/
#ifndef __GFX_CLIENT_H__
#define __GFX_CLIENT_H__
#include <metalsvm/stdio.h>
#include <metalsvm/stdlib.h>
#include <metalsvm/string.h>
#ifdef CONFIG_LWIP
#define BUFSIZE 1024
/*
* grafik initialisieren, letzte beide argumente, ip und port, werden entfernt
* verbindung zu server aufbauen, kollektiver aufruf, erstmal nur rank 0 connecten
*/
//int gfx_init(int* pargc, char*** pargv, int rank);
int gfx_init(char* ip_str, char* port_str, int rank);
/*
* paket mit der geg. laenge wird an den server gesehendet, das tag soll auch uebertragen werden
*/
int gfx_send(char* buf, int size, int tag);
/*
* kollektiver aufruf, vorhandene verbindungen kontrolliert beenden
*/
int gfx_finalize();
#endif
#endif

138
apps/gfx_generic.c Normal file
View file

@ -0,0 +1,138 @@
/*
* Copyright 2011 Sarah Fischer, Nicolas Berr, Pablo Reble
* 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 "gfx_client.h"
#include "gfx_generic.h"
#ifdef CONFIG_LWIP
int GFX_init(int* pargc, char*** pargv, int rank)
{
return gfx_init(pargc, pargv, rank);
}
int GFX_send(char* buf, int size, int tag)
{
return gfx_send(buf, size, tag);
}
int GFX_finalize()
{
return gfx_finalize();
}
int GFX_update()
{
return gfx_send(NULL, 0, GFX_UPDATE);
}
int GFX_usleep(int sleep_time)
{
int buf[1];
buf[0] = sleep_time;
return gfx_send((char*)buf, sizeof(int), GFX_USLEEP);
}
int GFX_set_rgb(int index, int r, int g, int b)
{
int buf[4];
buf[0] = index;
buf[1] = r;
buf[2] = g;
buf[3] = b;
return gfx_send((char*)buf, 4*sizeof(int), GFX_SET_RGB);
}
int GFX_set_xy(int x, int y)
{
int buf[2];
buf[0] = x;
buf[1] = y;
return gfx_send((char*)buf, 2*sizeof(int), GFX_SET_XY);
}
int GFX_set_hd(int height, int direction)
{
int buf[2];
buf[0] = height;
buf[1] = direction;
return gfx_send((char*)buf, 2*sizeof(int), GFX_SET_HD);
}
int GFX_draw_data(char *buf, int len)
{
return gfx_send(buf, len, GFX_DRAW_DATA);
}
int GFX_draw_pixel(int x, int y, int color)
{
int buf[3];
buf[0] = x;
buf[1] = y;
buf[2] = color;
return gfx_send((char*)buf, 3*sizeof(int), GFX_DRAW_PIXEL);
}
int GFX_draw_line(int x1, int y1, int x2, int y2, int color)
{
int buf[5];
buf[0] = x1;
buf[1] = y1;
buf[2] = x2;
buf[3] = y2;
buf[4] = color;
return gfx_send((char*)buf, 5*sizeof(int), GFX_DRAW_LINE);
}
int GFX_draw_box(int x, int y, int height, int width, int color)
{
int buf[5];
buf[0] = x;
buf[1] = y;
buf[2] = height;
buf[3] = width;
buf[4] = color;
return gfx_send((char*)buf, 5*sizeof(int), GFX_DRAW_BOX);
}
int GFX_draw_text(int x, int y, int color, char *text)
{
int buf[32];
buf[0] = x;
buf[1] = y;
buf[2] = color;
strcpy((char*)&(buf[3]), text);
return gfx_send((char*)buf, 32*sizeof(int), GFX_DRAW_TEXT);
}
int GFX_draw_points(int* points, int num)
{
return gfx_send((char*)points, num*3*sizeof(int), GFX_DRAW_POINTS);
}
int GFX_draw_poly(int* points, int num, int color)
{
int i;
for(i=0; i<num; i++) points[i*3+2] = color;
return gfx_send((char*)points, num*3*sizeof(int), GFX_DRAW_POLY);
}
#endif

84
apps/gfx_generic.h Normal file
View file

@ -0,0 +1,84 @@
/*
* Copyright 2011 Sarah Fischer, Nicolas Berr, Pablo Reble
* 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.
*/
#ifndef _GFX_GENERIC_H_
#define _GFX_GENERIC_H_
#include "gfx_client.h"
#ifdef CONFIG_LWIP
int GFX_init(int* pargc, char*** pargv, int rank);
int GFX_send(char* buf, int size, int tag);
int GFX_finalize();
int GFX_update();
int GFX_set_rgb(int index, int r, int g, int b);
int GFX_set_xy(int x, int y);
int GFX_set_hd(int height, int direction);
int GFX_draw_data(char *buf, int len);
int GFX_draw_pixel(int x, int y, int color);
int GFX_draw_line(int x1, int y1, int x2, int y2, int color);
int GFX_draw_box(int x, int y, int height, int width, int color);
int GFX_draw_text(int x, int y, int color, char *text);
int GFX_draw_points(int* points, int num);
int GFX_draw_poly(int *points, int num, int color);
typedef enum _GFX_colors
{
GFX_WHITE = -1,
GFX_BLACK = -2,
GFX_RED = -3,
GFX_DRED = -4,
GFX_GREEN = -5,
GFX_DGREEN = -6,
GFX_BLUE = -7,
GFX_DBLUE = -8,
GFX_CYAN = -9,
GFX_DCYAN = -10,
GFX_MAGENTA = -11,
GFX_DMAGENTA = -12,
GFX_YELLOW = -13,
GFX_DYELLOW = -14,
GFX_GRAY = -15,
GFX_DGRAY = -16
} GFX_colors;
typedef enum GFX_commands
{
GFX_UPDATE = 0,
GFX_USLEEP = 1,
GFX_SET_RGB = 2,
GFX_SET_XY = 3,
GFX_SET_HD = 4,
GFX_DRAW_DATA = 5,
GFX_DRAW_PIXEL = 6,
GFX_DRAW_POINTS = 7,
GFX_DRAW_LINE = 8,
GFX_DRAW_BOX = 9,
GFX_DRAW_POLY = 10,
GFX_DRAW_TEXT = 11
} GFX_commands;
#endif
#endif

288
apps/laplace.c Normal file
View file

@ -0,0 +1,288 @@
/*
* 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>
#ifdef CONFIG_ROCKCREEK
#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 512
#define M 512
#define TMAX 100*50
//#define DATA unsigned int
#define DATA double
//#define FIX 1024
#define FIX 1
#define USE_SVM 0
#define MEMTYPE SVM_STRONG
//#define MEMTYPE 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;
uint32_t flags;
#ifdef _USE_GFX
uint32_t ret;
#endif
int t;
int i, I, j, J;
int my_rank;
int num_ranks;
int n;
int m;
volatile DATA **NewValues;
volatile DATA **OldValues;
volatile DATA **tmp;
volatile char **BufValues;
uint64_t start, end;
flags = irq_nested_disable();
my_rank = RCCE_ue();
num_ranks = RCCE_num_ues();
irq_nested_enable(flags);
#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;
if (my_rank == num_ranks - 1)
n += N % num_ranks;
I = n * my_rank;
kprintf("(%d) %d x %d / offsets: %d, %d / (%d x %d)\n", my_rank, 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 *));
#if USE_SVM
NewValues[0] = (DATA *) svmmalloc((N + 2) * (M + 2) * sizeof(DATA), MEMTYPE);
#else
NewValues[0] = (DATA *) kmalloc((N + 2) * (M + 2) * sizeof(DATA));
#endif
OldValues = (volatile DATA **)kmalloc((N + 2) * sizeof(DATA *));
#if USE_SVM
OldValues[0] = (DATA *) svmmalloc((N + 2) * (M + 2) * sizeof(DATA), MEMTYPE);
#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 = (volatile 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);
}
RCCE_barrier(&RCCE_COMM_WORLD);
kprintf("(%d) Memory allocated!\n", my_rank);
//while (1)
{
int height = N + 2;
int width = M + 2;
if (my_rank == 0) {
for (i = 0; i < N + 2; i++) {
for (j = 0; j < M + 2; j++) {
double X = (((double)j / (double)width) * 5.0) - 2.5;
double Y = (((double)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;
NewValues[i][j] = (DATA) ((Z) * 255.0) * FIX;
//if(NewValues[i][j] < 0) NewValues[i][j] = 0;
}
}
for (i = 0; i < N + 2; i++) {
for (j = 0; j < M + 2; j++) {
OldValues[i][j] = NewValues[i][j];
}
}
}
svm_flush();
svm_invalidate();
RCCE_barrier(&RCCE_COMM_WORLD);
kprintf("(%d) Arrays initialized!\n", my_rank);
start = rdtsc();
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]) );
// over all collumns
for (i = 1; i < n + 1; i++) {
// over all rows
for (j = 1; j < m + 1; j++) {
#if 1
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;
//if ( NewValues[I+i][J+j] < 0.0 ) NewValues[I+i][J+j] = 0.0 * FIX;
//else if ( NewValues[I+i][J+j] > 255.0 ) NewValues[I+i][J+j] = 255.0 * FIX;
#else
NewValues[I + i][J + j] = 25 * (DATA) (my_rank + 1);
#endif
}
}
svm_flush();
svm_invalidate();
tmp = NewValues;
NewValues = OldValues;
OldValues = tmp;
RCCE_barrier(&RCCE_COMM_WORLD);
#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();
}
#endif
// END ITERATIONS LOOP
}
RCCE_barrier(&RCCE_COMM_WORLD);
end = rdtsc();
kprintf("Calculation time: %llu ms (%llu ticks)\n", (end-start)/(1000ULL*get_cpu_frequency()), end-start);
svm_statistics();
}
kprintf("(%d) Algorithm completed!\n", my_rank);
// TODO: Freeing memory regions
#ifdef _USE_GFX
gfx_finalize();
#endif
return 0;
}
#endif