gem5/splash2/codes/apps/volrend/opacity.C
Sanchayan Maity 2fcc51c2c1 Commit splash2 benchmark
While at it also add the libpthread static library amd m5op_x86
for matrix multiplication test code as well.

Note that the splash2 benchmark code does not comply with gem5
coding guidelines. Academic guys never seem to follow 80 columns
and no whitespace guideline :(.
2017-04-26 20:50:15 +05:30

238 lines
7.9 KiB
C

/*************************************************************************/
/* */
/* Copyright (c) 1994 Stanford University */
/* */
/* All rights reserved. */
/* */
/* Permission is given to use, copy, and modify this software for any */
/* non-commercial purpose as long as this copyright notice is not */
/* removed. All other uses, including redistribution in whole or in */
/* part, are forbidden without prior written permission. */
/* */
/* This software is provided with absolutely no warranty and no */
/* support. */
/* */
/*************************************************************************/
/******************************************************************************
* *
* opacity.c: Compute opacity map using region boundary method. Shading *
* transition width used is zero. *
* *
******************************************************************************/
#include <cstring>
#include "incl.h"
/* The following declarations show the layout of the .opc file. */
/* If changed, the version number must be incremented and code */
/* written to handle loading of both old and current versions. */
/* Version for new .opc files: */
#define OPC_CUR_VERSION 1 /* Initial release */
short opc_version; /* Version of this .opc file */
short opc_len[NM]; /* Size of this opacity map */
int opc_length; /* Total number of opacities in map */
/* (= product of lens) */
OPACITY *opc_address; /* Pointer to opacity map */
/* End of layout of .opc file. */
EXTERN_ENV
#include "anl.h"
void Compute_Opacity()
{
long i;
/* to allow room for gradient operator plus 1-voxel margin */
/* of zeros if shading transition width > 0. Zero voxels */
/* are independent of input map and can be outside inset. */
for (i=0; i<NM; i++) {
opc_len[i] = map_len[i] - 2*INSET;
}
opc_length = opc_len[X] * opc_len[Y] * opc_len[Z];
Allocate_Opacity(&opc_address, opc_length);
printf(" Computing opacity map...\n");
Global->Index = NODE0;
#ifndef SERIAL_PREPROC
for (i=1; i<num_nodes; i++) CREATE(Opacity_Compute)
#endif
Opacity_Compute();
}
void Allocate_Opacity(address, length)
OPACITY **address;
long length;
{
long i;
printf(" Allocating opacity map of %ld bytes...\n",
length*sizeof(OPACITY));
*address = (OPACITY *)NU_MALLOC(length*sizeof(OPACITY),0);
if (*address == NULL)
Error(" No space available for map.\n");
/* POSSIBLE ENHANCEMENT: Here's where one might distribute the
opacity map among physical memories if one wanted to.
*/
for (i=0; i<length; i++) *(*address+i) = 0;
}
void Opacity_Compute()
{
long inx,iny,inz; /* Voxel location in object space */
long outx,outy,outz; /* Loop indices in image space */
long density;
float magnitude;
float opacity, grd_x,grd_y,grd_z;
long zstart,zstop;
long num_xqueue,num_yqueue,num_zqueue,num_queue;
long xstart,xstop,ystart,ystop;
long my_node;
LOCK(Global->IndexLock);
my_node = Global->Index++;
UNLOCK(Global->IndexLock);
my_node = my_node%num_nodes;
/* POSSIBLE ENHANCEMENT: Here's where one might bind the process to a
processor, if one wanted to.
*/
num_xqueue = ROUNDUP((float)opc_len[X]/(float)voxel_section[X]);
num_yqueue = ROUNDUP((float)opc_len[Y]/(float)voxel_section[Y]);
num_zqueue = ROUNDUP((float)opc_len[Z]/(float)voxel_section[Z]);
num_queue = num_xqueue * num_yqueue * num_zqueue;
xstart = (my_node % voxel_section[X]) * num_xqueue;
xstop = MIN(xstart+num_xqueue,opc_len[X]);
ystart = ((my_node / voxel_section[X]) % voxel_section[Y]) * num_yqueue;
ystop = MIN(ystart+num_yqueue,opc_len[Y]);
zstart = (my_node / (voxel_section[X] * voxel_section[Y])) * num_zqueue;
zstop = MIN(zstart+num_zqueue,opc_len[Z]);
#ifdef SERIAL_PREPROC
zstart = 0;
zstop = opc_len[Z];
ystart = 0;
ystop = opc_len[Y];
xstart = 0;
xstop = opc_len[X];
#endif
for (outz=zstart; outz<zstop; outz++) {
for (outy=ystart; outy<ystop; outy++) {
for (outx=xstart; outx<xstop; outx++) {
inx = INSET + outx;
iny = INSET + outy;
inz = INSET + outz;
density = MAP(inz,iny,inx);
if (density > density_epsilon) {
grd_x = (float)((long)MAP(inz,iny,inx+1) - (long)MAP(inz,iny,inx-1));
grd_y = (float)((long)MAP(inz,iny+1,inx) - (long)MAP(inz,iny-1,inx));
grd_z = (float)((long)MAP(inz+1,iny,inx) - (long)MAP(inz-1,iny,inx));
magnitude = grd_x*grd_x+grd_y*grd_y+grd_z*grd_z;
/* If (magnitude*grd_divisor)**2 is small, skip voxel */
if (magnitude > nmag_epsilon) {
magnitude = .5*sqrt(magnitude);
/* For density * magnitude (d*m) operator: */
/* Set opacity of surface to the product of user-specified */
/* functions of local density and gradient magnitude. */
/* Detects both front and rear-facing surfaces. */
opacity = density_opacity[density] *
magnitude_opacity[(long)magnitude];
/* If opacity is small, skip shading and compositing of sample */
if (opacity > opacity_epsilon)
OPC(outz,outy,outx) = NINT(opacity*MAX_OPC);
}
}
else
OPC(outz,outy,outx) = MIN_OPC;
}
}
}
#ifndef SERIAL_PREPROC
BARRIER(Global->SlaveBarrier,num_nodes);
#endif
}
void Load_Opacity(filename)
char filename[];
{
char local_filename[FILENAME_STRING_SIZE];
int fd;
strcpy(local_filename,filename);
strcat(local_filename,".opc");
fd = Open_File(local_filename);
Read_Shorts(fd,(unsigned char *)&opc_version, (long)sizeof(opc_version));
if (opc_version != OPC_CUR_VERSION)
Error(" Can't load version %d file\n",opc_version);
Read_Shorts(fd,(unsigned char *)opc_len,(long)sizeof(map_len));
Read_Longs(fd,(unsigned char *)&opc_length,(long)sizeof(opc_length));
Allocate_Opacity(&opc_address,opc_length);
printf(" Loading opacity map from .opc file...\n");
Read_Bytes(fd,(unsigned char *)opc_address,(long)(opc_length*sizeof(OPACITY)));
Close_File(fd);
}
void Store_Opacity(filename)
char filename[];
{
char local_filename[FILENAME_STRING_SIZE];
int fd;
strcpy(local_filename,filename);
strcat(local_filename,".opc");
fd = Create_File(local_filename);
opc_version = OPC_CUR_VERSION;
strcpy(local_filename,filename);
strcat(local_filename,".opc");
fd = Create_File(local_filename);
Write_Shorts(fd,(unsigned char *)&opc_version,(long)sizeof(opc_version));
Write_Shorts(fd,(unsigned char *)opc_len,(long)sizeof(opc_len));
Write_Longs(fd,(unsigned char *)&opc_length,(long)sizeof(opc_length));
printf(" Storing opacity map into .opc file...\n");
Write_Bytes(fd,(unsigned char *)opc_address,(long)(opc_length*sizeof(OPACITY)));
Close_File(fd);
}
void Deallocate_Opacity(address)
OPACITY **address;
{
printf(" Deallocating opacity map...\n");
/* G_FREE(*address); */
*address = NULL;
}