Skip to content
Snippets Groups Projects
partition_allocator.c 80.66 KiB
/*****************************************************************************\
 *  partition_allocator.c - Assorted functions for layout of bglblocks, 
 *	 wiring, mapping for smap, etc.
 *  $Id$
 *****************************************************************************
 *  Copyright (C) 2004 The Regents of the University of California.
 *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
 *  Written by Dan Phung <phung4@llnl.gov>, Danny Auble <da@llnl.gov>
 *  
 *  This file is part of SLURM, a resource management program.
 *  For details, see <http://www.llnl.gov/linux/slurm/>.
 *  
 *  SLURM is free software; you can redistribute it and/or modify it under
 *  the terms of the GNU General Public License as published by the Free
 *  Software Foundation; either version 2 of the License, or (at your option)
 *  any later version.
 *  
 *  SLURM is distributed in the hope that it will be useful, but WITHOUT ANY
 *  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 *  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 *  details.
 *  
 *  You should have received a copy of the GNU General Public License along
 *  with SLURM; if not, write to the Free Software Foundation, Inc.,
 *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
\*****************************************************************************/

#if HAVE_CONFIG_H
#  include "config.h"
#endif

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "src/partition_allocator/partition_allocator.h"

#ifdef HAVE_BGL_FILES
# include "src/plugins/select/bluegene/wrap_rm_api.h"
#endif

#define DEBUG_PA
#define BEST_COUNT_INIT 20

#ifdef HAVE_BGL
int DIM_SIZE[PA_SYSTEM_DIMENSIONS] = {0,0,0};
#else
int DIM_SIZE[PA_SYSTEM_DIMENSIONS] = {0};
#endif

bool _initialized = false;
bool have_db2 = false;

/* _pa_system is the "current" system that the structures will work
 *  on */
pa_system_t *pa_system_ptr = NULL;
List path = NULL;
List best_path = NULL;
int best_count;
int color_count = 0;
char letters[36];
char colors[6];

/** internal helper functions */
#ifdef HAVE_BGL_FILES
/** */
static void _bp_map_list_del(void *object);
#endif
#ifdef HAVE_BGL
/* */
static int _check_for_options(pa_request_t* pa_request); 
/* */
static int _append_geo(int *geo, List geos, int rotate);
/* */
static int _fill_in_coords(List results, List start_list, 
			   int *geometry, int conn_type);
/* */
static int _reset_the_path(pa_switch_t *curr_switch, int source, 
			   int target, int dim);
/* */
static int _copy_the_path(pa_switch_t *curr_switch, pa_switch_t *mark_switch, 
			  int source, int dim);
/* */
static int _find_yz_path(pa_node_t *pa_node, int *first, 
			 int *geometry, int conn_type);
/* */
static int _create_config_even(pa_node_t ***grid);
#else
/* */
static int _create_config_even(pa_node_t *grid);
#endif

/** */
static void _new_pa_node(pa_node_t *pa_node, 
		int *coord);
/** */
//static void _print_pa_node(pa_node_t* pa_node);
/** */
static void _create_pa_system(void);
/* */
static void _delete_pa_system(void);
/* */
static void _delete_path_list(void *object);

/* find the first partition match in the system */
static int _find_match(pa_request_t* pa_request, List results);

static bool _node_used(pa_node_t* pa_node, int *geometry);

/* */
static void _switch_config(pa_node_t* source, pa_node_t* target, int dim, 
			   int port_src, int port_tar);
/* */
static void _set_external_wires(int dim, int count, pa_node_t* source, 
				pa_node_t* target_1);
/* */
static char *_set_internal_wires(List nodes, int size, int conn_type);

/* */
/* static int _find_one_hop(pa_switch_t *curr_switch, int source_port,  */
/* 			 List nodes, int dim, int *diff); */

/* */
static int _find_x_path(List results, pa_node_t *pa_node, 
			int *start, int *first, 
			int *geometry, int found, int conn_type);
/* */
static int _remove_node(List results, int *node_tar);
/* */
static int _find_next_free(pa_switch_t *curr_switch, int source_port, 
			   List nodes, int dim, int count);

/* */
static int _finish_torus(pa_switch_t *curr_switch, int source_port, 
			   List nodes, int dim, int count, int *start);
/* */
static int *_set_best_path();
/* */
/* static int _configure_dims(int *coord, List nodes, int *start,  */
/* 			   int *end, int conn_type); */
/* */
static int _set_one_dim(int *start, int *end, int *coord);

/* Global */
List bp_map_list;
List bgl_info_list;

extern void destroy_bgl_info_record(void* object)
{
	bgl_info_record_t* bgl_info_record = (bgl_info_record_t*) object;

	if (bgl_info_record) {
		if(bgl_info_record->nodes) 
			xfree(bgl_info_record->nodes);
		if(bgl_info_record->owner_name)
			xfree(bgl_info_record->owner_name);
		if(bgl_info_record->bgl_part_id)
			xfree(bgl_info_record->bgl_part_id);
		
		xfree(bgl_info_record);
	}
}

/**
 * create a partition request.  Note that if the geometry is given,
 * then size is ignored.  
 * 
 * OUT - pa_request: structure to allocate and fill in.  
 * IN - geometry: requested geometry of partition
 * IN - size: requested size of partition
 * IN - rotate: if true, allows rotation of partition during fit
 * IN - elongate: if true, will try to fit different geometries of
 *      same size requests
 * IN - contig: enforce contiguous regions constraint
 * IN - conn_type: connection type of request (SELECT_TORUS or SELECT_MESH)
 * 
 * return SUCCESS of operation.
 */
extern int new_pa_request(pa_request_t* pa_request)
{
	int i=0;
#ifdef HAVE_BGL
	float sz=1;
	int geo[PA_SYSTEM_DIMENSIONS] = {0,0,0};
	int i2, i3, picked, total_sz=1 , size2, size3;
	ListIterator itr;
	int checked[8];
	int *geo_ptr;
	int messed_with = 0;
	
	pa_request->rotate_count= 0;
	pa_request->elongate_count = 0;
	pa_request->elongate_geos = list_create(NULL);
	geo[X] = pa_request->geometry[X];
	geo[Y] = pa_request->geometry[Y];
	geo[Z] = pa_request->geometry[Z];
		
	if(geo[X] != -1) { 
		for (i=0; i<PA_SYSTEM_DIMENSIONS; i++){
			if ((geo[i] < 1) 
			    ||  (geo[i] > DIM_SIZE[i])){
				error("new_pa_request Error, "
				      "request geometry is invalid %d", 
				      geo[i]); 
				return 0;
			}
		}
		_append_geo(geo, pa_request->elongate_geos, 0);
		sz=1;
		for (i=0; i<PA_SYSTEM_DIMENSIONS; i++)
			sz *= pa_request->geometry[i];
		pa_request->size = sz;
		sz=0;
	}
	
	if(pa_request->elongate || sz) {
		sz=1;
		/* decompose the size into a cubic geometry */
		pa_request->rotate= 1;
		pa_request->elongate = 1;		
		
		for (i=0; i<PA_SYSTEM_DIMENSIONS; i++) { 
			total_sz *= DIM_SIZE[i];
			geo[i] = 1;
		}
		
		if(pa_request->size==1) {
			_append_geo(geo, 
				    pa_request->elongate_geos,
				    pa_request->rotate);
			goto endit;
		}
		
		if(pa_request->size<=DIM_SIZE[Y]) {
			geo[X] = 1;
			geo[Y] = pa_request->size;
			geo[Z] = 1;
			sz=pa_request->size;
			_append_geo(geo, 
				    pa_request->elongate_geos, 
				    pa_request->rotate);
		}
		
		i = pa_request->size/4;
		if(!(pa_request->size%2)
		   && i <= DIM_SIZE[Y]
		   && i <= DIM_SIZE[Z]) {
			geo[X] = 1;
			geo[Y] = i;
			geo[Z] = i;
			sz=pa_request->size;
			_append_geo(geo,
				    pa_request->elongate_geos,
				    pa_request->rotate);
		}
	
		if(pa_request->size>total_sz || pa_request->size<1) {
			return 0;			
		}
		sz = pa_request->size % (DIM_SIZE[Y] * DIM_SIZE[Z]);
		if(!sz) {
		      i = pa_request->size / (DIM_SIZE[Y] * DIM_SIZE[Z]);
		      geo[X] = i;
		      geo[Y] = DIM_SIZE[Y];
		      geo[Z] = DIM_SIZE[Z];
		      sz=pa_request->size;
		      _append_geo(geo,
				  pa_request->elongate_geos,
				  pa_request->rotate);
		}	
	startagain:		
		picked=0;
		for(i=0;i<8;i++)
			checked[i]=0;
		
		size3=pa_request->size;
		
		for (i=0; i<PA_SYSTEM_DIMENSIONS; i++) {
			total_sz *= DIM_SIZE[i];
			geo[i] = 1;
		}
	
		sz = 1;
		size3=pa_request->size;
		picked=0;
	tryagain:	
		if(size3!=pa_request->size)
			size2=size3;
		else
			size2=pa_request->size;
		//messedup:

		for (i=picked; i<PA_SYSTEM_DIMENSIONS; i++) { 
			if(size2<=1) 
				break;
			sz = size2%DIM_SIZE[i];
			if(!sz) {
				geo[i] = DIM_SIZE[i];	
				size2 /= DIM_SIZE[i];
			} else if (size2 > DIM_SIZE[i]){
				for(i2=(DIM_SIZE[i]-1);i2>1;i2--) {
					/* go through each number to see if 
					   the size is divisable by a smaller 
					   number that is 
					   good in the other dims. */
					if (!(size2%i2) && !checked[i2]) {
						size2 /= i2;
									
						if(i==0)
							checked[i2]=1;
							
						if(i2<DIM_SIZE[i]) 
							geo[i] = i2;
						else {
							goto tryagain;
						}
						if((i2-1)!=1 && 
						   i!=(PA_SYSTEM_DIMENSIONS-1))
							break;
					}		
				}				
				if(i2==1) {
					pa_request->size +=1;
					goto startagain;
				}
						
			} else {
				geo[i] = sz;	
				break;
			}					
		}
		
		if((geo[X]*geo[Y]) <= DIM_SIZE[Y]) {
			pa_request->geometry[X] = 1;
			pa_request->geometry[Y] = geo[X] * geo[Y];
			pa_request->geometry[Z] = geo[Z];
			_append_geo(pa_request->geometry, 
				    pa_request->elongate_geos, 
				    pa_request->rotate);

		}
		if((geo[X]*geo[Z]) <= DIM_SIZE[Y]) {
			pa_request->geometry[X] = 1;
			pa_request->geometry[Y] = geo[Y];
			pa_request->geometry[Z] = geo[X] * geo[Z];	
			_append_geo(pa_request->geometry, 
				    pa_request->elongate_geos, 
				    pa_request->rotate);		
	
		}
		if((geo[X]/2) <= DIM_SIZE[Y]) {
			if(geo[Y] == 1) {
				pa_request->geometry[Y] = geo[X]/2;
				messed_with = 1;
			} else  
				pa_request->geometry[Y] = geo[Y];
			if(!messed_with && geo[Z] == 1) {
				messed_with = 1;
				pa_request->geometry[Z] = geo[X]/2;
			} else
				pa_request->geometry[Z] = geo[Z];
			if(messed_with) {
				messed_with = 0;
				pa_request->geometry[X] = 2;
				_append_geo(pa_request->geometry, 
					    pa_request->elongate_geos, 
					    pa_request->rotate);
			}
		}
		if(geo[X] == DIM_SIZE[X]
		   && (geo[Y] < DIM_SIZE[Y] 
		       || geo[Z] < DIM_SIZE[Z])) {
			if(DIM_SIZE[Y]<DIM_SIZE[Z]) {
				i = DIM_SIZE[Y];
				DIM_SIZE[Y] = DIM_SIZE[Z];
				DIM_SIZE[Z] = i;
			}
			pa_request->geometry[X] = geo[X];
			pa_request->geometry[Y] = geo[Y];
			pa_request->geometry[Z] = geo[Z];
			if(pa_request->geometry[Y] < DIM_SIZE[Y]) {
				i = (DIM_SIZE[Y] - pa_request->geometry[Y]);
				pa_request->geometry[Y] +=i;
			}
			if(pa_request->geometry[Z] < DIM_SIZE[Z]) {
				i = (DIM_SIZE[Z] - pa_request->geometry[Z]);
				pa_request->geometry[Z] +=i;
			}
			for(i = DIM_SIZE[X]; i>0; i--) {
				pa_request->geometry[X]--;
				i2 = (pa_request->geometry[X]
				      * pa_request->geometry[Y]
				      * pa_request->geometry[Z]);
				if(i2 < pa_request->size) {
					pa_request->geometry[X]++;
					messed_with = 1;
					break;
				}					
			}			
			if(messed_with) {
				messed_with = 0;
				_append_geo(pa_request->geometry, 
					    pa_request->elongate_geos, 
					    pa_request->rotate);
			}
		}
		
		_append_geo(geo, 
			    pa_request->elongate_geos, 
			    pa_request->rotate);
	
		/* see if We can find a cube or square root of the 
		   size to make an easy cube */
		for(i=0;i<PA_SYSTEM_DIMENSIONS-1;i++) {
			sz = powf((float)pa_request->size,
				  (float)1/(PA_SYSTEM_DIMENSIONS-i));
			if(pow(sz,(PA_SYSTEM_DIMENSIONS-i))==pa_request->size)
				break;
		}
	
		if(i<PA_SYSTEM_DIMENSIONS-1) {
			/* we found something that looks like a cube! */
			i3=i;
			for (i=0; i<i3; i++) 
				geo[i] = 1;			
			
			for (i=i3; i<PA_SYSTEM_DIMENSIONS; i++)  
				if(sz<=DIM_SIZE[i]) 
					geo[i] = sz;	
				else
					goto endit;
				
			_append_geo(geo, 
				    pa_request->elongate_geos, 
				    pa_request->rotate);
		} 
	}
	
endit:
	itr = list_iterator_create(pa_request->elongate_geos);
	geo_ptr = list_next(itr);
	list_iterator_destroy(itr);
	
	if(geo_ptr == NULL)
		return 0;

	pa_request->elongate_count++;
	pa_request->geometry[X] = geo_ptr[X];
	pa_request->geometry[Y] = geo_ptr[Y];
	pa_request->geometry[Z] = geo_ptr[Z];
	sz=1;
	for (i=0; i<PA_SYSTEM_DIMENSIONS; i++)
		sz *= pa_request->geometry[i];
	pa_request->size = sz;
	
#else
	int geo[PA_SYSTEM_DIMENSIONS] = {0};
	
	pa_request->rotate_count= 0;
	pa_request->elongate_count = 0;
	pa_request->elongate_geos = list_create(NULL);
	geo[X] = pa_request->geometry[X];
		
	if(geo[X] != -1) { 
		for (i=0; i<PA_SYSTEM_DIMENSIONS; i++){
			if ((geo[i] < 1) 
			    ||  (geo[i] > DIM_SIZE[i])){
				error("new_pa_request Error, "
				      "request geometry is invalid %d", 
				      geo[i]); 
				return 0;
			}
		}
		
		pa_request->size = pa_request->geometry[X];

	} else if (pa_request->size) {
		pa_request->geometry[X] = pa_request->size;
	} else
		return 0;
			
#endif
	return 1;
}

