/*************************************************************************/ /* */ /* 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. */ /* */ /*************************************************************************/ /****************************************************************************** * * * octree.c: Perform hiearchical enumeration of dataset. * * * ******************************************************************************/ #include #include "incl.h" #define WRITE_PYR(IBIT,ILEVEL,IZ,IY,IX)\ (PYR_ADDRESS(ILEVEL,IZ,IY,IX),\ *pyr_address2|=(IBIT)<Index = NODE0; /* POSSIBLE ENHANCEMENT: If you did want to replicate the octree on all processors, don't do this create. */ #ifndef SERIAL_PREPROC for (i=1; iIndex = 0; /* POSSIBLE ENHANCEMENT: If you did want to replicate the octree on all processors, don't do this create. */ #ifndef SERIAL_PREPROC for (i=1; i 1) { pyr_len[level][i] = (pyr_len[level-1][i]+1)>>1; pyr_voxlen[level][i] = pyr_voxlen[level-1][i]<<1; } else { pyr_len[level][i] = pyr_len[level-1][i]; pyr_voxlen[level][i] = pyr_voxlen[level-1][i]; } } pyr_length[level] = (pyr_len[level][X]* pyr_len[level][Y]*pyr_len[level][Z]+7)/8; Allocate_Pyramid_Level(&pyr_address[level], pyr_length[level]); Compute_Pyramid_Level(level); } } void Compute_Base() { long outx, outy, outz; 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)pyr_len[0][X]/(float)voxel_section[X]); num_yqueue = ROUNDUP((float)pyr_len[0][Y]/(float)voxel_section[Y]); num_zqueue = ROUNDUP((float)pyr_len[0][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,pyr_len[0][X]); ystart = ((my_node / voxel_section[X]) % voxel_section[Y]) * num_yqueue; ystop = MIN(ystart+num_yqueue,pyr_len[0][Y]); zstart = (my_node / (voxel_section[X] * voxel_section[Y])) * num_zqueue; zstop = MIN(zstart+num_zqueue,pyr_len[0][Z]); /* POSSIBLE ENHANCEMENT: If you did want to replicate the octree on all processors, then execute what's in the SERIAL_PREPROC ifdef below. */ #ifdef SERIAL_PREPROC zstart = 0; zstop = pyr_len[0][Z]; ystart = 0; ystop = pyr_len[0][Y]; xstart = 0; xstop = pyr_len[0][X]; #endif for (outz=zstart; outzSlaveBarrier,num_nodes); #endif } void Or_Neighbors_In_Base() { long outx,outy,outz; /* Loop indices in image space */ long outx_plus_one,outy_plus_one,outz_plus_one; BOOLEAN bit; long pmap_partition,zstart,zstop; 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. */ /* assumed for now that z direction has enough parallelism */ pmap_partition = ROUNDUP((double)pyr_len[0][Z]/(double)num_nodes); zstart = pmap_partition * my_node; zstop = MIN(zstart+pmap_partition,pyr_len[0][Z]); /* POSSIBLE ENHANCEMENT: If you did want to replicate the octree on all processors, then you should execute what's in the SERIAL_PREPROC ifdef below. */ #ifdef SERIAL_PREPROC zstart = 0; zstop = pyr_len[0][Z]; #endif for (outz=zstart; outzSlaveBarrier,num_nodes); #endif } void Allocate_Pyramid_Level(address, length) BYTE **address; long length; { long i; printf(" Allocating pyramid level of %ld bytes...\n", length*sizeof(BYTE)); /* POSSIBLE ENHANCEMENT: If you want to replicate the octree on all processors, then replace the macro below with a regular malloc. */ *address = (BYTE *)NU_MALLOC(length*sizeof(BYTE),0); if (*address == NULL) Error(" No space available for pyramid level.\n"); /* POSSIBLE ENHANCEMENT: Here's where one might distribute the octree among physical memories if one wanted to. */ for (i=0; i