gem5/splash2/codes/apps/fmm/box.C
Sanchayan Maity 0f4b39775c Fix splash2 benchmark
During the last commit of splash2 benchmark it seems before committing
when we ran "make clean", it effectively undid what the patch at below
link did
http://www.capsl.udel.edu/splash/Download.html

Fix this since without this it is not possible to build the arcane
splash2 benchmark.
2017-04-26 21:33:02 +05:30

368 lines
9.7 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. */
/* */
/*************************************************************************/
#include <stdio.h>
#include <math.h>
#include "defs.h"
#include "memory.h"
#include "particle.h"
#include "box.h"
/* How many boxes can fit on one line */
#define BOXES_PER_LINE 4
#define TERMS_PER_LINE 2
box *Grid = NULL;
void ZeroBox(long my_id, box *b);
void
CreateBoxes (long my_id, long num_boxes)
{
long i;
LOCK(G_Memory->mal_lock);
Local[my_id].B_Heap = (box *) G_MALLOC(num_boxes * sizeof(box));
/* POSSIBLE ENHANCEMENT: Here is where one might distribute the
B_Heap data across physically distributed memories as desired.
One way to do this is as follows:
char *starting_address;
char *ending_address;
starting_address = (char *) Local[my_id].B_Heap;
ending_address = (((char *) Local[my_id].B_Heap)
+ (num_boxes * sizeof(particle *)) - 1);
Place all addresses x such that (starting_address <= x < ending_address)
on node my_id
*/
UNLOCK(G_Memory->mal_lock);
Local[my_id].Max_B_Heap = num_boxes;
Local[my_id].Index_B_Heap = 0;
for (i = 0; i < num_boxes; i++) {
Local[my_id].B_Heap[i].exp_lock_index = i % (MAX_LOCKS - 1);
Local[my_id].B_Heap[i].particle_lock_index = i % (MAX_LOCKS - 1);
Local[my_id].B_Heap[i].id = i + ((double) my_id / ID_LIMIT);
ZeroBox(my_id, &Local[my_id].B_Heap[i]);
}
}
void
FreeBoxes (long my_id)
{
long i;
box *b_array;
b_array = Local[my_id].B_Heap;
for (i = 0; i < Local[my_id].Index_B_Heap; i++)
ZeroBox(my_id, &b_array[i]);
Local[my_id].Index_B_Heap = 0;
}
void
ZeroBox (long my_id, box *b)
{
long i;
b->type = CHILDLESS;
b->num_particles = 0;
for (i = 0; i < MAX_PARTICLES_PER_BOX; i++)
b->particles[i] = NULL;
b->parent = NULL;
for (i = 0; i < NUM_OFFSPRING; i++) {
b->children[i] = NULL;
b->shadow[i] = NULL;
}
b->num_children = 0;
b->construct_synch = 0;
b->interaction_synch = 0;
b->cost = 0;
b->proc = my_id;
b->subtree_cost = 0;
b->next = NULL;
b->prev = NULL;
}
/*
* InitBox (long my_id, real x_center, real y_center, real length, long level, box *parent)
*
* Args : the x_center and y_center of the center of the box;
* the length of the box;
* the level of the box;
* the address of b's parent.
*
* Returns : the address of the newly created box.
*
* Side Effects : Initializes num_particles to 0, all other pointers to NULL,
* and sets the box ID to a unique number. It also creates the space for
* the two expansion arrays.
*
*/
box *
InitBox (long my_id, real x_center, real y_center, real length, box *parent)
{
box *b;
if (Local[my_id].Index_B_Heap == Local[my_id].Max_B_Heap) {
LockedPrint("ERROR (P%d) : Ran out of boxes\n", my_id);
exit(-1);
}
b = &Local[my_id].B_Heap[Local[my_id].Index_B_Heap++];
b->x_center = x_center;
b->y_center = y_center;
b->length = length;
b->parent = parent;
if (parent == NULL)
b->level = 0;
else
b->level = parent->level + 1;
return b;
}
/*
* PrintBox (box *b)
*
* Args : the address of a box, b.
*
* Returns : nothing.
*
* Side Effects : Prints to stdout the information stored for b.
*
*/
void
PrintBox (box *b)
{
LOCK(G_Memory->io_lock);
fflush(stdout);
if (b != NULL) {
printf("Info for B%f :\n", b->id);
printf(" X center = %.40g\n", b->x_center);
printf(" Y center = %.40g\n", b->y_center);
printf(" Length = %.40g\n", b->length);
printf(" Level = %ld\n", b->level);
printf(" Type = %d\n", b->type);
printf(" Child Num = %ld\n", b->child_num);
if (b->parent == NULL)
printf(" Parent = NONE\n");
else
printf(" Parent = B%f\n", b->parent->id);
printf(" Children's IDs : ");
if (b->num_children != 0)
PrintBoxArrayIds(b->children, b->num_children);
else
printf("NONE\n");
printf(" Sibling's IDs : ");
if (b->num_siblings != 0)
PrintBoxArrayIds(b->siblings, b->num_siblings);
else
printf("NONE\n");
printf(" Colleagues' IDs : ");
PrintBoxArrayIds(b->colleagues, b->num_colleagues);
printf(" U List IDs : ");
PrintBoxArrayIds(b->u_list, b->num_u_list);
printf(" V List IDs : ");
PrintBoxArrayIds(b->v_list, b->num_v_list);
printf(" W List IDs : ");
PrintBoxArrayIds(b->w_list, b->num_w_list);
printf(" # of Particles = %ld\n", b->num_particles);
printf(" Particles' IDs : ");
PrintParticleArrayIds(b->particles, b->num_particles);
printf(" Assigned Process ID : %ld\n", b->proc);
printf(" Cost : %ld\n", b->cost);
printf("\n");
}
else
printf("Box has not been initialized yet.\n\n");
UNLOCK(G_Memory->io_lock);
}
/*
* PrintBoxArrayIds (box_node *b_array[], long array_length)
*
* Args : the address of the box array, b_array;
* the length of the array, array_length.
*
* Returns : nothing.
*
* Side Effects : Prints to stdout just the id numbers for every box in
* b_array.
*
*/
void
PrintBoxArrayIds (box *b_array[], long array_length)
{
long i;
long tab_count;
tab_count = 0;
for (i = 0; i < array_length; i++) {
if (tab_count == 0) {
printf("\n");
tab_count = BOXES_PER_LINE;
}
if (b_array[i] != NULL)
printf("\tB%f", b_array[i]->id);
tab_count -= 1;
}
printf("\n");
}
/*
* PrintExpansionTerms (real expansion[])
*
* Args : the array of expansion terms, expansion.
*
* Returns : nothing.
*
* Side Effects : Prints to stdout the contents of expansion.
*
*/
void
PrintExpansionTerms (complex expansion[])
{
long i;
long tab_count = 0;
for (i = 0; i < Expansion_Terms; i++) {
if (tab_count == 0) {
printf("\n");
tab_count = TERMS_PER_LINE;
}
if (expansion[i].i >= (real) 0.0)
printf("\ta%ld = %.3e + %.3ei", i, expansion[i].r, expansion[i].i);
else
printf("\ta%ld = %.3e - %.3ei", i, expansion[i].r, -expansion[i].i);
tab_count -= 1;
}
printf("\n");
}
void
ListIterate (long my_id, box *b, box **list, long length, list_function function)
{
long i;
for (i = 0; i < length; i++) {
if (list[i] == NULL) {
LockedPrint("ERROR (P%d) : NULL list entry\n", my_id);
exit(-1);
}
(*function)(my_id, list[i], b);
}
}
/*
* AdjacentBoxes (box *b1, box *b2)
*
* Args : two potentially adjacent boxes, b1 and b2.
*
* Returns : TRUE, if boxes are adjacent, FALSE if not.
*
* Side Effects : none.
*
* Comments : Two boxes are adjacent if their centers are separated in either
* the x or y directions by (1/2 the length of b1) + (1/2 length of b2),
* and separated in the other direction by a distance less than or equal
* to (1/2 the length of b1) + (1/2 the length of b2).
*
* NOTE : By this definition, parents are NOT adjacent to their children.
*/
long
AdjacentBoxes (box *b1, box *b2)
{
real exact_separation;
real x_separation;
real y_separation;
long ret_val;
exact_separation = (b1->length / (real) 2.0) + (b2->length / (real) 2.0);
x_separation = (real) fabs((double)(b1->x_center - b2->x_center));
y_separation = (real) fabs((double)(b1->y_center - b2->y_center));
if ((x_separation == exact_separation) &&
(y_separation <= exact_separation))
ret_val = TRUE;
else
if ((y_separation == exact_separation) &&
(x_separation <= exact_separation))
ret_val = TRUE;
else
ret_val = FALSE;
return ret_val;
}
/*
* WellSeparatedBoxes (box *b1, box *b2)
*
* Args : Two potentially well separated boxes, b1 and b2.
*
* Returns : TRUE, if the two boxes are well separated, and FALSE if not.
*
* Side Effects : none.
*
* Comments : Well separated means that the two boxes are separated by the
* length of the boxes. If one of the boxes is bigger than the other,
* the smaller box is given the length of the larger box. This means
* that the centers of the two boxes, regardless of their relative size,
* must be separated in the x or y direction (or both) by at least
* twice the length of the biggest box.
*
*/
long
WellSeparatedBoxes (box *b1, box *b2)
{
real min_ws_distance;
real x_separation;
real y_separation;
long ret_val;
if (b1->length > b2->length)
min_ws_distance = b1->length * (real) 2.0;
else
min_ws_distance = b2->length * (real) 2.0;
x_separation = (real) fabs((double)(b1->x_center - b2->x_center));
y_separation = (real) fabs((double)(b1->y_center - b2->y_center));
if ((x_separation >= min_ws_distance) || (y_separation >= min_ws_distance))
ret_val = TRUE;
else
ret_val = FALSE;
return ret_val;
}
#undef BOXES_PER_LINE
#undef TERMS_PER_LINE