/**
 * delete a partition request 
 */
extern void delete_pa_request(pa_request_t *pa_request)
{
	int *geo_ptr;

	if(pa_request->save_name!=NULL)
		xfree(pa_request->save_name);
	
	while((geo_ptr = list_pop(pa_request->elongate_geos)) != NULL)
		xfree(geo_ptr);

	xfree(pa_request);
}

/**
 * print a partition request 
 */
extern void print_pa_request(pa_request_t* pa_request)
{
	int i;

	if (pa_request == NULL){
		error("print_pa_request Error, request is NULL");
		return;
	}
	debug("  pa_request:");
	debug("    geometry:\t");
	for (i=0; i<PA_SYSTEM_DIMENSIONS; i++){
		debug("%d", pa_request->geometry[i]);
	}
	debug("        size:\t%d", pa_request->size);
	debug("   conn_type:\t%d", pa_request->conn_type);
	debug("      rotate:\t%d", pa_request->rotate);
	debug("    elongate:\t%d", pa_request->elongate);
	debug("force contig:\t%d", pa_request->force_contig);
	debug("     node_use:\t%d", pa_request->node_use);
}

/**
 * Search for local DB2 library
 */
static void _db2_check(void)
{
	void *handle;

	handle = dlopen("libdb2.so", RTLD_LAZY);
	if (!handle) {
		debug("can not open libdb2.so");
		return;
	}

	if (dlsym(handle, "SQLAllocHandle") == NULL)
		debug("SQLAllocHandle not found in libdb2.so");
	else
		have_db2 = true;

	dlclose(handle);
}

/**
 * Initialize internal structures by either reading previous partition
 * configurations from a file or by running the graph solver.
 * 
 * IN: node_info_msg_t * can be null, 
 *     should be from slurm_load_node().
 * 
 * return: void.
 */
extern void pa_init(node_info_msg_t *node_info_ptr)
{
	node_info_t *node_ptr = NULL;
	int i;
	int start, temp;
	char *numeric = NULL;
	int x,y,z;

#ifdef HAVE_BGL_FILES
	rm_BGL_t *bgl = NULL;
	rm_size3D_t bp_size;
	int rc = 0;
#endif		
	/* We only need to initialize once, so return if already done so. */

	if (_initialized){
		return;
	}
	y = 65;
	for (x = 0; x < 62; x++) {
		if (y == 91)
			y = 97;
		else if(y == 123)
			y = 48;
		else if(y == 58)
			y = 65;
		letters[x] = y;
		y++;
	}

	z=1;
	for (x = 0; x < 6; x++) {
		if(z == 4)
			z++;
		colors[x] = z;				
		z++;
	}
	_db2_check();

	best_count=BEST_COUNT_INIT;
						
	pa_system_ptr = (pa_system_t *) xmalloc(sizeof(pa_system_t));
	
	pa_system_ptr->xcord = 1;
	pa_system_ptr->ycord = 1;
	pa_system_ptr->num_of_proc = 0;
	pa_system_ptr->resize_screen = 0;
	
	if(node_info_ptr!=NULL) {
		for (i = 0; i < node_info_ptr->record_count; i++) {
			node_ptr = &node_info_ptr->node_array[i];
			start = 0;
			numeric = node_ptr->name;
			while (numeric) {
				if ((numeric[0] < '0')
				||  (numeric[0] > '9')) {
					numeric++;
					continue;
				}
				start = atoi(numeric);
				break;
			}
#ifdef HAVE_BGL
			temp = start / 100;
			if (DIM_SIZE[X] < temp)
				DIM_SIZE[X] = temp;
			temp = (start / 10) % 10;
			if (DIM_SIZE[Y] < temp)
				DIM_SIZE[Y] = temp;
			temp = start % 10;
			if (DIM_SIZE[Z] < temp)
				DIM_SIZE[Z] = temp;
#else
			temp = start;
			if (DIM_SIZE[X] < temp)
				DIM_SIZE[X] = temp;
#endif
		}
#ifdef HAVE_BGL
		DIM_SIZE[X]++;
		DIM_SIZE[Y]++;
		DIM_SIZE[Z]++;
#endif
		pa_system_ptr->num_of_proc = node_info_ptr->record_count;
        } 

#ifdef HAVE_BGL_FILES
	if (have_db2
	&&  (DIM_SIZE[X]==0) && (DIM_SIZE[X]==0) && (DIM_SIZE[X]==0)) {
		if ((rc = rm_set_serial(BGL_SERIAL)) != STATUS_OK) {
			error("rm_set_serial(%s): %d", BGL_SERIAL, rc);
			return;
		}
		if ((rc = rm_get_BGL(&bgl)) != STATUS_OK) {
			error("rm_get_BGL(): %d", rc);
			return;
		}
		
		if ((bgl != NULL)
		&&  ((rc = rm_get_data(bgl, RM_Msize, &bp_size)) 
		     == STATUS_OK)) {
			DIM_SIZE[X]=bp_size.X;
			DIM_SIZE[Y]=bp_size.Y;
			DIM_SIZE[Z]=bp_size.Z;
		} else {
			error("rm_get_data(RM_Msize): %d", rc);	
		}
		if ((rc = rm_free_BGL(bgl)) != STATUS_OK)
			error("rm_free_BGL(): %d", rc);
	}
#endif

#ifdef HAVE_BGL
	if ((DIM_SIZE[X]==0) && (DIM_SIZE[X]==0) && (DIM_SIZE[X]==0)) {
		debug("Setting default system dimensions");
		DIM_SIZE[X]=8;
		DIM_SIZE[Y]=4;
		DIM_SIZE[Z]=4;
	}
#else 
	if ((DIM_SIZE[X]==0) && (DIM_SIZE[X]==0) && (DIM_SIZE[X]==0)) {
		debug("Setting default system dimensions");
		DIM_SIZE[X]=100;
	}	
#endif

	if(!pa_system_ptr->num_of_proc)
		pa_system_ptr->num_of_proc = 
			DIM_SIZE[X] * DIM_SIZE[Y] * DIM_SIZE[Z];

		
	_create_pa_system();
	
	init_grid(node_info_ptr);
	
	_create_config_even(pa_system_ptr->grid);
	
	path = list_create(_delete_path_list);
	best_path = list_create(_delete_path_list);

	_initialized = true;
}

/** 
 * destroy all the internal (global) data structs.
 */
extern void pa_fini()
{
	if (!_initialized){
		return;
	}

	if (path)
		list_destroy(path);
	if (best_path)
		list_destroy(best_path);
#ifdef HAVE_BGL_FILES
	if (bp_map_list)
		list_destroy(bp_map_list);
#endif
	_delete_pa_system();

//	debug2("pa system destroyed");
}


/** 
 * set the node in the internal configuration as unusable
 * 
 * IN c: coordinate of the node to put down
 */
extern void pa_set_node_down(pa_node_t *pa_node)
{
	if (!_initialized){
		error("Error, configuration not initialized, "
			"call init_configuration first");
		return;
	}

#ifdef DEBUG_PA
#ifdef HAVE_BGL
	debug("pa_set_node_down: node to set down: [%d%d%d]", 
	      pa_node->coord[X], pa_node->coord[Y], pa_node->coord[Z]); 
#else
	debug("pa_set_node_down: node to set down: [%d]", pa_node->coord[X]); 
#endif
#endif

	/* basically set the node as used */
	pa_node->used = true;
}

/** 
 * Try to allocate a partition.
 * 
 * IN - pa_request: allocation request
 * OUT - results: List of results of the allocation request.  Each
 * list entry will be a coordinate.  allocate_part will create the
 * list, but the caller must destroy it.
 * 
 * return: success or error of request
 */
extern int allocate_part(pa_request_t* pa_request, List results)
{

	if (!_initialized){
		error("allocate_part Error, configuration not initialized, "
		      "call init_configuration first");
		return 0;
	}

	if (!pa_request){
		error("allocate_part Error, request not initialized");
		return 0;
	}
	
	// _backup_pa_system();
	if (_find_match(pa_request, results)){
		return 1;
	} else {
		return 0;
	}
}


/** 
 * Doh!  Admin made a boo boo.  Note: Undo only has one history
 * element, so two consecutive undo's will fail.
 *
 * returns SLURM_SUCCESS if undo was successful.
 */
extern int remove_part(List nodes, int new_count)
{
	int dim;
	pa_node_t* pa_node = NULL;
	pa_switch_t *curr_switch = NULL; 
	ListIterator itr;
		
	itr = list_iterator_create(nodes);
	while((pa_node = (pa_node_t*) list_next(itr)) != NULL) {
		pa_node->used = false;
		pa_node->color = 7;
		pa_node->letter = '.';
		for(dim=0;dim<PA_SYSTEM_DIMENSIONS;dim++) {		
			curr_switch = &pa_node->axis_switch[dim];
			if(curr_switch->int_wire[0].used) {
				_reset_the_path(curr_switch, 0, 1, dim);
			}
		}
	}
	list_iterator_destroy(itr);
	color_count=new_count;			
	return 1;
}

/** 
 * Doh!  Admin made a boo boo.  Note: Undo only has one history
 * element, so two consecutive undo's will fail.
 *
 * returns SLURM_SUCCESS if undo was successful.
 */
extern int alter_part(List nodes, int conn_type)
{
	/* int dim; */
/* 	pa_node_t* pa_node = NULL; */
/* 	pa_switch_t *curr_switch = NULL;  */
/* 	int size=0; */
/* 	char *name = NULL; */
/* 	ListIterator results_i;	 */	

	return SLURM_ERROR;
	/* results_i = list_iterator_create(nodes); */
/* 	while ((pa_node = list_next(results_i)) != NULL) { */
/* 		pa_node->used = false; */
		
/* 		for(dim=0;dim<PA_SYSTEM_DIMENSIONS;dim++) { */
/* 			curr_switch = &pa_node->axis_switch[dim]; */
/* 			if(curr_switch->int_wire[0].used) { */
/* 				_reset_the_path(curr_switch, 0, 1, dim); */
/* 			} */
/* 		} */
/* 		size++; */
/* 	} */
/* 	list_iterator_destroy(results_i); */
/* 	if((name = _set_internal_wires(nodes, size, conn_type)) == NULL) */
/* 		return SLURM_ERROR; */
/* 	else { */
/* 		xfree(name); */
/* 		return SLURM_SUCCESS; */
/* 	} */
}

/** 
 * After a partition is deleted or altered following allocations must
 * be redone to make sure correct path will be used in the real system
 *
 */
extern int redo_part(List nodes, int conn_type, int new_count)
{
	int dim;
	pa_node_t* pa_node;
	pa_switch_t *curr_switch; 
	int size=0;
	char *name = NULL;
	int geo[PA_SYSTEM_DIMENSIONS];
	int start[PA_SYSTEM_DIMENSIONS];
	int x = -1;
#ifdef HAVE_BGL
	int y = -1, z = -1;
#endif
	ListIterator itr;		

	itr = list_iterator_create(nodes);
	while ((pa_node = list_next(itr)) != NULL) {
		if(x==-1) {
			start[X] = pa_node->coord[X];
			start[Y] = pa_node->coord[Y];
			start[Z] = pa_node->coord[Z];
		}
		if(pa_node->coord[X]>x) {
			geo[X]++;
			x = pa_node->coord[X];
		}
#ifdef HAVE_BGL
		if(pa_node->coord[Y]>y) {
			geo[Y]++;
			y = pa_node->coord[Y];
		}
		if(pa_node->coord[Z]>z) {
			geo[Z]++;
			z = pa_node->coord[Z];
		}
#endif
		pa_node->used = false;

		pa_node->letter = letters[new_count%62];
		pa_node->color = colors[new_count%6];
			
		for(dim=0;dim<PA_SYSTEM_DIMENSIONS;dim++) {
			curr_switch = &pa_node->axis_switch[dim];
			if(curr_switch->int_wire[0].used) {
				_reset_the_path(curr_switch, 0, 1, dim);
			}
		}
		size++;
	}
	list_iterator_destroy(itr);
	color_count++;
	name = set_bgl_part(nodes, start, geo, conn_type);
	if(!name)
		return SLURM_ERROR;
	else {
		xfree(name);
		return SLURM_SUCCESS;
	}
}

extern char *set_bgl_part(List results, int *start, 
			  int *geometry, int conn_type)
{
	char *name = NULL;
	pa_node_t* pa_node = NULL;
       	int size = 0;
	int send_results = 0;
	List start_list = NULL;
	ListIterator itr;
	
	if(!results)
		results = list_create(NULL);
	else
		send_results = 1;
	start_list = list_create(NULL);
#ifdef HAVE_BGL
	if(start[X]>=DIM_SIZE[X] 
	   || start[Y]>=DIM_SIZE[Y]
	   || start[Z]>=DIM_SIZE[Z])
		return NULL;
	size = geometry[X] * geometry[Y] * geometry[Z];
	pa_node = &pa_system_ptr->
		grid[start[X]][start[Y]][start[Z]];
#else
	if(start[X]>=DIM_SIZE[X])
		return NULL;
	size = geometry[X];
	pa_node = &pa_system_ptr->
			grid[start[X]];	
#endif

	if(!pa_node)
		return NULL;
	
#ifdef HAVE_BGL
	debug2("starting at %d%d%d",pa_node->coord[X],
	       pa_node->coord[Y],pa_node->coord[Z]);
#else
	debug2("starting at %d",pa_node->coord[X]);
#endif
	
	list_append(results, pa_node);
	if(_find_x_path(results, pa_node,
			pa_node->coord, 
			pa_node->coord, 
			geometry, 
			1,
			conn_type)) {
#ifdef HAVE_BGL
		itr = list_iterator_create(results);
		while((pa_node = (pa_node_t*) list_next(itr))) {
			list_append(start_list, pa_node);
		}
		list_iterator_destroy(itr);
		
		if(!_fill_in_coords(results, 
				     start_list, 
				     geometry, 
				     conn_type))			
			return NULL;
#endif		
	} else {
		return NULL;
	}

	name = _set_internal_wires(results,
				   size,
				   conn_type);
	if(!send_results)
		list_destroy(results);
	if(name!=NULL) {
		debug2("name = %s", name);
	} else {
		debug2("can't allocte");
		xfree(name);
		return NULL;
	}

	return name;
	
}

extern int reset_pa_system()
{
	int x, y, z;
	int coord[PA_SYSTEM_DIMENSIONS];

	for (x = 0; x < DIM_SIZE[X]; x++)
		for (y = 0; y < DIM_SIZE[Y]; y++)
			for (z = 0; z < DIM_SIZE[Z]; z++) {
#ifdef HAVE_BGL
				coord[X] = x;
				coord[Y] = y;
				coord[Z] = z;
				_new_pa_node(&pa_system_ptr->grid[x][y][z], 
					     coord);
#else
				coord[X] = x;
				_new_pa_node(&pa_system_ptr->grid[x], coord);

#endif
			}
				
	return 1;
}
/* init_grid - set values of every grid point */
extern void init_grid(node_info_msg_t * node_info_ptr)
{
	node_info_t *node_ptr;
	int x, i = 0;
	uint16_t node_base_state;
	/* For systems with more than 62 active jobs or BGL blocks, 
	 * we just repeat letters */

#ifdef HAVE_BGL
	int y,z;
	for (x = 0; x < DIM_SIZE[X]; x++)
		for (y = 0; y < DIM_SIZE[Y]; y++)
			for (z = 0; z < DIM_SIZE[Z]; z++) {
				if(node_info_ptr!=NULL) {
					node_ptr = 
						&node_info_ptr->node_array[i];
					node_base_state = 
						(node_ptr->node_state) 
						& (~NODE_STATE_NO_RESPOND);
					pa_system_ptr->grid[x][y][z].color = 7;
					if ((node_base_state 
					     == NODE_STATE_DOWN) || 
					    (node_base_state 
					     == NODE_STATE_DRAINED) || 
					    (node_base_state 
					     == NODE_STATE_DRAINING)) {
						pa_system_ptr->
							grid[x][y][z].color 
							= 0;
						pa_system_ptr->
							grid[x][y][z].letter 
							= '#';
						if(_initialized) {
							pa_set_node_down(
							&pa_system_ptr->
							grid[x][y][z]);
						}
					} else {
						pa_system_ptr->grid[x][y][z].
							color = 7;
						pa_system_ptr->grid[x][y][z].
							letter = '.';
					}
					pa_system_ptr->grid[x][y][z].state 
						= node_ptr->node_state;
				} else {
					pa_system_ptr->grid[x][y][z].color = 7;
					pa_system_ptr->grid[x][y][z].letter 
						= '.';
					pa_system_ptr->grid[x][y][z].state = 
						NODE_STATE_IDLE;
				}
				pa_system_ptr->grid[x][y][z].indecies = i++;
			}
#else
	for (x = 0; x < DIM_SIZE[X]; x++) {
		if(node_info_ptr!=NULL) {
			node_ptr = &node_info_ptr->node_array[i];
			node_base_state = 
				(node_ptr->node_state) 
				& (~NODE_STATE_NO_RESPOND);
			pa_system_ptr->grid[x].color = 7;
			if ((node_base_state == NODE_STATE_DOWN) || 
			    (node_base_state == NODE_STATE_DRAINED) || 
			    (node_base_state == NODE_STATE_DRAINING)) {
				pa_system_ptr->grid[x].color = 0;
				pa_system_ptr->grid[x].letter = '#';
				if(_initialized) {
					pa_set_node_down(
						&pa_system_ptr->grid[x]);
				}
			} else {
				pa_system_ptr->grid[x].color = 7;
				pa_system_ptr->grid[x].letter = '.';
			}
			pa_system_ptr->grid[x].state = node_ptr->node_state;
		} else {
			pa_system_ptr->grid[x].color = 7;
			pa_system_ptr->grid[x].letter = '.';
			pa_system_ptr->grid[x].state = 
				NODE_STATE_IDLE;
		}
		pa_system_ptr->grid[x].indecies = i++;
	}
#endif
	return;
}

extern int *find_bp_loc(char* bp_id)
{
#ifdef HAVE_BGL_FILES
	pa_bp_map_t *bp_map = NULL;
	ListIterator itr;
	
	if(!bp_map_list) {
		if(set_bp_map() == -1)
			return NULL;
	}
	itr = list_iterator_create(bp_map_list);
	while ((bp_map = list_next(itr)) != NULL)
		if (!strcmp(bp_map->bp_id, bp_id)) 
			break;	/* we found it */
	
	list_iterator_destroy(itr);
	if(bp_map != NULL)
		return bp_map->coord;
	else
		return NULL;

#else
	return NULL;
#endif
}

extern char *find_bp_rack_mid(char* xyz)
{
#ifdef HAVE_BGL_FILES
	pa_bp_map_t *bp_map = NULL;
	ListIterator itr;
	int number;
	int coord[PA_SYSTEM_DIMENSIONS];
	int len = strlen(xyz);
	len -= 3;
	if(len<0)
		return NULL;
	number = atoi(&xyz[X]+len);
	coord[X] = number / 100;
	coord[Y] = (number % 100) / 10;
	coord[Z] = (number % 10);
	if(!bp_map_list) {
		if(set_bp_map() == -1)
			return NULL;
	}
	
	itr = list_iterator_create(bp_map_list);
	while ((bp_map = list_next(itr)) != NULL)
		if (bp_map->coord[X] == coord[X] &&
		    bp_map->coord[Y] == coord[Y] &&
		    bp_map->coord[Z] == coord[Z]) 
			break;	/* we found it */
	
	list_iterator_destroy(itr);
	if(bp_map != NULL)
		return bp_map->bp_id;
	else
		return NULL;

#else
	return NULL;
#endif
}

/********************* Local Functions *********************/

#ifdef HAVE_BGL_FILES
static void _bp_map_list_del(void *object)
{
	pa_bp_map_t *bp_map = (pa_bp_map_t *)object;
	
	if (bp_map) {
		xfree(bp_map);		
	}
}
#endif
#ifdef HAVE_BGL
static int _check_for_options(pa_request_t* pa_request) 
{

	int temp;
	int set=0;
	int *geo = NULL;
	ListIterator itr;

	if(pa_request->rotate) {
	rotate_again:
		debug2("Rotating! %d",pa_request->rotate_count);
		
		if (pa_request->rotate_count==(PA_SYSTEM_DIMENSIONS-1)) {
			temp=pa_request->geometry[X];
			pa_request->geometry[X]=pa_request->geometry[Z];
			pa_request->geometry[Z]=temp;
			pa_request->rotate_count++;
			set=1;
		
		} else if(pa_request->rotate_count<(PA_SYSTEM_DIMENSIONS*2)) {
			temp=pa_request->geometry[X];
			pa_request->geometry[X]=pa_request->geometry[Y];
			pa_request->geometry[Y]=pa_request->geometry[Z];
			pa_request->geometry[Z]=temp;
			pa_request->rotate_count++;
			set=1;
		} else 
			pa_request->rotate = false;
		if(set) {
			if(pa_request->geometry[X]<=DIM_SIZE[X] 
			   && pa_request->geometry[Y]<=DIM_SIZE[Y]
			   && pa_request->geometry[Z]<=DIM_SIZE[Z])
				return 1;
			else {
				set = 0;
				goto rotate_again;
			}
		}
	}
	if(pa_request->elongate) {
	elongate_again:
		debug2("Elongating! %d",pa_request->elongate_count);
		pa_request->rotate_count=0;
		pa_request->rotate = true;
		
		set = 0;
		itr = list_iterator_create(pa_request->elongate_geos);
		for(set=0; set<=pa_request->elongate_count; set++)
			geo = list_next(itr);
		list_iterator_destroy(itr);
		if(geo == NULL)
			return 0;
		pa_request->elongate_count++;
		pa_request->geometry[X] = geo[X];
		pa_request->geometry[Y] = geo[Y];
		pa_request->geometry[Z] = geo[Z];
		if(pa_request->geometry[X]<=DIM_SIZE[X] 
		   && pa_request->geometry[Y]<=DIM_SIZE[Y]
		   && pa_request->geometry[Z]<=DIM_SIZE[Z]) {
			return 1;
		} else 				
			goto elongate_again;
		
	}
	return 0;
}

static int _append_geo(int *geometry, List geos, int rotate) 
{
	ListIterator itr;
	int *geo_ptr = NULL;
	int *geo = NULL;
	int temp_geo;
	int i, j;
	geo = xmalloc(sizeof(int)*3);
	if(rotate) {
		for (i = (PA_SYSTEM_DIMENSIONS - 1); i >= 0; i--) {
			for (j = 1; j <= i; j++) {
				if (geometry[j-1] > geometry[j]) {
					temp_geo = geometry[j-1];
					geometry[j-1] = geometry[j];
					geometry[j] = temp_geo;
				}
			}
		}
	}
	itr = list_iterator_create(geos);
	while ((geo_ptr = list_next(itr)) != NULL) {
		if(geometry[X] == geo_ptr[X]
		   && geometry[Y] == geo_ptr[Y]
		   && geometry[Z] == geo_ptr[Z])
			break;
		
	}
	list_iterator_destroy(itr);
	
	if(geo_ptr == NULL) { 
		geo[X] = geometry[X];
		geo[Y] = geometry[Y];
		geo[Z] = geometry[Z];
		list_append(geos, geo);
	}
	return 1;
}

static int _fill_in_coords(List results, List start_list,
			    int *geometry, int conn_type)
{
	pa_node_t *pa_node = NULL;
	pa_node_t *check_node = NULL;
	int rc = 1;
	ListIterator itr = NULL;
	int y=0, z=0, j;
	pa_switch_t *curr_switch = NULL; 
	pa_switch_t *next_switch = NULL; 
	
	if(!start_list)
		return 0;
	itr = list_iterator_create(start_list);
	while(check_node = (pa_node_t*) list_next(itr)) {		
		curr_switch = &check_node->axis_switch[X];
	
		for(y=0; y<geometry[Y]; y++) {
			if((check_node->coord[Y]+y) 
			   >= DIM_SIZE[Y]) {
				rc = 0;
				goto failed;
			}
			for(z=0; z<geometry[Z]; z++) {
				if((check_node->coord[Z]+z) 
				   >= DIM_SIZE[Z]) {
					rc = 0;
					goto failed;
				}
				pa_node = &pa_system_ptr->grid
					[check_node->coord[X]]
					[check_node->coord[Y]+y]
					[check_node->coord[Z]+z];
				if(pa_node->coord[Y] 
				   == check_node->coord[Y]
				   && pa_node->coord[Z] 
				   == check_node->coord[Z])
					continue;
				if (!_node_used(pa_node,geometry)) {
					debug2("here Adding %d%d%d",
					       pa_node->coord[X],
					       pa_node->coord[Y],
					       pa_node->coord[Z]);
					list_append(results, pa_node);
					next_switch = &pa_node->axis_switch[X];
					_copy_the_path(curr_switch, 
						       next_switch, 
						       pa_node->coord[X],
						       0);
				} else {
					rc = 0;
					goto failed;
				}
			}
		}
		
	}
	list_iterator_destroy(itr);
	itr = list_iterator_create(start_list);
	check_node = (pa_node_t*) list_next(itr);
	list_iterator_destroy(itr);
	
	itr = list_iterator_create(results);
	while(pa_node = (pa_node_t*) list_next(itr)) {	
		if(!_find_yz_path(pa_node, 
				  check_node->coord, 
				  geometry, 
				  conn_type)){
			rc = 0;
			goto failed;
		}
	}
failed:
	list_iterator_destroy(itr);				
				
	return rc;
}

static int _reset_the_path(pa_switch_t *curr_switch, int source, 
			   int target, int dim)
{
	int *node_tar;
	int *node_curr;
	int port_tar, port_tar1;
	pa_switch_t *next_switch = NULL; 
	/*set the switch to not be used */
		
	curr_switch->int_wire[source].used = 0;
	port_tar = curr_switch->int_wire[source].port_tar;
	port_tar1 = port_tar;
	curr_switch->int_wire[source].port_tar = source;
	curr_switch->int_wire[port_tar].used = 0;
	curr_switch->int_wire[port_tar].port_tar = port_tar;
	if(port_tar==target) {
		return 1;
	}
	/* follow the path */
	node_curr = curr_switch->ext_wire[0].node_tar;
	node_tar = curr_switch->ext_wire[port_tar].node_tar;
	port_tar = curr_switch->ext_wire[port_tar].port_tar;
	debug2("from %d%d%d %d %d -> %d%d%d %d",
	       node_curr[X],
	       node_curr[Y],
	       node_curr[Z],
	       source,
	       port_tar1,
	       node_tar[X],
	       node_tar[Y],
	       node_tar[Z],
	       port_tar);
	if(node_curr[X] == node_tar[X]
	   && node_curr[Y] == node_tar[Y]
	   && node_curr[Z] == node_tar[Z]) {
		debug2("%d something bad happened!!", dim);
		return 0;
	}
	next_switch = &pa_system_ptr->
		grid[node_tar[X]]
#ifdef HAVE_BGL
		[node_tar[Y]]
		[node_tar[Z]]
#endif
		.axis_switch[dim];

	_reset_the_path(next_switch, port_tar, target, dim);
	return 1;
}

static int _copy_the_path(pa_switch_t *curr_switch, pa_switch_t *mark_switch, 
			  int start, int source)
{
	int *node_tar;
	int *mark_node_tar;
	int *node_curr;
	int port_tar, port_tar1;
	pa_switch_t *next_switch = NULL; 
	pa_switch_t *next_mark_switch = NULL; 
	/*set the switch to not be used */
		
	mark_switch->int_wire[source].used = 
		curr_switch->int_wire[source].used;
	mark_switch->int_wire[source].port_tar = 
		curr_switch->int_wire[source].port_tar;

	port_tar = curr_switch->int_wire[source].port_tar;
	
	mark_switch->int_wire[port_tar].used = 
		curr_switch->int_wire[port_tar].used;
	mark_switch->int_wire[port_tar].port_tar = 
		curr_switch->int_wire[port_tar].port_tar;
	port_tar1 = port_tar;
	
	/* follow the path */
	node_curr = curr_switch->ext_wire[0].node_tar;
	if(port_tar == 1) {
		mark_switch->int_wire[1].used = 
			curr_switch->int_wire[1].used;
		mark_switch->int_wire[1].port_tar = 
			curr_switch->int_wire[1].port_tar;
		return 1;
	}

	node_tar = curr_switch->ext_wire[port_tar].node_tar;
	mark_node_tar = mark_switch->ext_wire[port_tar].node_tar;
	port_tar = curr_switch->ext_wire[port_tar].port_tar;
	
	if(node_curr[X] == node_tar[X]
	   && node_curr[Y] == node_tar[Y]
	   && node_curr[Z] == node_tar[Z]) {
		debug2("something bad happened!!");
		return 0;
	}
	next_switch = &pa_system_ptr->
		grid[node_tar[X]]
#ifdef HAVE_BGL
		[node_tar[Y]]
		[node_tar[Z]]
#endif
		.axis_switch[X];
	next_mark_switch = &pa_system_ptr->
		grid[mark_node_tar[X]]
#ifdef HAVE_BGL
		[mark_node_tar[Y]]
		[mark_node_tar[Z]]
#endif
		.axis_switch[X];

	_copy_the_path(next_switch, next_mark_switch, start, port_tar);
	return 1;
}

static int _find_yz_path(pa_node_t *pa_node, int *first, 
			 int *geometry, int conn_type)
{
	pa_node_t *next_node = NULL;
	int *node_tar = NULL;
	pa_switch_t *dim_curr_switch = NULL; 
	pa_switch_t *dim_next_switch = NULL; 
	int i2;
	int count = 0;

	for(i2=1;i2<=2;i2++) {
		if(geometry[i2] > 1) {
			debug("%d node %d%d%d"
			       " port 2 -> ",
			       i2,
			       pa_node->coord[X],
			       pa_node->coord[Y],
			       pa_node->coord[Z]);
							       
			dim_curr_switch = 
				&pa_node->
				axis_switch[i2];
			if(dim_curr_switch->int_wire[2].used) {
				debug2("returning here");
				return 0;
			}
							
			node_tar = dim_curr_switch->
				ext_wire[2].node_tar;
							
			next_node = &pa_system_ptr->
				grid[node_tar[X]][node_tar[Y]][node_tar[Z]];
			dim_next_switch = &next_node->axis_switch[i2];
			debug("%d%d%d port 5",
			       next_node->coord[X],
			       next_node->coord[Y],
			       next_node->coord[Z]);
							  
			if(dim_next_switch->int_wire[5].used) {
				debug2("returning here 2");
				return 0;
			}
			debug3("%d %d %d %d",i2, node_tar[i2],
			       first[i2], geometry[i2]);
			if(node_tar[i2] < first[i2])
				count = DIM_SIZE[i2]-first[i2]+node_tar[i2];
			else
				count = node_tar[i2]+first[i2];
			if((count) == (geometry[i2])) {
				debug3("found end of me %d%d%d",
				       node_tar[X],
				       node_tar[Y],
				       node_tar[Z]);
				if(conn_type == TORUS) {
					dim_curr_switch->
						int_wire[0].used = 1;
					dim_curr_switch->
						int_wire[0].port_tar
						= 2;
					dim_curr_switch->
						int_wire[2].used
						= 1;
					dim_curr_switch->
						int_wire[2].
						port_tar = 0;
					dim_curr_switch = dim_next_switch;
									
					while(node_tar[i2] != first[i2]) {
						debug2("on dim %d at %d "
						       "looking for %d",
						       i2,
						       node_tar[i2],
						       first[i2]);
						
						if(dim_curr_switch->
						   int_wire[2].used) {
							debug2("returning "
							       "here 3");
							return 0;
						} 
						dim_curr_switch->
							int_wire[2].used = 1;
						dim_curr_switch->
							int_wire[2].port_tar
							= 5;
						dim_curr_switch->
							int_wire[5].used
							= 1;
						dim_curr_switch->
							int_wire[5].
							port_tar = 2;
						
						
						node_tar = dim_curr_switch->
							ext_wire[2].node_tar;
						next_node = &pa_system_ptr->
							grid
							[node_tar[X]]
							[node_tar[Y]]
							[node_tar[Z]];
						dim_curr_switch = 
							&next_node->
							axis_switch[i2];
					}
									
					debug2("back to first on dim %d "
					       "at %d looking for %d",
					       i2,
					       node_tar[i2],
					       first[i2]);
									
					dim_curr_switch->
						int_wire[5].used = 1;
					dim_curr_switch->
						int_wire[5].port_tar
						= 1;
					dim_curr_switch->
						int_wire[1].used
						= 1;
					dim_curr_switch->
						int_wire[1].
						port_tar = 5;
				}
								
			} else {
				if(conn_type == TORUS || 
				   (conn_type == MESH && 
				    (node_tar[i2] != first[i2]))) {
					dim_curr_switch->
						int_wire[0].used = 1;
					dim_curr_switch->
						int_wire[0].port_tar
						= 2;
					dim_curr_switch->
						int_wire[2].used
						= 1;
					dim_curr_switch->
						int_wire[2].
						port_tar = 0;
								
					dim_next_switch->int_wire[5].used
						= 1;
					dim_next_switch->
						int_wire[5].port_tar
						= 1;
					dim_next_switch->
						int_wire[1].used = 1;
					dim_next_switch->
						int_wire[1].port_tar
						= 5;
				}
			}
		}
	}
	return 1;
}
#endif

/** */
#ifdef HAVE_BGL
static int _create_config_even(pa_node_t ***grid)
#else
static int _create_config_even(pa_node_t *grid)
#endif
{
	int x;
	pa_node_t *source = NULL, *target = NULL;

#ifdef HAVE_BGL
	int y,z;

	for(x=0;x<DIM_SIZE[X];x++) {
		for(y=0;y<DIM_SIZE[Y];y++) {
			for(z=0;z<DIM_SIZE[Z];z++) {
				source = &grid[x][y][z];
				
				if(x<(DIM_SIZE[X]-1)) {
					target = &grid[x+1][y][z];
				} else
					target = &grid[0][y][z];

				_set_external_wires(X, x, source, 
						    target);
				
				if(y<(DIM_SIZE[Y]-1)) 
					target = &grid[x][y+1][z];
				else 
					target = &grid[x][0][z];
				
				_set_external_wires(Y, y, source, 
						    target);
				if(z<(DIM_SIZE[Z]-1)) 
					target = &grid[x][y][z+1];
				else 
					target = &grid[x][y][0];
				
				_set_external_wires(Z, z, source, 
						    target);
			}
		}
	}
#else
	for(x=0;x<DIM_SIZE[X];x++) {
		source = &grid[x];
				
		target = &grid[x+1];
		
		_set_external_wires(X, x, source, 
				    target);
	}
#endif
	return 1;
}

/** */
extern int set_bp_map(void)
{
#ifdef HAVE_BGL_FILES
	static rm_BGL_t *bgl = NULL;
	int rc;
	rm_BP_t *my_bp = NULL;
	pa_bp_map_t *bp_map = NULL;
	int bp_num, i;
	char *bp_id = NULL;
	rm_location_t bp_loc;

	bp_map_list = list_create(_bp_map_list_del);

	if (!have_db2) {
		error("Can't access DB2 library, run from service node");
		return -1;
	}

	if (!getenv("DB2INSTANCE") || !getenv("VWSPATH")) {
		error("Missing DB2INSTANCE or VWSPATH env var."
			"Execute 'db2profile'");
		return -1;
	}
	
	if ((rc = rm_set_serial(BGL_SERIAL)) != STATUS_OK) {
		error("rm_set_serial(): %d", rc);
		return -1;
	}
	
	if ((rc = rm_get_BGL(&bgl)) != STATUS_OK) {
		error("rm_get_BGL(): %d", rc);
		return -1;
	}
	if ((rc = rm_get_data(bgl, RM_BPNum, &bp_num)) != STATUS_OK) {
		error("rm_get_data(RM_BPNum): %d", rc);
		bp_num = 0;
	}

	for (i=0; i<bp_num; i++) {

		if (i) {
			if ((rc = rm_get_data(bgl, RM_NextBP, &my_bp))
			    != STATUS_OK) {
				error("rm_get_data(RM_NextBP): %d", rc);
				break;
			}
		} else {
			if ((rc = rm_get_data(bgl, RM_FirstBP, &my_bp))
			    != STATUS_OK) {
				error("rm_get_data(RM_FirstBP): %d", rc);
				break;
			}
		}
		
		bp_map = (pa_bp_map_t *) xmalloc(sizeof(pa_bp_map_t));
		
		if ((rc = rm_get_data(my_bp, RM_BPID, &bp_id))
		    != STATUS_OK) {
			xfree(bp_map);
			error("rm_get_data(RM_BPID): %d", rc);
			continue;
		}
		
		if ((rc = rm_get_data(my_bp, RM_BPLoc, &bp_loc))
		    != STATUS_OK) {
			xfree(bp_map);
			error("rm_get_data(RM_BPLoc): %d", rc);
			continue;
		}
		
		bp_map->bp_id = strdup(bp_id);
		bp_map->coord[X] = bp_loc.X;
		bp_map->coord[Y] = bp_loc.Y;
		bp_map->coord[Z] = bp_loc.Z;
		
		list_push(bp_map_list, bp_map);
		
	}
	if ((rc = rm_free_BGL(bgl)) != STATUS_OK)
		error("rm_free_BGL(): %s", rc);

#endif
	return 1;
	
}

