Commit 707f25c9 authored by Björn Fischer's avatar Björn Fischer

changes

parent a8bc3e1e
File added
File added
File added
File added
This source diff could not be displayed because it is too large. You can view the blob instead.
# Heatmap
Das Programm verwendet zum Parallelisieren SPMD und Threads.
## Datendekomposition
Jeder Bildpunkt braucht seine Nachbarn zur iterativen Berechnung, also müssen die Strukturen bei dem "verteilten Speicher" Modell möglichst gut erhalten bleiben. Bei der threadparallelen Verarbeitung
## SPMD
Das Programm läuft mehrfach. Die Prozesse kommunizieren dabei über Nachrichten. Jede Instanz kann sich selbst eindeutig identifizieren. Dies kann genutzt werden und Datenmengen (gleichmäßig) zuzuordnen.
\ No newline at end of file
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void process_args(int argc, char **argv, int *m, int *n, double *eps, double *delta_t) {
if ((argc < 3) || (argc > 5)) {
fprintf(stderr, "Usage: heat <m> <n> [<epsilon> [delta_t]]!\n\n");
fprintf(stderr, " <m> -- X-Size of matrix\n");
fprintf(stderr, " <n> -- Y-Size of matrix\n");
fprintf(stderr, " <epsilon> -- accuracy parameter\n");
fprintf(stderr, " <delta_t> -- time step\n");
exit(1);
}
/*
** Erstes und zweites Argument: Größe der Matrix
*/
*m = atoi(argv[1]);
if ((*m < 3) || (*m > 6000)) {
fprintf(stderr, "Error: size m out of range [3 .. 6000] !\n");
exit(1);
}
*n = atoi(argv[2]);
if ((*n < 3) || (*n > 6000)) {
fprintf(stderr, "Error: size n out of range [3 .. 6000] !\n");
exit(1);
}
/*
** Drittes (optionales) Argument: "Genauigkeitsfaktor" eps
*/
if (argc >= 4) {
*eps = atof(argv[3]);
}
if ((*eps <= 0) || (*eps > 0.01)){
fprintf(stderr, "Error: epsilon must be between 0.0000000001 and 0.01 )\n");
exit(1);
}
/*
** Viertes (optionales) Argument: delta_t
*/
if (argc >= 5) {
*delta_t = atof(argv[4]);
}
if ((*delta_t <= 0) || (*delta_t > 1.0)){
fprintf(stderr, "Error: delta_t (%f) must be between 0.0000000001 and 1.0\n", *delta_t);
exit(1);
}
}
\ No newline at end of file
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <mpi.h>
#include <sys/time.h>
/* HILFSFUNKTIONEN ******************************************************* */
/*
** Allokiere ein 2D-Array mit m * n Elementen (m Zeilen mit n Spalten).
** Also so etwas wie ``new double[m][n]'' ...
*/
double ** New_Matrix(int m, int n)
{
double **res;
double *array;
int i;
/*
** Ergebnis ist ein 1D-Array mit Zeigern auf die Zeilen des 2D-Arrays
*/
res = (double **)malloc(sizeof(double *) * m);
if (res == NULL)
return NULL;
/*
** Das eigentliche Array wird aus Effizienzgr�nden in einem St�ck
** allokiert. Das entspricht dem Speicher-Layout, den es auch bei
** statischer Allokation h�tte.
*/
array = (double *)malloc(sizeof(double) * m * n);
if (array == NULL)
return NULL;
/*
** Jeder Zeilen-Zeiger wird nun mit dem richtigen Wert besetzt.
** (Zeile i beginnt bei Eintrag i*n)
*/
for (i = 0; i < m; i++) {
res[i] = &array[i * n];
}
return res;
}
/*
** Freigabe eines 2D-Arrays.
*/
void Delete_Matrix(double **matrix)
{
free(matrix[0]);
free(matrix);
}
/*
** Gibt die mxn-Matrix 'a' in die Datei 'Matrix.txt' aus.
*/
void Write_Matrix(double **a, int m, int n)
{
int i, j;
FILE *f;
/* Datei zum Schreiben �ffnen */
f = fopen("Matrix.txt", "w");
if (f == NULL) {
fprintf(stderr, "Cannot open file 'Matrix.txt' for writing!");
exit(1);
}
/* Gr��e der Matrix schreiben */
fprintf(f, "%d\n", m);
fprintf(f, "%d\n\n", n);
/* Matrix-Elemente zeilenweise in die Datei schreiben */
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
fprintf(f, "%.10lf\n", a[i][j]);
}
fprintf(f, "\n");
}
/* Datei schlie�en */
fclose(f);
}
/*
** Matrix initialisieren
*/
void Init_Matrix(double **a, int m, int n, int init_value) {
int i,j;
for (i=0; i<m; i++) {
for (j=0; j<n; j++) {
a[i][j] = init_value;
}
}
}
void Insert_Matrix(double **a, int a_dim0, int a_dim1, int pos_dim0, int pos_dim1, double **b, int b_dim0, int b_dim1, int offset_dim0_left, int offset_dim0_right, int offset_dim1_left, int offset_dim1_right) {
int i,j;
for(i=0; i < b_dim0 - offset_dim0_left - offset_dim0_right; i++) {
for(j=0; j < b_dim1 - offset_dim1_left - offset_dim1_right; j++) {
a[pos_dim0 + i][pos_dim0 + j] = b[offset_dim0_left + i][offset_dim1_right + j];
}
}
}
\ No newline at end of file
No preview for this file type
......@@ -4,72 +4,35 @@
#include <math.h>
#include <mpi.h>
#include <sys/time.h>
#include "project.h"
double eps = 0.001;
double delta_t = 0.000001;
double alpha = 1;
typedef struct {
int start_m; // first tile to process in X-axis
int start_n; // first tile to process in Y-axis
int end_m; // last tile to process in X-axis
int end_n; // last tile to process in Y-axis
} t_process_info;
int main(int argc, char **argv)
{
MPI_Init(&argc, &argv);
int i, j, m, n, err;
double **a;
int m, n;
double **partial_field;
double start, end;
t_process_info pi;
if ((argc < 3) || (argc > 5)) {
fprintf(stderr, "Usage: heat <m> <n> [<epsilon> [delta_t]]!\n\n");
fprintf(stderr, " <m> -- X-Size of matrix\n");
fprintf(stderr, " <n> -- Y-Size of matrix\n");
fprintf(stderr, " <epsilon> -- accuracy parameter\n");
fprintf(stderr, " <delta_t> -- time step\n");
exit(1);
}
process_args(argc, argv, &m, &n, &eps, &delta_t);
/*
** Erstes und zweites Argument: Größe der Matrix
*/
m = atoi(argv[1]);
if ((m < 3) || (m > 6000)) {
fprintf(stderr, "Error: size m out of range [3 .. 6000] !\n");
exit(1);
}
n = atoi(argv[2]);
if ((n < 3) || (n > 6000)) {
fprintf(stderr, "Error: size n out of range [3 .. 6000] !\n");
exit(1);
}
/*
** Drittes (optionales) Argument: "Genauigkeitsfaktor" eps
*/
if (argc >= 4) {
eps = atof(argv[3]);
}
if ((eps <= 0) || (eps > 0.01)){
fprintf(stderr, "Error: epsilon must be between 0.0000000001 and 0.01 )\n");
exit(1);
}
/*
** Viertes (optionales) Argument: delta_t
*/
if (argc >= 5) {
delta_t = atof(argv[4]);
}
if ((delta_t <= 0) || (delta_t > 1.0)){
fprintf(stderr, "Error: delta_t (%f) must be between 0.0000000001 and 1.0\n", delta_t);
/*
a = New_Matrix(m, n);
if (a == NULL) {
fprintf(stderr, "Can't allocate matrix !\n");
exit(1);
}
Init_Matrix(a, m, n, 0);
*/
int pid, num_p;
if((err = MPI_Comm_rank(MPI_COMM_WORLD, &pid))) {
fprintf(stderr, "Cannot fetch PID due to %d\n", err);
if(MPI_Comm_rank(MPI_COMM_WORLD, &pid)) {
fprintf(stderr, "Cannot fetch PID\n");
exit(1);
}
......@@ -122,6 +85,12 @@ int main(int argc, char **argv)
pi.end_m = (coord[0]+1)*m_per_pro -1;
pi.start_n = coord[1] * n_per_pro;
pi.end_n = (coord[0]+1) * n_per_pro -1;
if(pi.end_m > m - 1) {
pi.end_m = m - 1;
}
if(pi.end_n > n - 1) {
pi.end_n = n - 1;
}
// print own info
printf("pid(%d,%d) from (%d, %d) to (%d,%d)\n",
......@@ -133,10 +102,47 @@ int main(int argc, char **argv)
pi.end_m
);
double delta_a;
partial_field = New_Matrix(pi.end_m - pi.start_m + 2, pi.end_n - pi.start_n + 2);
double **partial_field_tmp = New_Matrix(pi.end_m - pi.start_m + 2, pi.end_n - pi.start_n + 2);
int i,j;
double **swap;
double hx = 1.0/(double)m;
double hy = 1.0/(double)n;
double hx_square = hx * hx;
double hy_square = hy * hy;
double max_delta_t = 0.25*((min(hx,hy))*(min(hx,hy)))/alpha; /* minimaler Wert f�r Konvergenz */
if (delta_t > max_delta_t) {
delta_t = max_delta_t;
printf ("Info: delta_t set to %.10lf.\n", delta_t);
}
for(i = 1; i < pi.end_m - pi.start_m + 1; i++) { // catch edges
for(j = 1; j < pi.end_n - pi.start_n + 1; j++) { // catch edges
delta_a = alpha *
( (partial_field[i+1][j] + partial_field[i-1][j] - 2.0 * partial_field[i][j]) / (hy_square)
+(partial_field[i][j-1] + partial_field[i][j+1] - 2.0 * partial_field[i][j]) / (hx_square) );
delta_a = delta_a * delta_t;
partial_field_tmp[i][j] = partial_field[i][j] + delta_a;
if(delta_a > maxdiff)
maxdiff = delta_a;
}
}
swap = partial_field_tmp;
partial_field_tmp = partial_field;
partial_field = swap;
if(pid == 0) {
Write_Matrix(partial_field, pi.end_m - pi.start_m + 2, pi.end_n - pi.start_n + 2);
}
// write neighbar_com function
//MPI_Gather()
MPI_Finalize();
return 0;
}
}
\ No newline at end of file
double ** New_Matrix(int m, int n);
void Delete_Matrix(double **matrix);
void Write_Matrix(double **a, int m, int n);
void Init_Matrix(double **a, int m, int n, int init_value);
void Insert_Matrix(double **a, int a_dim0, int a_dim1, int pos_dim0, int pos_dim1, double **b, int b_dim0, int b_dim1, int offset_top, int offset_right, int offset_bottom, int offset_left);
void process_args(int argc, char **argv, int *m, int *n, double *eps, double *delta_t);
typedef struct {
int start_m; // first tile to process in X-axis
int start_n; // first tile to process in Y-axis
int end_m; // last tile to process in X-axis
int end_n; // last tile to process in Y-axis
} t_process_info;
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment