--- /dev/null
+/* Helper Functions to handle data (2D) */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "../shared.h"
+
+/* fix file owner if run with sudo */
+void fixsudo(const char *filename)
+{
+ if(getenv("SUDO_UID") && getenv("SUDO_GID")) {
+ int uid = atoi(getenv("SUDO_UID"));
+ int gid = atoi(getenv("SUDO_GID"));
+ if(chown(filename, uid, gid)) {
+ perror("fixsudo/chown");
+ return;
+ }
+ }
+}
+
+
+/* write a (semi-) human-readable dump of the lattice */
+void write_populations(d2q9_block_t lattice[CORES_Y][CORES_X],
+ int core_x, int core_y, int iter)
+{
+ char *name = "populations.dat";
+
+ FILE *file = fopen(name, "a");
+ if(!file) {
+ perror("write_populations/fopen");
+ return;
+ }
+
+ for(int y = 0; y < BLOCK_Y; y++) {
+ for(int x = 0; x < BLOCK_X; x++) {
+ fprintf(file, "%03d: [%02d,%02d]: ", iter, x, y);
+ for(int q = 0; q < 9; q++) {
+ fprintf(file, "%.5f\t", lattice[core_y][core_x][y][x][q]);
+ }
+ fprintf(file, "\n");
+ }
+ }
+ fprintf(file, "\n");
+
+ /* close and chown if run with sudo */
+ fclose(file);
+
+ return;
+}
+
+/* write an 8-bit grayscale, binary PPM image of the lattice */
+void write_image(d2q9_block_t lattice[CORES_Y][CORES_X], int iter)
+{
+ char name[32]; snprintf(name, 32, "./tmp/i%06d.ppm", iter);
+
+ /* open image file and write header */
+ FILE *file = fopen(name, "wb");
+ if(!file) {
+ perror("write_image/fopen");
+ return;
+ }
+ fprintf(file, "P5\n%d %d\n%d\n", CORES_X*BLOCK_X, CORES_Y*BLOCK_Y, 255);
+
+ /* calculate all densities and remember min/max */
+ FLOAT min = 1.0, max = 0;
+ FLOAT rhos[CORES_Y][BLOCK_Y][CORES_X][BLOCK_X];
+ for(int cy = 0; cy < CORES_Y; cy++) {
+ for(int y = 0; y < BLOCK_Y; y++) {
+ for(int cx = 0; cx < CORES_X; cx++) {
+ for(int x = 0; x < BLOCK_X; x++) {
+ FLOAT rho = 0;
+ for(int q = 0; q < 9; q++)
+ rho += lattice[cy][cx][y][x][q];
+ rhos[cy][y][cx][x] = rho;
+
+ if(rho < min) min = rho;
+ if(rho > max) max = rho;
+ }
+ }
+ }
+ }
+
+ /* scale values and write them to the image */
+ for(int cy = 0; cy < CORES_Y; cy++) {
+ for(int y = 0; y < BLOCK_Y; y++) {
+ for(int cx = 0; cx < CORES_X; cx++) {
+ for(int x = 0; x < BLOCK_X; x++) {
+ unsigned char gray;
+ gray = (255. * (rhos[cy][y][cx][x]-min) / (max-min));
+ fwrite(&gray, 1, 1, file);
+ }
+ }
+ }
+ }
+
+ /* close the file and chown if run with sudo */
+ fclose(file);
+ fixsudo(name);
+
+ return;
+}
+
+/* convert image files to animated gif ./tmp/anim.gif */
+void write_animation(void)
+{
+ int result;
+
+ /* call imagemagick */
+ result = system("convert ./tmp/i*.ppm ./tmp/anim.gif"); (void)result;
+ fixsudo("./tmp/anim.gif");
+
+ return;
+}
#define FAIL(...) { fprintf(stderr, __VA_ARGS__); exit(1); }
#define SHM_OFFSET 0x01000000
+/* helper functions */
+void fixsudo(const char *filename);
+void write_populations(d2q9_block_t lattice[CORES_Y][CORES_X], int core_x, int core_y, int iter);
+void write_image(d2q9_block_t lattice[CORES_Y][CORES_X], int iter);
+void write_animation(void);
+
+/* globals */
static states_t laststates, states; /* old state value */
static shm_t shm = {{{ 0 }}}; /* local shm copy */
-void write_populations(FILE *file, int core_x, int core_y, int iter)
-{
- for(int y = 0; y < BLOCK_Y; y++) {
- for(int x = 0; x < BLOCK_X; x++) {
- fprintf(file, "%03d: [%02d,%02d]: ", iter, x, y);
- for(int q = 0; q < 9; q++) {
- fprintf(file, "%.5f\t",
- shm.lattice[core_y][core_x][y][x][q]);
- }
- fprintf(file, "\n");
- }
- }
- fprintf(file, "\n");
-
- return;
-}
-
-void write_image(int iter)
-{
- FILE *file; char name[32];
-
- snprintf(name, 32, "./tmp/i%06d.ppm", iter);
- file = fopen(name, "wb");
- if(!file) exit(-1);
-
- fprintf(file, "P5\n%d %d\n%d\n",
- CORES_X*BLOCK_X, CORES_Y*BLOCK_Y, 255);
-
- /* calculate all densities and remember min/max */
- FLOAT min = 1.0, max = 0;
- FLOAT rhos[CORES_Y][BLOCK_Y][CORES_X][BLOCK_X];
- for(int cy = 0; cy < CORES_Y; cy++) {
- for(int y = 0; y < BLOCK_Y; y++) {
- for(int cx = 0; cx < CORES_X; cx++) {
- for(int x = 0; x < BLOCK_X; x++) {
- FLOAT rho = 0;
- for(int q = 0; q < 9; q++)
- rho += shm.lattice[cy][cx][y][x][q];
- rhos[cy][y][cx][x] = rho;
-
- if(rho < min) min = rho;
- if(rho > max) max = rho;
- }
- }
- }
- }
-
- /* now scale values and write to image file */
- for(int cy = 0; cy < CORES_Y; cy++) {
- for(int y = 0; y < BLOCK_Y; y++) {
- for(int cx = 0; cx < CORES_X; cx++) {
- for(int x = 0; x < BLOCK_X; x++) {
- unsigned char gray;
- gray = (255. * (rhos[cy][y][cx][x]-min)
- / (max-min));
- fwrite(&gray, 1, 1, file);
- }
- }
- }
- }
-
- fclose(file);
- if(chown(name, atoi(getenv("SUDO_UID")), atoi(getenv("SUDO_GID")))) {
- FAIL("Can't chown image!\n");
- }
-
- return;
-}
-
int main()
{
char *filename = "bin/lb_2d.srec";
- FILE *datfile; char *datname = "populations.dat";
- int dummy, old0 = 0;
/* remove old results */
- dummy = system("rm -f ./tmp/i*.ppm ./tmp/anim.gif populations.dat");
+ int dummy = system("rm -f ./tmp/i*.ppm ./tmp/anim.gif populations.dat");
(void)dummy;
e_epiphany_t dev;
e_set_host_verbosity(H_D0);
e_set_loader_verbosity(L_D0);
- /* overwrite results file */
- datfile = fopen(datname, "w");
- if(!datfile)
- FAIL("Can't write result file: %s\n", strerror(errno));
-
/* initialize workgroup, allocate and clear shared memory */
if(e_init(NULL) != E_OK)
FAIL("Can't init!\n");
printf("\n");
}
#else
- printf("0x%08x\r", states[0][0]);
- fflush(stdout);
+ printf("0x%08x\r", states[0][0]); fflush(stdout);
#endif
/* write data */
+ static uint32_t old0 = -1;
if(states[0][0] != old0) {
- //write_populations(datfile, 0, states[0]);
- write_image(states[0][0]);
+ //write_populations(shm.lattice, 0, 0, states[0][0]);
+ write_image(shm.lattice, states[0][0]);
old0 = states[0][0];
}
if(e_close(&dev) != E_OK) FAIL("Can't close!\n");
if(e_finalize() != E_OK) FAIL("Can't finalize!\n");
- fclose(datfile);
- if(chown(datname, atoi(getenv("SUDO_UID")), atoi(getenv("SUDO_GID")))) {
- FAIL("Can't chown populations!\n");
- }
+ fixsudo("populations.dat");
printf("\nProgram finished successfully.\n");
printf("Convert ...\n");
- dummy = system("convert ./tmp/i*.ppm ./tmp/anim.gif"); (void)dummy;
- if(chown("./tmp/anim.gif", atoi(getenv("SUDO_UID")), atoi(getenv("SUDO_GID")))) {
- FAIL("Can't chown anim!\n");
- }
+ write_animation();
return(0);
}