static void _new_pa_node(pa_node_t *pa_node, int *coord)
{
	int i,j;
	pa_node->used = false;
	
	for (i=0; i<PA_SYSTEM_DIMENSIONS; i++){
		pa_node->coord[i] = coord[i];
		
		for(j=0;j<NUM_PORTS_PER_NODE;j++) {
			pa_node->axis_switch[i].int_wire[j].used = 0;	
			if(i!=X) {
				if(j==3 || j==4) 
					pa_node->axis_switch[i].int_wire[j].
						used = 1;	
			}
			pa_node->axis_switch[i].int_wire[j].port_tar = j;
		}
	}
}

static void _create_pa_system(void)
{
	int x;
	int coord[PA_SYSTEM_DIMENSIONS];
				
#ifdef HAVE_BGL
	int y,z;
	pa_system_ptr->grid = (pa_node_t***) 
		xmalloc(sizeof(pa_node_t**) * DIM_SIZE[X]);
#else
	pa_system_ptr->grid = (pa_node_t*) 
		xmalloc(sizeof(pa_node_t) * DIM_SIZE[X]);
#endif
	for (x=0; x<DIM_SIZE[X]; x++) {
#ifdef HAVE_BGL
		pa_system_ptr->grid[x] = (pa_node_t**) 
			xmalloc(sizeof(pa_node_t*) * DIM_SIZE[Y]);
		for (y=0; y<DIM_SIZE[Y]; y++) {
			pa_system_ptr->grid[x][y] = (pa_node_t*) 
				xmalloc(sizeof(pa_node_t) * DIM_SIZE[Z]);
			for (z=0; z<DIM_SIZE[Z]; z++){
				coord[X] = x;
				coord[Y] = y;
				coord[Z] = z;
				_new_pa_node(&pa_system_ptr->grid[x][y][z], 
					     coord);
			}
		}
#else
		coord[X] = x;
		_new_pa_node(&pa_system_ptr->grid[x], coord);
#endif
	}
}

/** */
static void _delete_pa_system(void)
{
#ifdef HAVE_BGL
	int x=0;
	int y;
#endif
	if (!pa_system_ptr){
		return;
	}
	
	if(pa_system_ptr->grid) {
#ifdef HAVE_BGL
		for (x=0; x<DIM_SIZE[X]; x++) {
			for (y=0; y<DIM_SIZE[Y]; y++)
				xfree(pa_system_ptr->grid[x][y]);
			
			xfree(pa_system_ptr->grid[x]);
		}
#endif
		
		
		xfree(pa_system_ptr->grid);
	}
	xfree(pa_system_ptr);
}

static void _delete_path_list(void *object)
{
	pa_path_switch_t *path_switch = (pa_path_switch_t *)object;

	if (path_switch) {
		xfree(path_switch);
	}
	return;
}
/** 
 * algorithm for finding match
 */
/* static int _find_match(pa_request_t *pa_request, List results) */
/* { */
/* 	int x=0; */
/* 	int *geometry = pa_request->geometry; */
/* #ifdef HAVE_BGL */
/* 	int y=0, z=0; */
/* 	int start[PA_SYSTEM_DIMENSIONS] = {0,0,0}; */
/* 	int find[PA_SYSTEM_DIMENSIONS] = {0,0,0}; */
/* #else */
/* 	int find[PA_SYSTEM_DIMENSIONS] = {0}; */
/* #endif */
/* 	pa_node_t* pa_node = NULL; */
/* 	int found_one=0; */
/* 	char *name=NULL; */

/* #ifdef HAVE_BGL */
/* 	if(geometry[X]>DIM_SIZE[X]  */
/* 	   || geometry[Y]>DIM_SIZE[Y] */
/* 	   || geometry[Z]>DIM_SIZE[Z]) */
/* 		if(!_check_for_options(pa_request)) */
/* 			return 0; */
/* start_again: */
	
/* 	for (x=0; x<geometry[X]; x++) { */
/* 		for (y=0; y<geometry[Y]; y++) {			 */
/* 			for (z=0; z<geometry[Z]; z++) { */
				
/* 				pa_node = &pa_system_ptr-> */
/* 					grid[find[X]][find[Y]][find[Z]]; */
/* 				if (!_node_used(pa_node,geometry)) { */
/* 					list_append(results, pa_node); */
/* 					find[Z]++; */
/* 					found_one=1; */
/* 				} else { */
/* 					if(found_one) { */
/* 						list_destroy(results); */
/* 						results = list_create(NULL); */
/* 						found_one=0; */
/* 					} */
/* 					if((DIM_SIZE[Z]-find[Z]-1) */
/* 					   >= geometry[Z]) { */
/* 						find[Z]++; */
/* 						start[Z]=find[Z]; */
/* 					} else { */
/* 						find[Z]=0; */
/* 						start[Z]=find[Z]; */
/* 						if((DIM_SIZE[Y]-find[Y]-1) */
/* 						   >= geometry[Y]) { */
/* 							find[Y]++; */
/* 							start[Y]=find[Y]; */
/* 						} else { */
/* 							find[Y]=0; */
/* 							start[Y]=find[Y]; */

/* 							if ((DIM_SIZE[X] */
/* 							     - find[X]-1) */
/* 							    >= geometry[X]) { */
/* 								find[X]++; */
/* 								start[X] = find[X]; */
/* 							} else { */
/* 								if(!_check_for_options(pa_request)) */
/* 									return 0; */
/* 								else { */
/* 									find[X]=0; */
/* 									find[Y]=0; */
/* 									find[Z]=0; */
/* 									start[X]=0; */
/* 									start[Y]=0; */
/* 									start[Z]=0; */
/* 									goto start_again; */
/* 								} */
/* 							} */
/* 						} */
/* 					} */
/* 					goto start_again; */
/* 				}		 */
/* 			} */
/* 			find[Z]=start[Z]; */
/* 			if(y<(geometry[Y]-1)) { */
/* 				if(find[Y]<(DIM_SIZE[Y]-1)) { */
/* 					find[Y]++; */
/* 				} else { */
/* 					if(!_check_for_options(pa_request)) */
/* 						return 0; */
/* 					else { */
/* 						find[X]=0; */
/* 						find[Y]=0; */
/* 						find[Z]=0; */
/* 						start[X]=0; */
/* 						start[Y]=0; */
/* 						start[Z]=0; */
/* 						goto start_again; */
/* 					} */
/* 				} */
/* 			} */
/* 		} */
/* 		find[Y]=start[Y]; */
/* 		if(x<(geometry[X]-1)) { */
/* 			if(find[X]<(DIM_SIZE[X]-1)) { */
/* 				find[X]++; */
/* 			} else { */
/* 				if(!_check_for_options(pa_request)) */
/* 					return 0; */
/* 				else { */
/* 					find[X]=0; */
/* 					find[Y]=0; */
/* 					find[Z]=0; */
/* 					start[X]=0; */
/* 					start[Y]=0; */
/* 					start[Z]=0; */
/* 					goto start_again; */
/* 				} */
/* 			} */
/* 		} */
/* 	} */

/* 	if(found_one) { */
/* 		if(pa_request->conn_type==TORUS) */
/* 			name = _set_internal_wires(results,  */
/* 						   pa_request->size,  */
/* 						   TORUS); */
/* 		else */
/* 			name = _set_internal_wires(results,  */
/* 						   pa_request->size,  */
/* 						   MESH); */
		
/* 		if(name!=NULL) { */
/* 			debug("name = %s", name); */
/* 			pa_request->save_name = name; */
/* 		 } else */
/* 			return 0; */
/* 	} else { */
/* 		debug("couldn't find it 2"); */
/* 		return 0; */
/* 	} */

/* #else */
/* start_again: */
	
/* 	for (x=0; x<geometry[X]; x++) { */
/* 		pa_node = &pa_system_ptr->grid[find[X]]; */
/* 		if (!_node_used(pa_node,geometry)) { */
/* 			list_append(results, pa_node); */
/* 			find[X]++; */
/* 			found_one=1; */
/* 		} else { */
/* 			if(found_one) { */
/* 				list_destroy(results); */
/* 				results = list_create(NULL); */
/* 				found_one=0; */
/* 			} */
			
/* 			if ((DIM_SIZE[X]-find[X]-1)>=geometry[X]) { */
/* 				find[X]++; */
/* 			} else */
/* 				break; */
/* 			goto start_again; */
/* 		}		 */
/* 	} */
	
/* 	if(found_one) { */
/* 		if(pa_request->conn_type==TORUS) */
/* 			name = _set_internal_wires(results,  */
/* 						   pa_request->size,  */
/* 						   TORUS); */
/* 		else */
/* 			name = _set_internal_wires(results,  */
/* 						   pa_request->size,  */
/* 						   MESH); */
		
/* 		if(name!=NULL) */
/* 			pa_request->save_name = name; */
/* 		else */
/* 			return 0; */
/* 	} else { */
/* 		debug("couldn't find it 2"); */
/* 		return 0; */
/* 	} */

/* #endif */
/* 	return 1; */
/* } */

/** 
 * algorithm for finding match
 */
static int _find_match(pa_request_t *pa_request, List results)
{
	int x=0;
#ifdef HAVE_BGL
	int start[PA_SYSTEM_DIMENSIONS] = {0,0,0};
#else
	int start[PA_SYSTEM_DIMENSIONS] = {0};
#endif
	pa_node_t *pa_node = NULL;
	char *name=NULL;

#ifdef HAVE_BGL
	if(pa_request->geometry[X]>DIM_SIZE[X] 
	   || pa_request->geometry[Y]>DIM_SIZE[Y]
	   || pa_request->geometry[Z]>DIM_SIZE[Z])
		if(!_check_for_options(pa_request))
			return 0;
#endif

start_again:
	for (x=0; x<DIM_SIZE[X]; x++) {	
		debug3("finding %d%d%d try %d",
		       pa_request->geometry[X],
		       pa_request->geometry[Y],
		       pa_request->geometry[Z],
		       x);
	new_node:
		debug("starting at %d%d%d",
		     start[X],
		     start[Y],
		     start[Z]);
					
		pa_node = &pa_system_ptr->
			grid[start[X]]
#ifdef HAVE_BGL
			[start[Y]]
			[start[Z]]
#endif
			;
		if (!_node_used(pa_node, pa_request->geometry)) {
			name = set_bgl_part(results,
					    start, 
					    pa_request->geometry, 
					    pa_request->conn_type);
			if(name) {
				pa_request->save_name = xstrdup(name);
				xfree(name);
				return 1;
			}
			//exit(0);
			debug("trying something else");
			remove_part(results, color_count);
			list_destroy(results);
			results = list_create(NULL);
		}
#ifdef HAVE_BGL
		if((DIM_SIZE[Z]-start[Z])
		   >= pa_request->geometry[Z])
			start[Z]++;
		else {
			start[Z] = 0;
			if((DIM_SIZE[Y]-start[Y])
			   >= pa_request->geometry[Y])
				start[Y]++;
			else {
				start[Y] = 0;
				if ((DIM_SIZE[X]-start[X])
				    >= pa_request->geometry[X])
					start[X]++;
				else {
					if(!_check_for_options(pa_request))
						return 0;
					else {
						start[X]=0;
						start[Y]=0;
						start[Z]=0;
						goto start_again;
					}
				}
			}
		}
		goto new_node;
#endif
	}							
	
	error("can't allocate");
	
	return 0;
}

/* bool _node_used(pa_node_t* pa_node, int geometry,  */
static bool _node_used(pa_node_t* pa_node, int *geometry)
{
	int i=0;
	pa_switch_t* pa_switch = NULL;
	
	/* if we've used this node in another partition already */
	if (!pa_node || pa_node->used) {
		debug3("node used");
		return true;
	}
	/* if we've used this nodes switches completely in another 
	   partition already */
	for(i=0;i<1;i++) {
		if(geometry[i]>1) {
			pa_switch = &pa_node->axis_switch[i];
			
			if(pa_switch->int_wire[3].used 
			   && pa_switch->int_wire[5].used) {
				debug3("switch in use dim %d!",i);
				return true;
			}
		}
	}
		
	return false;

}


static void _switch_config(pa_node_t* source, pa_node_t* target, int dim, 
			   int port_src, int port_tar)
{
	pa_switch_t* config = NULL, *config_tar = NULL;
	int i;

	if (!source || !target)
		return;
	
	config = &source->axis_switch[dim];
	config_tar = &target->axis_switch[dim];
	for(i=0;i<PA_SYSTEM_DIMENSIONS;i++) {
		/* Set the coord of the source target node to the target */
		config->ext_wire[port_src].node_tar[i] = target->coord[i];
	
		/* Set the coord of the target back to the source */
		config_tar->ext_wire[port_tar].node_tar[i] = source->coord[i];
	}

	/* Set the port of the source target node to the target */
	config->ext_wire[port_src].port_tar = port_tar;
	
	/* Set the port of the target back to the source */
	config_tar->ext_wire[port_tar].port_tar = port_src;
}

static void _set_external_wires(int dim, int count, pa_node_t* source, 
		pa_node_t* target)
{
	
	_switch_config(source, source, dim, 0, 0);
	_switch_config(source, source, dim, 1, 1);
	if(dim!=X) {
		_switch_config(source, target, dim, 2, 5);
		_switch_config(source, source, dim, 3, 3);
		_switch_config(source, source, dim, 4, 4);
		return;
	}
#ifdef HAVE_BGL

	/* always 2->5 of next. If it is the last 
		   it will go to the first.*/
		
	_switch_config(source, target, dim, 2, 5);
	if(count == 0 || count==4) {
		/* 0 and 4th Node */
		/* 3->4 of next */
		_switch_config(source, target, dim, 3, 4);
		/* 4 is not in use */
		_switch_config(source, source, dim, 4, 4);
	} else if( count == 1 || count == 5) {
		/* 1st and 5th Node */
		/* 3 is not in use */
		_switch_config(source, source, dim, 3, 3);
	} else if(count == 2) {
		/* 2nd Node */
		/* make sure target is the last node */
		target = &pa_system_ptr->grid[DIM_SIZE[X]-1]
			[source->coord[Y]]
			[source->coord[Z]];
		/* 3->4 of last */
		_switch_config(source, target, dim, 3, 4);
		/* 4->3 of last */
		_switch_config(source, target, dim, 4, 3);
	} else if(count == 3) {
		/* 3rd Node */
		/* make sure target is the next to last node */
		target = &pa_system_ptr->grid[DIM_SIZE[X]-2]
			[source->coord[Y]]
			[source->coord[Z]];
		/* 3->4 of next to last */ 
		_switch_config(source, target, dim, 3, 4);
		/* 4->3 of next to last */
		_switch_config(source, target, dim, 4, 3);
	}

	if(DIM_SIZE[X] <= 4) {
		/* 4 X dim fixes for wires */
		
		if(count == 2) {
			/* 2 not in use */		
			_switch_config(source, source, dim, 2, 2);
		} else if(count == 3) {
			/* 5 not in use */
			_switch_config(source, source, dim, 5, 5);
		}
	} else if(DIM_SIZE[X] != 8) {
		fatal("Do don't have a config to do this BGL system.");
	}
#else
	if(count == 0)
		_switch_config(source, source, dim, 5, 5);
	else if(count < DIM_SIZE[X]-1) 
		_switch_config(source, target, dim, 2, 5);
	else
		_switch_config(source, source, dim, 2, 2);		
	_switch_config(source, source, dim, 3, 3);
	_switch_config(source, source, dim, 4, 4);
#endif

}

/* static char *_set_internal_wires(List nodes, int size, int conn_type) */
/* { */
/* 	pa_node_t* pa_node[size+1]; */
/* 	int count=0, i, set=0; */
/* 	int *start = NULL; */
/* 	int *end = NULL; */
/* 	char *name = (char *) xmalloc(sizeof(char)*8); */
/* 	ListIterator itr; */

/* 	memset(name,0,8);		 */
/* 	itr = list_iterator_create(nodes); */
/* 	while((pa_node[count] = (pa_node_t*) list_next(itr))) { */
/* 		count++; */
/* 	} */
/* 	list_iterator_destroy(itr); */
		
/* 	start = pa_node[0]->coord; */
/* 	end = pa_node[count-1]->coord;	 */
/* #ifdef HAVE_BGL */
/* 	sprintf(name, "%d%d%dx%d%d%d",start[X],start[Y],start[Z], */
/* 		end[X],end[Y],end[Z]); */
/* #else */
/* 	sprintf(name, "%d-%d", start[X], end[X]); */
/* #endif */
/* 	for(i=0;i<count;i++) { */
/* 		if(!pa_node[i]->used) { */
/* 			if(size!=1)  */
/* 				if(!_configure_dims(pa_node[i]->coord,  */
/* 						    nodes, start, end,  */
/* 						    conn_type)) { */
/* 					error("No network connection to " */
/* 					      "create bglblock " */
/* 					      "containing bgl[%s]", name); */
/* 					error("Use smap to define bglblocks " */
/* 					      "in bluegene.conf"); */
/* 					xfree(name); */
/* 					return 0; */
/* 				} */
				
/* 			pa_node[i]->used=1; */
/* 			pa_node[i]->conn_type=conn_type; */
/* 			if(pa_node[i]->letter == '.') { */
/* 				pa_node[i]->letter = letters[color_count%62]; */
/* 				pa_node[i]->color = colors[color_count%6]; */
				
/* 				set=1; */
/* 			} */
/* 		} else { */
/* 			error("No network connection to create bglblock " */
/* 			      "containing bgl[%s]", name); */
/* 			error("Use smap to define bglblocks in bluegene.conf"); */
/* 			xfree(name); */
/* 			return NULL; */
/* 		} */
/* 	} */

/* 	if(conn_type == TORUS) */
/* 		for(i=0;i<count;i++) { */
/* 			_set_one_dim(start, end, pa_node[i]->coord); */
/* 		} */

/* 	if(set) */
/* 		color_count++;		 */

/* 	return name; */
/* } */
				
static char *_set_internal_wires(List nodes, int size, int conn_type)
{
	pa_node_t* pa_node[size+1];
	int count=0, i, set=0;
	int *start = NULL;
	int *end = NULL;
	char *name = xmalloc(sizeof(char)*BUFSIZE);
	ListIterator itr;
	hostlist_t hostlist = hostlist_create(NULL);
	
	if(!nodes)
		return NULL;
	itr = list_iterator_create(nodes);
	while((pa_node[count] = (pa_node_t*) list_next(itr))) {
		sprintf(name, "bgl%d%d%d\0", 
			pa_node[count]->coord[X],
			pa_node[count]->coord[Y],
			pa_node[count]->coord[Z]);
		debug3("name = %s",name);
		count++;
		hostlist_push(hostlist, name);
				
	}
	list_iterator_destroy(itr);
		
	start = pa_node[0]->coord;
	end = pa_node[count-1]->coord;	
	hostlist_ranged_string(hostlist, BUFSIZE, name);
	hostlist_destroy(hostlist);
	for(i=0;i<count;i++) {
		if(!pa_node[i]->used) {
			pa_node[i]->used=1;
			pa_node[i]->conn_type=conn_type;
			if(pa_node[i]->letter == '.') {
				pa_node[i]->letter = letters[color_count%62];
				pa_node[i]->color = colors[color_count%6];
				debug3("count %d setting letter = %c "
				       "color = %d",
				       color_count,
				       pa_node[i]->letter,
				       pa_node[i]->color);
				set=1;
			}
		} else {
			error("No network connection to create bglblock "
			      "containing bgl[%s]", name);
			error("Use smap to define bglblocks in bluegene.conf");
			xfree(name);
			return NULL;
		}
	}

	if(conn_type == TORUS)
		for(i=0;i<count;i++) {
			_set_one_dim(start, end, pa_node[i]->coord);
		}

	if(set)
		color_count++;		

	return name;
}				

/* static int _find_one_hop(pa_switch_t *curr_switch, int source_port,  */
/* 			  List nodes, int dim, int *diff)  */
/* { */
/* 	pa_switch_t *next_switch = NULL;  */
/* 	int port_tar; */
/* 	int target_port=0; */
/* 	int ports_to_try[2] = {3,5}; */
/* 	int *node_tar = NULL; */
/* 	int i; */
/* 	pa_node_t *pa_node = NULL; */
/* 	ListIterator itr; */

/* 	if(!curr_switch) */
/* 		return 0; */

/* 	if(!source_port) { */
/* 		target_port=1; */
/* 		ports_to_try[0] = 4; */
/* 		ports_to_try[1] = 2;			 */
/* 	} */
	
/* 	debug3("dim %d has %d", dim, diff[dim]); */
/* 	for(i=0;i<2;i++) { */
/* 		/\* check to make sure it isn't used *\/ */
/* 		if(!curr_switch->int_wire[ports_to_try[i]].used) { */
/* 			node_tar = curr_switch-> */
/* 				ext_wire[ports_to_try[i]].node_tar; */
/* 			debug2("looking at port %d going " */
/* 			       "to %d%d%d %d", */
/* 			       ports_to_try[i], */
/* 			       node_tar[X], */
/* 			       node_tar[Y], */
/* 			       node_tar[Z]); */
/* 			itr = list_iterator_create(nodes); */
/* 			while((pa_node = (pa_node_t*) list_next(itr))) { */
/* 				if(node_tar[X] != pa_node->coord[X]  */
/* #ifdef HAVE_BGL */
/* 				    || node_tar[Y] != pa_node->coord[Y]  */
/* 				    || node_tar[Z] != pa_node->coord[Z] */
/* #endif */
/* 					)  */
/* 					continue; */
/* 				next_switch = &pa_system_ptr-> */
/* 					grid[node_tar[X]] */
/* #ifdef HAVE_BGL */
/* 					[node_tar[Y]] */
/* 					[node_tar[Z]] */
/* #endif */
/* 					.axis_switch[dim]; */
			

/* 				port_tar = curr_switch-> */
/* 					ext_wire[ports_to_try[i]]. */
/* 					port_tar; */
/* 				if(next_switch->int_wire[source_port].used  */
/* 				   && diff[dim] > 1) { */
					
/* 					debug2("%d%d%d %d  %d%d%d %d",  */
/* 					       next_switch-> */
/* 					       ext_wire[next_switch-> */
/* 							int_wire[source_port] */
/* 							.port_tar]. */
/* 					       node_tar[X], */
/* 					       next_switch-> */
/* 					       ext_wire[next_switch-> */
/* 							int_wire[source_port] */
/* 							.port_tar]. */
/* 					       node_tar[Y], */
/* 					       next_switch-> */
/* 					       ext_wire[next_switch-> */
/* 							int_wire[source_port] */
/* 							.port_tar]. */
/* 					       node_tar[Z],  */
/* 					       source_port, */
/* 					       curr_switch-> */
/* 					       ext_wire[target_port]. */
/* 					       node_tar[X], */
/* 					       curr_switch-> */
/* 					       ext_wire[target_port]. */
/* 					       node_tar[Y], */
/* 					       curr_switch-> */
/* 					       ext_wire[target_port]. */
/* 					       node_tar[Z], */
/* 					       target_port); */
/* 					if(next_switch-> */
/* 					   ext_wire[next_switch-> */
/* 						    int_wire[source_port] */
/* 						    .port_tar]. */
/* 					   node_tar[X] */
/* 					   == curr_switch-> */
/* 					   ext_wire[target_port]. */
/* 					   node_tar[X] */
/* 					   && next_switch-> */
/* 					   ext_wire[next_switch-> */
/* 						    int_wire[source_port] */
/* 						    .port_tar]. */
/* 					   node_tar[Y] */
/* 					   == curr_switch-> */
/* 					   ext_wire[target_port]. */
/* 					   node_tar[Y] */
/* 					   && next_switch-> */
/* 					   ext_wire[next_switch-> */
/* 						    int_wire[source_port] */
/* 						    .port_tar]. */
/* 					   node_tar[Z] */
/* 					   == curr_switch-> */
/* 					   ext_wire[target_port]. */
/* 					   node_tar[Z]) { */
/* 						list_delete(itr); */
/* 						continue; */
/* 					} */
				       
/* 				} */
				
				
/* 				if(!next_switch->int_wire[target_port].used) { */
/* 					debug2("found"); */
/* 					curr_switch-> */
/* 						int_wire[source_port].used = 1; */
/* 					curr_switch-> */
/* 						int_wire[source_port].port_tar  */
/* 						= ports_to_try[i]; */
/* 					curr_switch-> */
/* 						int_wire[ports_to_try[i]].used  */
/* 						= 1; */
/* 					curr_switch-> */
/* 						int_wire[ports_to_try[i]]. */
/* 						port_tar = source_port; */
					
/* 					next_switch->int_wire[port_tar].used  */
/* 						= 1; */
/* 					next_switch-> */
/* 						int_wire[port_tar].port_tar  */
/* 						= target_port; */
/* 					next_switch-> */
/* 						int_wire[target_port].used = 1; */
/* 					next_switch-> */
/* 						int_wire[target_port].port_tar  */
/* 						= port_tar; */
/* 					list_iterator_destroy(itr); */
/* 					return 1; */
/* 				}  */
/* 			} */
/* 			list_iterator_destroy(itr); */
/* 		} */
/* 	} */
/* 	debug("no good"); */
/* 	return 0; */
/* } */

static int _find_x_path(List results, pa_node_t *pa_node, 
			int *start, int *first, int *geometry, 
			int found, int conn_type) 
{
	pa_switch_t *curr_switch = NULL; 
	pa_switch_t *next_switch = NULL; 
	
	int port_tar;
	int source_port=0;
	int target_port=0;
	int num_visited=0;
	int broke = 0, not_first = 0;
	int ports_to_try[2] = {3,5};
	int *node_tar = NULL;
	int i, i2;
	pa_node_t *next_node = NULL;
	pa_node_t *check_node = NULL;
	
	ListIterator itr;
	List path = NULL;

	if(!pa_node)
		return 0;

	if(!source_port) {
		target_port=1;
		ports_to_try[0] = 4;
		ports_to_try[1] = 2;
			
	}
	curr_switch = &pa_node->axis_switch[X];
	if(geometry[X] == 1) {
		goto found_one;
	}
	debug2("found - %d",found);
	for(i=0;i<2;i++) {
		/* check to make sure it isn't used */
		if(!curr_switch->int_wire[ports_to_try[i]].used) {
			node_tar = curr_switch->
				ext_wire[ports_to_try[i]].node_tar;
			port_tar = curr_switch->
				ext_wire[ports_to_try[i]].port_tar;
			if((node_tar[X] == 
			    start[X] && 
			    node_tar[Y] == 
			    start[Y] && 
			    node_tar[Z] == 
			    start[Z])) {
				broke = 1;
				goto broke_it;
			}
			if((node_tar[X] == 
			    pa_node->coord[X] && 
			    node_tar[Y] == 
			    pa_node->coord[Y] && 
			    node_tar[Z] == 
			    pa_node->coord[Z])) {
				continue;
			}
			itr = list_iterator_create(results);
			while((next_node = (pa_node_t*) list_next(itr))) {
				if((node_tar[X] == 
				    next_node->coord[X] && 
				    node_tar[Y] == 
				    next_node->coord[Y] && 
				    node_tar[Z] == 
				    next_node->coord[Z])) {
					not_first = 1;
					break;
				}
				
			}
			list_iterator_destroy(itr);
			if(not_first && found<DIM_SIZE[X]) {
				not_first = 0;
				continue;
			} 
			not_first = 0;
				
		broke_it:
#ifdef HAVE_BGL
			next_node = &pa_system_ptr->
				grid[node_tar[X]][node_tar[Y]][node_tar[Z]];
#else
			next_node = &pa_system_ptr->
				grid[node_tar[X]];
#endif
			next_switch = &next_node->axis_switch[X];
		
			
 			if((conn_type == MESH) && (found == (geometry[X]))) {
				debug2("we found the end of the mesh");
				return 1;
			}
			debug3("Broke = %d Found = %d geometry[X] = %d",
			       broke, found, geometry[X]);
			if(broke && (found == geometry[X])) {
				return 1;
			} else if(found == geometry[X]) {
				debug2("finishing the torus!");
				list_destroy(best_path);
				best_path = list_create(_delete_path_list);
				_finish_torus(curr_switch, 
					      0, 
					      results, 
					      X, 
					      0, 
					      start);
				
				if(best_count < BEST_COUNT_INIT) {
					debug2("Found a best path with %d "
					       "steps.", best_count);
					_set_best_path();
					return 1;
				} else {
					return 0;
				}
			} else if(broke) {
				broke = 0;
				continue;
			}

			if (!_node_used(next_node, geometry)) {
#ifdef HAVE_BGL
				debug2("found %d looking at %d%d%d "
				       "%d going to %d%d%d %d",
				       found,
				       pa_node->coord[X],
				       pa_node->coord[Y],
				       pa_node->coord[Z],
				       ports_to_try[i],
				       node_tar[X],
				       node_tar[Y],
				       node_tar[Z],
				       port_tar);
#endif
				itr = list_iterator_create(results);
				while((check_node = 
				       (pa_node_t*) list_next(itr))) {
					if((node_tar[X] == 
					    check_node->coord[X] && 
					    node_tar[Y] == 
					    check_node->coord[Y] && 
					    node_tar[Z] == 
					    check_node->coord[Z])) {
						break;
					}
				}
				list_iterator_destroy(itr);
				if(!check_node) {
#ifdef HAVE_BGL
					debug2("add %d%d%d",
					       next_node->coord[X],
					       next_node->coord[Y],
					       next_node->coord[Z]);
#endif					       
					list_append(results, next_node);
				} else {
#ifdef HAVE_BGL
					debug2("Hey this is already added "
					       "%d%d%d",
					       node_tar[X],
					       node_tar[Y],
					       node_tar[Z]);
#endif
					continue;
				}
				found++;
				
				if(!_find_x_path(results, next_node, 
						 start, first, geometry, 
						 found, conn_type)) {
					_remove_node(results,
						     next_node->coord);
					found--;
					continue;
				} else {
					/* check Y and Z dims */
#ifdef HAVE_BGL
				found_path:
					debug("added node %d%d%d %d %d -> "
					       "%d%d%d %d %d",
					       pa_node->coord[X],
					       pa_node->coord[Y],
					       pa_node->coord[Z],
					       source_port,
					       ports_to_try[i],
					       node_tar[X],
					       node_tar[Y],
					       node_tar[Z],
					       port_tar,
					       target_port);
#endif					
				found_one:			
					if(geometry[X] != 1) {
						curr_switch->
							int_wire
							[source_port].used = 1;
						curr_switch->
							int_wire
							[source_port].port_tar
							= ports_to_try[i];
						curr_switch->
							int_wire
							[ports_to_try[i]].used
							= 1;
						curr_switch->
							int_wire
							[ports_to_try[i]].
							port_tar = source_port;
					
						next_switch->
							int_wire[port_tar].used
							= 1;
						next_switch->
							int_wire
							[port_tar].port_tar
							= target_port;
						next_switch->
							int_wire
							[target_port].used = 1;
						next_switch->
							int_wire
							[target_port].port_tar
							= port_tar;
					}
					return 1;

				}
			} 			
		}
	}
#ifdef HAVE_BGL
	debug2("looking for the next free node starting at %d%d%d",
	       pa_node->coord[X],
	       pa_node->coord[Y],
	       pa_node->coord[Z]);
#endif
	list_destroy(best_path);
	best_path = list_create(_delete_path_list);
	_find_next_free(curr_switch, 
			0, 
			results, 
			X, 
			0);
	if(best_count < BEST_COUNT_INIT) {
		debug2("yes found next free %d", best_count);
		node_tar = _set_best_path();
#ifdef HAVE_BGL
		next_node = &pa_system_ptr->
			grid[node_tar[X]][node_tar[Y]][node_tar[Z]];
#else
		next_node = &pa_system_ptr->
			grid[node_tar[X]];
#endif
		next_switch = &next_node->axis_switch[X];
		
#ifdef HAVE_BGL
		debug2("found %d looking at %d%d%d going to %d%d%d %d",
		       found,
		       pa_node->coord[X],
		       pa_node->coord[Y],
		       pa_node->coord[Z],
		       node_tar[X],
		       node_tar[Y],
		       node_tar[Z],
		       port_tar);
#endif		
		list_append(results, next_node);
		found++;
		if(_find_x_path(results, next_node, 
				start, first, geometry, found, conn_type)) {
			return 1;
		} else {
			found--;
			_reset_the_path(curr_switch, 0, 1, X);
			_remove_node(results, next_node->coord);
			return 0;
		}
	} 
	
	debug2("couldn't find path");
	return 0;
}

static int _remove_node(List results, int *node_tar)
{
	ListIterator itr;
	pa_node_t *pa_node = NULL;
	
	itr = list_iterator_create(results);
	while((pa_node = (pa_node_t*) list_next(itr))) {
		
#ifdef HAVE_BGL
		if(node_tar[X] == pa_node->coord[X] 
		   && node_tar[Y] == pa_node->coord[Y] 
		   && node_tar[Z] == pa_node->coord[Z]) {
			debug2("removing %d%d%d from list",
			       node_tar[X],
			       node_tar[Y],
			       node_tar[Z]);
			list_remove (itr);
			break;
		}
#else
		if(node_tar[X] == pa_node->coord[X]) {
			debug2("removing %d from list",
			       node_tar[X]);
			list_remove (itr);
			break;
		}
#endif
	}
	list_iterator_destroy(itr);
	return 1;
}

static int _find_next_free(pa_switch_t *curr_switch, int source_port, 
			   List nodes, int dim, int count) 
{
	pa_switch_t *next_switch = NULL; 
	pa_path_switch_t *path_add = 
		(pa_path_switch_t *) xmalloc(sizeof(pa_path_switch_t));
	pa_path_switch_t *path_switch = NULL;
	pa_path_switch_t *temp_switch = NULL;
	int port_tar;
	int target_port = 0;
	int ports_to_try[2] = {3,5};
	int *node_tar= curr_switch->ext_wire[0].node_tar;
	int *node_src = curr_switch->ext_wire[0].node_tar;
	int i;
	int used=0;
	int broke = 0;
	pa_node_t *pa_node = NULL;
	
	ListIterator itr;
	static bool found = false;

	path_add->geometry[X] = node_src[X];
#ifdef HAVE_BGL
	path_add->geometry[Y] = node_src[Y];
	path_add->geometry[Z] = node_src[Z];
#endif
	path_add->dim = dim;
	path_add->in = source_port;

	if(count>=best_count)
		return 0;
	
	itr = list_iterator_create(nodes);
	while((pa_node = (pa_node_t*) list_next(itr))) {
		
#ifdef HAVE_BGL
		if(node_tar[X] == pa_node->coord[X] 
		   && node_tar[Y] == pa_node->coord[Y] 
		   && node_tar[Z] == pa_node->coord[Z]) {
			broke = 1;
			break;
		}
#else
		if(node_tar[X] == pa_node->coord[X]) {
			broke = 1;
			break;
		}
#endif
		
	}
	list_iterator_destroy(itr);

	if(!broke && count>0 &&
	   !pa_system_ptr->grid[node_tar[X]]
#ifdef HAVE_BGL
	   [node_tar[Y]]
	   [node_tar[Z]]
#endif
	   .used) {
		
		debug3("this one not found %d%d%d",
		       node_tar[X],
		       node_tar[Y],
		       node_tar[Z]);
		
		broke = 0;
				
		if((source_port%2))
			target_port=1;
		
		list_destroy(best_path);
		best_path = list_create(_delete_path_list);
		found = true;
		path_add->out = target_port;
		list_push(path, path_add);
		
		itr = list_iterator_create(path);
		while((path_switch = (pa_path_switch_t*) list_next(itr))){
		
			temp_switch = (pa_path_switch_t *) 
				xmalloc(sizeof(pa_path_switch_t));
			 
			temp_switch->geometry[X] = path_switch->geometry[X];
#ifdef HAVE_BGL
			temp_switch->geometry[Y] = path_switch->geometry[Y];
			temp_switch->geometry[Z] = path_switch->geometry[Z];
#endif
			temp_switch->dim = path_switch->dim;
			temp_switch->in = path_switch->in;
			temp_switch->out = path_switch->out;
			list_append(best_path,temp_switch);
		}
		list_iterator_destroy(itr);
		best_count = count;
		return 1;
	} 

	if(source_port==0 || source_port==3 || source_port==5) {
		ports_to_try[0] = 4;
		ports_to_try[1] = 2;	
	}
			
	for(i=0;i<2;i++) {
		used=0;
		if(!curr_switch->int_wire[ports_to_try[i]].used) {
			itr = list_iterator_create(path);
			while((path_switch = 
			       (pa_path_switch_t*) list_next(itr))){
				
				if(((path_switch->geometry[X] == node_src[X]) 
#ifdef HAVE_BGL
				    && (path_switch->geometry[Y] 
					== node_src[Y])
				    && (path_switch->geometry[Z] 
					== node_tar[Z])
#endif
					   )) {
					
					if( path_switch->out
					    == ports_to_try[i]) {
						used = 1;
						break;
					}
				}
			}
			list_iterator_destroy(itr);
			
			if(curr_switch->
			   ext_wire[ports_to_try[i]].node_tar[X]
			   == curr_switch->ext_wire[0].node_tar[X]  
#ifdef HAVE_BGL
			   && curr_switch->
			   ext_wire[ports_to_try[i]].node_tar[Y] 
			   == curr_switch->ext_wire[0].node_tar[Y] 
			   && curr_switch->
			   ext_wire[ports_to_try[i]].node_tar[Z] 
			   == curr_switch->ext_wire[0].node_tar[Z]
#endif
				) {
				continue;
			}
						
			if(!used) {
				port_tar = curr_switch->
					ext_wire[ports_to_try[i]].port_tar;
				node_tar = curr_switch->
					ext_wire[ports_to_try[i]].node_tar;
				
				next_switch = &pa_system_ptr->
					grid[node_tar[X]]
#ifdef HAVE_BGL
					[node_tar[Y]]
					[node_tar[Z]]
#endif
					.axis_switch[X];
				
				count++;
				path_add->out = ports_to_try[i];
				list_push(path, path_add);
				_find_next_free(next_switch, port_tar, nodes,
						dim, count);
				while(list_pop(path) != path_add){
				} 
			}
		}
	}
	xfree(path_add);
	return 0;
}

static int _finish_torus(pa_switch_t *curr_switch, int source_port, 
			 List nodes, int dim, int count, int *start) 
{
	pa_switch_t *next_switch = NULL; 
	pa_path_switch_t *path_add = 
		(pa_path_switch_t *) xmalloc(sizeof(pa_path_switch_t));
	pa_path_switch_t *path_switch = NULL;
	pa_path_switch_t *temp_switch = NULL;
	int port_tar;
	int target_port=0;
	int ports_to_try[2] = {3,5};
	int *node_tar= curr_switch->ext_wire[0].node_tar;
	int *node_src = curr_switch->ext_wire[0].node_tar;
	int i;
	int used=0;
	pa_node_t *pa_node = NULL;
	ListIterator itr;
	static bool found = false;

	path_add->geometry[X] = node_src[X];
#ifdef HAVE_BGL
	path_add->geometry[Y] = node_src[Y];
	path_add->geometry[Z] = node_src[Z];
#endif
	path_add->dim = dim;
	path_add->in = source_port;

	if(count>=best_count)
		return 0;
		
	if(node_tar[X] == start[X] 
#ifdef HAVE_BGL
	    && node_tar[Y] == start[Y] 
	    && node_tar[Z] == start[Z]
#endif
		) {
		
		if((source_port%2))
			target_port=1;
		if(!curr_switch->int_wire[target_port].used) {
			
			list_destroy(best_path);
			best_path = list_create(_delete_path_list);
			found = true;
			path_add->out = target_port;
			list_push(path, path_add);
			
			itr = list_iterator_create(path);
			while((path_switch = 
			       (pa_path_switch_t*) list_next(itr))){
				
				temp_switch = (pa_path_switch_t *) 
					xmalloc(sizeof(pa_path_switch_t));
				
				temp_switch->geometry[X] = 
					path_switch->geometry[X];
#ifdef HAVE_BGL
				temp_switch->geometry[Y] = 
					path_switch->geometry[Y];
				temp_switch->geometry[Z] = 
					path_switch->geometry[Z];
#endif
				temp_switch->dim = path_switch->dim;
				temp_switch->in = path_switch->in;
				temp_switch->out = path_switch->out;
				list_append(best_path,temp_switch);
			}
			list_iterator_destroy(itr);
			best_count = count;
			return 1;
		} 
	}
	
	if(source_port==0 || source_port==3 || source_port==5) {
		ports_to_try[0] = 4;
		ports_to_try[1] = 2;		
	}
	
	for(i=0;i<2;i++) {
		used=0;
		if(!curr_switch->int_wire[ports_to_try[i]].used) {
			itr = list_iterator_create(path);
			while((path_switch = 
			       (pa_path_switch_t*) list_next(itr))){
				
				if(((path_switch->geometry[X] == node_src[X]) 
#ifdef HAVE_BGL
				    && (path_switch->geometry[Y] 
					== node_src[Y])
				    && (path_switch->geometry[Z] 
					== node_tar[Z])
#endif
					)) {
					if( path_switch->out
					    == ports_to_try[i]) {
						used = 1;
						break;
					}
				}
			}
			list_iterator_destroy(itr);
			if((curr_switch->
			    ext_wire[ports_to_try[i]].node_tar[X] == 
			    curr_switch->ext_wire[0].node_tar[X] && 
			    curr_switch->
			    ext_wire[ports_to_try[i]].node_tar[Y] == 
			    curr_switch->ext_wire[0].node_tar[Y] && 
			    curr_switch->
			    ext_wire[ports_to_try[i]].node_tar[Z] == 
			    curr_switch->ext_wire[0].node_tar[Z])) {
				continue;
			}
			if(!used) {
				port_tar = curr_switch->
					ext_wire[ports_to_try[i]].port_tar;
				node_tar = curr_switch->
					ext_wire[ports_to_try[i]].node_tar;
				
				next_switch = &pa_system_ptr->
					grid[node_tar[X]]
#ifdef HAVE_BGL
					[node_tar[Y]]
					[node_tar[Z]]
#endif
					.axis_switch[dim];
			
				
				count++;
				path_add->out = ports_to_try[i];
				list_push(path, path_add);
				_finish_torus(next_switch, port_tar, nodes,
						dim, count, start);
				while(list_pop(path) != path_add){
				} 
			}
		}
       }
       xfree(path_add);
       return 0;
}

static int *_set_best_path()
{
	ListIterator itr;
	pa_path_switch_t *path_switch = NULL;
	pa_switch_t *curr_switch = NULL; 
	int *geo = NULL;
	if(!best_path)
		return NULL;
	itr = list_iterator_create(best_path);
	while((path_switch = (pa_path_switch_t*) list_next(itr))) {
#ifdef HAVE_BGL
		debug3("mapping %d%d%d",path_switch->geometry[X],
		       path_switch->geometry[Y],
		       path_switch->geometry[Z]);
		if(!geo)
			geo = path_switch->geometry;
		curr_switch = &pa_system_ptr->
			grid
			[path_switch->geometry[X]]
			[path_switch->geometry[Y]]
			[path_switch->geometry[Z]].  
			axis_switch[path_switch->dim];
#else
		curr_switch = &pa_system_ptr->
			grid[path_switch->geometry[X]].
			axis_switch[path_switch->dim];
#endif
	
		curr_switch->int_wire[path_switch->in].used = 1;
		curr_switch->int_wire[path_switch->in].port_tar = 
			path_switch->out;
		curr_switch->int_wire[path_switch->out].used = 1;
		curr_switch->int_wire[path_switch->out].port_tar = 
			path_switch->in;
	}
	list_iterator_destroy(itr);

	best_count=BEST_COUNT_INIT;
	return geo;
}

/* static int _configure_dims(int *coord, List nodes, int *start,  */
/* 			   int *end, int conn_type) */
/* { */
/* 	pa_switch_t *curr_switch = NULL;  */
/* 	int dim; */
/* 	List send_nodes; */
/* 	ListIterator itr; */
/* 	pa_node_t* pa_node = NULL; */
/* 	int diff[PA_SYSTEM_DIMENSIONS]; */

/* 	/\* set it up for the X axis *\/ */
/* 	for(dim=0; dim<PA_SYSTEM_DIMENSIONS; dim++) { */
/* 		if(start[dim] == end[dim]) */
/* 			continue; */
/* #ifdef HAVE_BGL */
/* 		curr_switch = &pa_system_ptr-> */
/* 			grid[coord[X]][coord[Y]][coord[Z]].axis_switch[dim]; */
/* 		diff[X] = end[X] - start[X]; */
/* 		diff[Y] = end[Y] - start[Y]; */
/* 		diff[Z] = end[Z] - start[Z]; */
/* #else */
/* 		curr_switch = &pa_system_ptr->grid[coord[X]].axis_switch[dim]; */
/* 		diff[X] = end[X] - start[X]; */
/* #endif */
		

/* 		if(conn_type == MESH && (coord[dim]==(end[dim]))) { */
/* 			continue; */
/* 		} */
			
/* 		/\* set it up for 0 *\/ */
/* 		if(!curr_switch->int_wire[0].used) { */
/* 			send_nodes = list_create(NULL); */
			
/* 			itr = list_iterator_create(nodes); */
/* 			while((pa_node =  */
/* 			       (pa_node_t*) list_next(itr))) { */
/* #ifdef HAVE_BGL */
/* 				if(coord[X] == pa_node->coord[X] && */
/* 				   coord[Y] == pa_node->coord[Y] && */
/* 				   coord[Z] == pa_node->coord[Z]) { */
/* #else  */
/* 				if(coord[X] == pa_node->coord[X]) { */
/* #endif */
/* 					continue; */
/* 				} */
/* 				list_append(send_nodes, pa_node); */
/* 			} */
/* 			list_iterator_destroy(itr); */
			
/* 			if(!_find_one_hop(curr_switch,  */
/* 					  0,  */
/* 					  send_nodes,  */
/* 					  dim, diff)) { */
/* 				list_destroy(best_path); */
/* 				best_path = list_create(NULL); */
/* 				_finish_torus(curr_switch,  */
/* 						0,  */
/* 						send_nodes,  */
/* 						dim,  */
/* 						0, start); */
				
/* 				if(best_count < BEST_COUNT_INIT) { */
/* 					debug("yes %d",best_count); */
/* 					_set_best_path(); */
/* 				} else  */
/* 					return 0; */
/* 			} */
/* 		}  */
			
/* 	} */
/* 	return 1; */
	
/* } */

static int _set_one_dim(int *start, int *end, int *coord)
{
	int dim;
	pa_switch_t *curr_switch = NULL; 
	
	for(dim=0;dim<PA_SYSTEM_DIMENSIONS;dim++) {
		if(start[dim]==end[dim]) {
			curr_switch = &pa_system_ptr->grid[coord[X]]
#ifdef HAVE_BGL
				[coord[Y]]
				[coord[Z]]
#endif
				.axis_switch[dim];

			if(!curr_switch->int_wire[0].used 
			   && !curr_switch->int_wire[1].used) {
				curr_switch->int_wire[0].used = 1;
				curr_switch->int_wire[0].port_tar = 1;
				curr_switch->int_wire[1].used = 1;
				curr_switch->int_wire[1].port_tar = 0;
			}
		}
	}
	return 1;
}

//#define BUILD_EXE
#ifdef BUILD_EXE
/** */
int main(int argc, char** argv)
{
	pa_request_t *request = (pa_request_t*) xmalloc(sizeof(pa_request_t)); 
	log_options_t log_opts = LOG_OPTS_INITIALIZER;
	int debug_level = 3;

	List results;
//	List results2;
//	int i,j;
	DIM_SIZE[X]=8;
	DIM_SIZE[Y]=4;
	DIM_SIZE[Z]=4;
	pa_init(NULL);	
	log_opts.stderr_level  = debug_level;
	log_opts.logfile_level = debug_level;
	log_opts.syslog_level  = debug_level;
	
	log_alter(log_opts, LOG_DAEMON, 
		  "/dev/null");
						
	results = list_create(NULL);
	request->geometry[0] = 6;
	request->geometry[1] = 2;
	request->geometry[2] = 2;
	//request->size = 32;
	request->rotate = 0;
	request->elongate = 0;
	request->conn_type = TORUS;
	new_pa_request(request);
	print_pa_request(request);
	if(!allocate_part(request, results)) {
       		debug("couldn't allocate %d%d%d",
		       request->geometry[0],
		       request->geometry[1],
		       request->geometry[2]);	
	}
	list_destroy(results);
	
	results = list_create(NULL);
	request->geometry[0] = 6;
	request->geometry[1] = 2;
	request->geometry[2] = 2;
	//request->size = 32;
	request->conn_type = TORUS;
	new_pa_request(request);
	print_pa_request(request);
	if(!allocate_part(request, results)) {
       		printf("couldn't allocate %d%d%d\n",
		       request->geometry[0],
		       request->geometry[1],
		       request->geometry[2]);
	}
	list_destroy(results);
	
/* 	results = list_create(NULL); */
/* 	request->geometry[0] = 4; */
/* 	request->geometry[1] = 4; */
/* 	request->geometry[2] = 4; */
/* 	//request->size = 2; */
/* 	request->conn_type = TORUS; */
/* 	new_pa_request(request); */
/* 	print_pa_request(request); */
/* 	if(!allocate_part(request, results)) { */
/*        		printf("couldn't allocate %d%d%d\n", */
/* 		       request->geometry[0], */
/* 		       request->geometry[1], */
/* 		       request->geometry[2]); */
/* 	} */

/* 	results = list_create(NULL); */
/* 	request->geometry[0] = 1; */
/* 	request->geometry[1] = 4; */
/* 	request->geometry[2] = 4; */
/* 	//request->size = 2; */
/* 	request->conn_type = TORUS; */
/* 	new_pa_request(request); */
/* 	print_pa_request(request); */
/* 	if(!allocate_part(request, results)) { */
/*        		printf("couldn't allocate %d%d%d\n", */
/* 		       request->geometry[0], */
/* 		       request->geometry[1], */
/* 		       request->geometry[2]); */
/* 	} */

	
	int dim,j;
	int x,y,z;
	int startx=0;
	int starty=0;
	int startz=2;
	int endx=1;//DIM_SIZE[X];
	int endy=DIM_SIZE[Y];
	int endz=3;//DIM_SIZE[Z];
	for(x=startx;x<endx;x++) {
		for(y=starty;y<endy;y++) {
			for(z=startz;z<endz;z++) {
				info("Node %d%d%d Used = %d Letter = %c",
				       x,y,z,pa_system_ptr->grid[x][y][z].used,
				       pa_system_ptr->grid[x][y][z].letter);
				for(dim=1;dim<2;dim++) {
					info("Dim %d",dim);
					pa_switch_t *wire =
						&pa_system_ptr->
						grid[x][y][z].axis_switch[dim];
					for(j=0;j<6;j++)
						info("\t%d -> %d -> %d%d%d %d "
						     "Used = %d",
						     j, wire->int_wire[j].
						     port_tar,
						     wire->ext_wire[
							     wire->int_wire[j].
							     port_tar].
						     node_tar[X],
						     wire->ext_wire[
							     wire->int_wire[j].
							     port_tar].
						     node_tar[Y],
						     wire->ext_wire[
							     wire->int_wire[j].
							     port_tar].
						     node_tar[Z],
						     wire->ext_wire[
							     wire->int_wire[j].
							     port_tar].
						     port_tar,
						     wire->int_wire[j].used);
				}
			}
		}
	}
	/* list_destroy(results); */

/* 	pa_fini(); */

/* 	delete_pa_request(request); */
	
	return 0;
}


#endif