diff --git a/src/partition_allocator/Makefile.am b/src/partition_allocator/Makefile.am index 9e6492eaf9207711ae8436bc8c89d26781609395..19cf74ce04191ad647040c25c785ed5d58a6dd96 100644 --- a/src/partition_allocator/Makefile.am +++ b/src/partition_allocator/Makefile.am @@ -2,6 +2,7 @@ # Makefile.am for graph_solver AUTOMAKE_OPTIONS = foreign +CLEANFILES = core.* INCLUDES = -I$(top_srcdir) $(BGL_INCLUDES) @@ -14,8 +15,8 @@ INCLUDES = -I$(top_srcdir) $(BGL_INCLUDES) # $(top_builddir)/src/common/libcommon.la -lpthread \ # $(top_builddir)/src/api/libslurm.la -# partition_allocator_LDFLAGS = -export-dynamic -lm $(CMD_LDFLAGS) -# CFLAGS = -DBUILD_EXE +# partition_allocator_LDFLAGS = -export-dynamic -lm $(CMD_LDFLAGS) $(BGL_LDFLAGS) +# CPPFLAGS = -DBUILD_EXE # making a .la noinst_LTLIBRARIES = libpartition_allocator.la @@ -33,9 +34,9 @@ libpartition_allocator_la_DEPENDENCIES = \ $(top_builddir)/src/common/libcommon.la #### -#force: -#$(convenience_libs) : force -# @cd `dirname $@` && $(MAKE) `basename $@` +# force: +# $(convenience_libs) : force +# @cd `dirname $@` && $(MAKE) `basename $@` ######### diff --git a/src/partition_allocator/graph_solver.c b/src/partition_allocator/graph_solver.c deleted file mode 100644 index 148d0e08a2be6c180d29fe435d320393468ae5e7..0000000000000000000000000000000000000000 --- a/src/partition_allocator/graph_solver.c +++ /dev/null @@ -1,1729 +0,0 @@ -/*****************************************************************************\ - * graph_solver.c - * - ***************************************************************************** - * 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> - * - * 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. -\*****************************************************************************/ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <time.h> -#include "slurm.h" -#include "graph_solver.h" -#include "src/common/xstring.h" - -#define SUCCESS 0 -#define ERROR -1 - -#define NOT_INDETERMINATE != NO_VAL -#define IS_INDETERMINATE < 0 - -#define SWAP(a,b,t) \ -_STMT_START { \ - (t) = (a); \ - (a) = (b); \ - (b) = (t); \ -} _STMT_END - -// #define PRINT_RESULTS -// #define DEBUG_PRINT_RESULTS -// #define DEBUG -/* this is for debugging, so that we don't run through all - * permutations each time - */ -// #define PERM_DEBUG -int __permutations; -#define __PERM_LIMIT 1000 - -// for list utility functions -// extern void * lsd_fatal_error(char *file, int line, char *mesg){exit(0);} -// extern void * lsd_nomem_error(char *file, int line, char *mesg){exit(0);} - -enum conn_labels {LABEL_IGNORE, LABEL_FOUND, LABEL_RECYCLE, - LABEL_MERGE}; - -char* convert_label(int label); - -/** internally used helper functions */ -void _join_ext_connections(switch_t* switchA, int port_numA, - switch_t* switchB, int port_numB, - connection_t** conn); -/* */ -int _join_int_connections(switch_t* my_switch, int port_numA, int port_numB, - connection_t** conn); -/** */ -int _test_ext_connections(node_t* node); -/* */ -void _init_internal_connections(system_t *sys); -/** */ -void _swap(char* a, int i, int j); -/** */ -void _enumerate(char* enum_string, int string_size, List results); -/** */ -int _find_all_port_permutations(int** plus_ports, List* minus_ports_list); - -/** */ -int _find_all_switch_permutations(node_t* node, int* plus_ports, - List minus_ports_list); - -/** */ -int _find_all_paths(int* plus_ports, List minus_ports_list, - List current_nodes, List current_configs, - List conf_result_list); - -/** */ -void _find_all_paths_aux(List* connection_list, List current_port_conf, - List conf_result_list); - -/** */ -void _connect_switch(switch_t* my_switch, int* plus_ports, int* minus_ports); -/** */ -void _test_list_copy(List A); -/** */ -int _convert_string_to_int_array(char* string, int size, int** result_array); -/** */ -int _connection_t_cmpf(connection_t* A, connection_t* B); -/** */ -int _get_connection_partition(connection_t* conn, List partitions_list); -/** */ -int _merge_connection(connection_t* conn, List partitions_list); -/** */ -int _label_connection(connection_t* conn); -/* reset the sys structures */ -void _reset_sys(); -/* reset the partition data */ -void _reset_partitions(); -/** reset all the indeterminate connections back to their correct values */ -void _reset_indeterminate_connections(); -/** */ -void _init_local_partition(List result_partitions); -/** */ -void _print_all_connections(); -/** */ -// void _print_results(List result_partitions, List current_port_conf); -void _print_results(List conf_result_list); -/** */ -void _insert_results(List conf_result_list, List result_partitions, List current_port_conf); - -/** configure up the system to get ready for partitioning*/ -// int init_system(system_t* sys) -int gs_init(List port_config_list, int num_nodes) -{ - ListIterator itr; - int i; - node_t *node; - switch_t *switch_x; // , *switch_y, *switch_z; - switch_t *switch_src, *switch_tar; - connection_t *conn; - switch_config_t* switch_config; - -#ifdef PERM_DEBUG - __permutations = 0; -#endif - - /** bad bad programming practice, just a quick fix...for now...*/ - __initialized = false; - /** */ - - new_system(); - - /* 1) create all the nodes */ - for (i=0; i<num_nodes; i++){ - new_node(&node, i); - } - - /* wire the nodes up externally */ - /* FIXME, need to do this intelligently, and dynamically - * according to some config file - */ - - /* 2) create the switches for the nodes */ - itr = list_iterator_create(global_sys->node_list); - for (i=0; i<num_nodes; i++){ - node = (node_t*) list_next(itr); - - new_switch(&switch_x, node, i, X); - // new_switch(&switch_y, node, i, Y); - // new_switch(&switch_z, node, i, Z); - } - list_iterator_destroy(itr); - - /* 3) wire up the external connections */ - itr = list_iterator_create(port_config_list); - while ((switch_config = (switch_config_t*) list_next(itr))){ - new_connection(&conn); - conn->place = EXTERNAL; -/* switch_src = get_switch(switch_config->node_src, switch_config->dim); */ -/* switch_tar = get_switch(switch_config->node_tar, switch_config->dim); */ - - if (!switch_src || ! switch_tar){ - printf("Error, external switch configuration failed\n"); - return ERROR; - } - _join_ext_connections(switch_src, switch_config->port_src, - switch_tar, switch_config->port_tar, - &conn); - list_push(global_sys->connection_list, conn); - } - list_iterator_destroy(itr); - - // print_system(global_sys); - return SUCCESS; -} - -/* deletes the graph structs */ -void gs_fini(List port_config_list) -{ - delete_system(); -} - -/** */ -void new_conf_result(conf_result_t** conf_result, conf_data_t* conf_data) -{ - *conf_result = (conf_result_t*) xmalloc(sizeof(conf_result_t)); - (*conf_result)->conf_data = conf_data; - (*conf_result)->port_conf_list = list_create(delete_port_conf); -} - -/** delete a conf_result_t */ -void delete_conf_result(void* object) -{ - conf_result_t* conf_result = (conf_result_t*) object; - - delete_conf_data(conf_result->conf_data); - list_destroy(conf_result->port_conf_list); - xfree(conf_result); -} - -/** */ -void print_conf_result(conf_result_t* conf_result) -{ - int i, j; - int num_part; - if (!conf_result){ - printf("printf_conf_result, error conf_result is NULL\n"); - return; - } - - num_part = conf_result->conf_data->num_partitions; - printf("NumPartitions=%d ", num_part); - printf("PartitionSizes="); - for (i=0; i<num_part; i++){ - printf("%d", conf_result->conf_data->partition_sizes[i]); - if (i != (num_part - 1)){ - printf(","); - } else { - printf(" "); - } - } - - printf("PartitionTypes="); - for (i=0; i<num_part; i++){ - printf("%d", conf_result->conf_data->partition_type[i]); - if (i != (num_part - 1)){ - printf(","); - } else { - printf(" "); - } - } - - printf("NodeIDs="); - for (i=0; i<num_part; i++){ - for (j=0; j<conf_result->conf_data->partition_sizes[i]; j++){ - printf("%d", conf_result->conf_data->node_id[i][j]); - if (j != (conf_result->conf_data->partition_sizes[i] - 1)){ - printf("/"); - } - } - - if (i != (num_part - 1)){ - printf(","); - } else { - printf(" "); - } - } - - printf("PortConfig="); - print_port_conf_list(conf_result->port_conf_list); - printf("\n"); -} - -void print_conf_result_list(List conf_result_list) -{ - ListIterator itr; - conf_result_t* conf_result; - - itr = list_iterator_create(conf_result_list); - while((conf_result = (conf_result_t*) list_next(itr) )){ - print_conf_result(conf_result); - } - list_iterator_destroy(itr); -} - -/** */ -void new_conf_data(conf_data_t** conf_data, int num_partitions) -{ - *conf_data = (conf_data_t*) xmalloc(sizeof(conf_data_t)); - (*conf_data)->num_partitions = num_partitions; - (*conf_data)->partition_sizes = (int*) xmalloc(sizeof(int) * num_partitions); - (*conf_data)->partition_type = (conn_type_t*) xmalloc(sizeof(conn_type_t) * num_partitions); - - /* note that before using the node_id, you must again xmalloc for each entry */ - (*conf_data)->node_id = (int**) xmalloc(sizeof(int*) * num_partitions); -} - -/** */ -void delete_conf_data(void* object) -{ - int i; - conf_data_t* conf_data = (conf_data_t*) object; - - for (i=0; i<conf_data->num_partitions; i++){ - xfree(conf_data->node_id[i]); - } - xfree(conf_data->node_id); - xfree(conf_data->partition_sizes); - xfree(conf_data->partition_type); - xfree(conf_data); -} - -/** */ -void new_port_conf(port_conf_t** port_conf, int* plus_ports, int* minus_ports) -{ - int i; - (*port_conf) = (port_conf_t*) xmalloc(sizeof(port_conf_t)); - (*port_conf)->plus_ports = (int*) xmalloc(sizeof(int)*NUM_PLUS_PORTS); - (*port_conf)->minus_ports = (int*) xmalloc(sizeof(int)*NUM_MINUS_PORTS); - - for (i=0; i<NUM_PLUS_PORTS; i++){ - (*port_conf)->plus_ports[i] = plus_ports[i]; - } - - for (i=0; i<NUM_MINUS_PORTS; i++){ - (*port_conf)->minus_ports[i] = minus_ports[i]; - } -} - -/** */ -void delete_port_conf(void * object) -{ - port_conf_t* port_conf = (port_conf_t*) object; - xfree(port_conf->plus_ports); - xfree(port_conf->minus_ports); - xfree(port_conf); -} - -/** - * - * IN - sys: - * - * OUT - conf_result_list: results of the graph search for - * the given configuration, as set by init_system(); - */ -int find_all_tori(List conf_result_list) -{ - List switches_copy = NULL, minus_ports_list = NULL; - int *plus_ports = NULL; - List current_configs; - - if (_find_all_port_permutations(&plus_ports, &minus_ports_list)){ - printf("had some trouble there with the find all port perms\n"); - return ERROR; - } - - list_copy(global_sys->switch_list, &switches_copy); - /** - * find all the toroidal paths in the system, and insert - * results into conf_result_list - */ - - current_configs = list_create(delete_port_conf); - _find_all_paths(plus_ports, minus_ports_list, - switches_copy, current_configs, - conf_result_list); - - list_destroy(current_configs); - list_destroy(switches_copy); - - xfree(plus_ports); - list_destroy(minus_ports_list); - - /* if the configs and num nodes are too big, then the - * algorithm may not finish, so you may want to print this out - * to indicate in the output file an actual successful finish. - printf("ALL DONE\n"); - */ - - // 999 - // _print_results(conf_result_list); - - return SUCCESS; -} - -/** - * recursively iterates through all the possible combinations of - * wiring configurations and uses _find_all_paths to find all the - * paths in the given configuration. - * - * NOTE: if we wanted to split each of these permutations up (have - * _find_all_paths_aux be a pthread), then we need to make copies of - * the system at each of those, and also keep the results - * "synchronzied" (in a mutex/semaphore, etc). - */ -int _find_all_paths(int* plus_ports, List minus_ports_list, - List current_switches, List current_configs, - List conf_result_list) -{ - ListIterator list_itr; - int* minus_ports = NULL; - switch_t* my_switch; - port_conf_t* port_conf; - List connection_list_copy; - - /* order doesn't matter here because all switches will - * iterate through all the permutations anyway - */ - my_switch = list_pop(current_switches); - if (!my_switch) { - printf("ERROR: _find_all_paths: went past the end\n"); - return ERROR; - } - list_itr = list_iterator_create(minus_ports_list); - while((minus_ports = (int*) list_next(list_itr))){ - _connect_switch(my_switch, plus_ports, minus_ports); - /* print the configured switch: */ - // print_node(my_switch); - new_port_conf(&port_conf, plus_ports, minus_ports); - list_push(current_configs, port_conf); - - /** base case */ - if (list_count(current_switches) == 0){ - // print_port_conf_list(current_configs); - list_copy(global_sys->connection_list, &connection_list_copy); - _find_all_paths_aux(&connection_list_copy, current_configs, conf_result_list); - list_destroy(connection_list_copy); - } else { - _find_all_paths(plus_ports, minus_ports_list, current_switches, - current_configs, conf_result_list); - } - port_conf = list_pop(current_configs); - delete_port_conf(port_conf); - } - list_iterator_destroy(list_itr); - - /** we have to put the guy back in*/ - list_push(current_switches, my_switch); - - return SUCCESS; -} - -/** - * go through the list of all system connections and search for - * the connection's partition. - * - * This is called for a configuration instance, ie: - * node [0] plus port [0 3 5] minus port [1 2 4] - * node [1] plus port [0 3 5] minus port [1 2 4] - * node [2] plus port [0 3 5] minus port [2 1 4] - * - */ -void _find_all_paths_aux(List* connection_list, List current_port_conf, - List conf_result_list) -{ - connection_t* conn; - - /* number of indeterminate connections */ - int num_ind = 0, num_itr = 0; - int last_num_ind = NO_VAL; - connection_t* list_head = NULL; - - int label; - -#ifdef PERM_DEBUG - __permutations++; - if (__permutations > __PERM_LIMIT){ - printf("test complete\n"); - exit(0); - } -#endif - - /* need to keep a local copy of all this stuff */ - List result_partitions = list_create(delete_partition); - _init_local_partition(result_partitions); -#ifdef DEBUG - printf("_find_all_paths_aux\n"); -#endif - - list_sort (*connection_list, (ListCmpF) _connection_t_cmpf); - // conn_itr = list_iterator_create(connection_list); - /** - * this is the engine of the graph solving program. it - * iterates through all connections and labels them according - * to the connection charateristics. if either end of the - * connection is connected to a pre-lableled connection (ie, - * in a node), then it inherits the label. otherwise it is - * marked as indeterminate. since all partitions (connected - * graphs w/ nodes) originate at nodes and thus the labels - * will "spread out" on each cycle. Thus one important - * property of this loop is that the number of indeterminate - * connections that participate in a partition will decrease - * on each iteration. If the indeterminate connections do not - * decrease, that indicates that the algorithm has found all - * partitions, and hence we are done. - * - * - * NOTE: one way to make each iteration best case: - * (num permutations) * O(indeterminate_conns - 1) faster is if we - * keep a separate List indeterminate_conns, and when we remove the - * head of a list, we simply move the head of the list to the next - * in line indeterinate conn. - */ - while((conn = (connection_t*) list_pop(*connection_list))){ - label = _label_connection(conn); -#ifdef DEBUG - printf("------------------------------------\n"); - printf(" _label_connection: %s\n", convert_label(label)); - // printf("number of partitions %d\n", list_count(global_sys->partition_list)); - // printf("number of current partitions %d\n", list_count(result_partitions)); - print_connection(conn); -#endif - switch(label){ - case LABEL_IGNORE: - /* drop the connection */ -#ifdef DEBUG - printf("find_all_paths_aux: LABEL_IGNORE, dropping connection\n"); -#endif - break; - case LABEL_FOUND: - /* simply add the connection to the partition*/ - if (conn->partition == NULL){ - // this also adds the connection to the partition - _get_connection_partition(conn, result_partitions); - } - /* otherwise, the connection should already be - * in the partition */ - break; - case LABEL_MERGE: - if (_merge_connection(conn, result_partitions)){ - printf("_find_all_paths_aux failed for LABEL_MERGE\n"); - exit(0); - } - break; - case LABEL_RECYCLE: - num_ind++; - /** dunno if we're going to have probs with the list */ - list_append(*connection_list, conn); - if (list_head == NULL){ -#ifdef DEBUG - printf("_find_all_paths_aux: defining head of list\n"); -#endif - list_head = conn; - } - /* if the former head is removed, then we have - * to redefine the head - */ - else if (list_head->id NOT_INDETERMINATE){ -#ifdef DEBUG - printf("_find_all_paths_aux: redefining head of list\n"); -#endif - list_head = conn; - /* since we don't know "where" we are - * in the list, we must reset the - * ind_conn counters so that we know - * where we are in the list. - */ - last_num_ind = NO_VAL; - num_ind = 0; - } - /* */ - else { - /* list_head = wrap in indeterminate conns list */ - if (conn == list_head){ - num_itr++; - /* first case = progress being made */ -#ifdef DEBUG - printf("_find_all_paths_aux: back at head\n"); - printf("_find_all_paths_aux: num_ind <%d> last_num_ind <%d>\n", - num_ind, last_num_ind); -#endif - if (last_num_ind == NO_VAL || num_ind < last_num_ind){ - last_num_ind = num_ind; - num_ind = 0; - } - /* 2nd case = no change, */ - else if (num_ind == last_num_ind){ -#ifdef DEBUG - printf("no change since last iteration, we're done\n"); -#endif - goto done; - } - /* 3rd case = ...wtf? */ - else { - printf("ERROR, finding more work on this iteration???\n"); - printf("_find_all_paths_aux: num_ind <%d> last_num_ind <%d>\n", - num_ind, last_num_ind); - exit(0); - } - } - } - break; - case ERROR: - default: - printf("_label_connection: ERROR, unknown label\n"); /** dunno what's going on... */ - exit(0); - } - } - done: - - _insert_results(conf_result_list, result_partitions, current_port_conf); - - list_destroy(result_partitions); - _reset_sys(); -} - -void _insert_results(List conf_result_list, List result_partitions, List current_port_conf) -{ - int part_size; - bool has_large_part=false, found_torus=false, p1_all_toroidal = true; - ListIterator itr; - partition_t* part; - - /* check to see if this set has partitions greater than or - * equal to LARGE_PART size partitions, and that we at least - * have one toroidal partition (otherwise, it's worthless to - * save. - * - * in addition, we're enforcing that all partitions of size 1 - * must be toroidal (cleans up the conf_result_list) - */ - itr = list_iterator_create(result_partitions); - while((part = (partition_t*) list_next(itr))){ - part_size = list_count(part->node_list); - if (part_size >= LARGE_PART){ - has_large_part = true; - if (part->conn_type == SELECT_TORUS){ - found_torus = true; - } - } - if (part_size == 1 && part->conn_type != SELECT_TORUS){ - p1_all_toroidal = false; - break; - } - } - list_iterator_destroy(itr); - - if (has_large_part && found_torus && p1_all_toroidal){ - conf_data_t* conf_data; - conf_result_t* conf_result; - port_conf_t* port_conf, *port_conf_copy; - ListIterator node_itr; - int i; - node_t* node; - - new_conf_data(&conf_data, list_count(result_partitions)); - - itr = list_iterator_create(result_partitions); - i = 0; - while((part = (partition_t*) list_next(itr))){ - int j, list_size; - - conf_data->partition_sizes[i] = list_count(part->node_list); - conf_data->partition_type[i] = part->conn_type; - - /* this is xfree'd by delete_conf_data */ - list_size = list_count(part->node_list); - conf_data->node_id[i] = (int*) xmalloc (sizeof(int) * list_size); - j = 0; - node_itr = list_iterator_create(part->node_list); - while((node = (node_t*) list_next(node_itr))){ - conf_data->node_id[i][j++] = node->id; - } - list_iterator_destroy(node_itr); - - sort_node_id(conf_data->node_id[i], list_size); - - i++; - } - list_iterator_destroy(itr); - - new_conf_result(&conf_result, conf_data); - - itr = list_iterator_create(current_port_conf); - while((port_conf = (port_conf_t*) list_next(itr))){ - new_port_conf(&port_conf_copy, port_conf->plus_ports, port_conf->minus_ports); - list_push(conf_result->port_conf_list, port_conf_copy); - } - list_iterator_destroy(itr); - - list_push(conf_result_list, conf_result); - } -} - -/** - * easy to implement swap sort, and since there aren't that - * many nodes, this shouldn't take too long. - */ -void sort_node_id(int* node_id, int size) -{ - int i; - int tmp; - bool no_change = false; - while(!no_change){ - no_change = true; - for (i=0; i<size-1; i++){ - if (node_id[i] > node_id[i+1]){ - SWAP(node_id[i], node_id[i+1], tmp); - no_change = false; - } - } - } -} - -/** print out the results of the search */ -void _print_results(List conf_result_list){ - ListIterator itr; - conf_result_t* conf_result; - itr = list_iterator_create(conf_result_list); - while((conf_result = (conf_result_t*) list_next(itr))){ - print_conf_result(conf_result); - } - list_iterator_destroy(itr); -} - -/* reset the sys structures */ -void _reset_sys() -{ - ListIterator conn_itr; - connection_t* conn; - - /* reset all the indeterminate connections back to their - * correct values. set all connections that are not the - * special "node" connection and set as back as INDETERMINATE - * (NO_VAL); - */ - conn_itr = list_iterator_create(global_sys->connection_list); - while((conn = (connection_t*) list_next(conn_itr))){ - conn->id = conn->original_id; - if (conn->id == NO_VAL){ - conn->partition = NULL; - } - } - list_iterator_destroy(conn_itr); -} - -/** - * - * NOTE: if we switched to using arrays and pointers for INTERNAL/EXTERNAL, - * and the endpoints, then this function could be cut in half. - * - */ -int _label_connection(connection_t* conn) -{ -#ifdef DEBUG - printf("_label_connection\n"); -#endif - if (!conn){ - printf("_label_connection error, connection NULL\n"); - return ERROR; - } - - if (conn->id NOT_INDETERMINATE){ -#ifdef DEBUG - printf("_label_connection: found prelabeled node\n"); -#endif - return LABEL_FOUND; - } - - if (conn->place == INTERNAL){ -#ifdef DEBUG - printf("internal connection found\n"); -#endif - /* CASE A: both endpoints non-NULL */ - if (conn->ep0->conn_ext != NULL && conn->ep1->conn_ext != NULL){ - /** both endpoints with labels */ - if (conn->ep0->conn_ext->id NOT_INDETERMINATE && - conn->ep1->conn_ext->id NOT_INDETERMINATE){ -#ifdef DEBUG - printf("_label_connection: both endpoints have labels\n"); -#endif - - return LABEL_MERGE; - } - /** no endpoints with label */ - else if (conn->ep0->conn_ext->id IS_INDETERMINATE && - conn->ep1->conn_ext->id IS_INDETERMINATE){ -#ifdef DEBUG - printf("_label_connection: no endpoints have labels\n"); -#endif - return LABEL_RECYCLE; - } - /** one endpoint with label */ - else { -#ifdef DEBUG - printf("_label_connection: one endpoint has label\n"); -#endif - if (conn->ep0->conn_ext->id NOT_INDETERMINATE){ - conn->id = conn->ep0->conn_ext->id; - return LABEL_FOUND; - } else { - conn->id = conn->ep1->conn_ext->id; - return LABEL_FOUND; - } - } - } - - /* CASE B: both endpoints NULL */ - else if (conn->ep0->conn_ext == NULL && conn->ep1->conn_ext == NULL){ -#ifdef DEBUG - printf("_label_connection: both endpoints NULL\n"); -#endif - return LABEL_IGNORE; - } - - /* CASE C: one side of connection NULL */ - else { -#ifdef DEBUG - printf("_label_connection: one side of connection NULL\n"); -#endif - /** if one side is labeled, place this - * connection into that partition. - */ - if (conn->ep0->conn_ext != NULL && - conn->ep0->conn_ext->id NOT_INDETERMINATE){ - conn->id = conn->ep0->conn_ext->id; - return LABEL_FOUND; - } else if (conn->ep1->conn_ext != NULL && - conn->ep1->conn_ext->id NOT_INDETERMINATE){ - conn->id = conn->ep1->conn_ext->id; - return LABEL_FOUND; - } - /* otherwise, otherwise, recycle */ - else { - return LABEL_RECYCLE; - } - } - } /** for external connections */ - else { -#ifdef DEBUG - printf("external connection found\n"); -#endif - /* CASE A: both endpoints non-NULL */ - if (conn->ep0->conn_int != NULL && conn->ep1->conn_int != NULL){ - /** both endpoints with labels */ - if (conn->ep0->conn_int->id NOT_INDETERMINATE && - conn->ep1->conn_int->id NOT_INDETERMINATE){ -#ifdef DEBUG - printf("_label_connection: both endpoints have labels\n"); -#endif - return LABEL_MERGE; - } - /** no endpoints with label */ - else if (conn->ep0->conn_int->id IS_INDETERMINATE && - conn->ep1->conn_int->id IS_INDETERMINATE){ -#ifdef DEBUG - printf("_label_connection: no endpoints have labels\n"); -#endif - return LABEL_RECYCLE; - } - /** one endpoint with label */ - else { -#ifdef DEBUG - printf("_label_connection: one endpoint has label\n"); -#endif - if (conn->ep0->conn_int->id NOT_INDETERMINATE){ - conn->id = conn->ep0->conn_int->id; - return LABEL_FOUND; - } else { - conn->id = conn->ep1->conn_int->id; - return LABEL_FOUND; - } - } - } - - /* CASE B: both endpoints NULL */ - else if (conn->ep0->conn_int == NULL - && conn->ep1->conn_int == NULL){ -#ifdef DEBUG - printf("_label_connection: both endpoints NULL\n"); -#endif - return LABEL_IGNORE; - } - - /* CASE C: one side of connection NULL. */ - else { -#ifdef DEBUG - printf("_label_connection: one side of connection NULL\n"); -#endif - /* if one side - * is labeled, place this connection into that - * partition. - */ - if (conn->ep0->conn_ext != NULL && - conn->ep0->conn_ext->id NOT_INDETERMINATE){ - conn->id = conn->ep0->conn_ext->id; - return LABEL_FOUND; - } else if (conn->ep1->conn_ext != NULL && - conn->ep1->conn_ext->id NOT_INDETERMINATE){ - conn->id = conn->ep1->conn_ext->id; - return LABEL_FOUND; - } - /* otherwise, recycle */ - else { - return LABEL_RECYCLE; - } - } - } -} - -/** - * NOTE: since we place the configs in a stack fashion the list is - * printed "backwards" - * - * it's inefficient to print the list out this way, so in production, - * we should simply print it backwards, or ask moe to add the reverse - * iterator - */ -void print_port_conf_list(List port_configs) -{ - port_conf_t* port_conf; - ListIterator itr = list_iterator_create(port_configs); - - port_conf = (port_conf_t*) list_next(itr); - while(port_conf != NULL){ - printf("%d%d%d/", - port_conf->plus_ports[0], - port_conf->plus_ports[1], - port_conf->plus_ports[2]); - printf("%d%d%d", - port_conf->minus_ports[0], - port_conf->minus_ports[1], - port_conf->minus_ports[2]); - - port_conf = (port_conf_t*) list_next(itr); - if (port_conf != NULL){ - printf(","); - } else { - printf(" "); - } - } - list_iterator_destroy(itr); -} - -/** */ -void _print_all_connections() -{ - ListIterator itr; - connection_t* conn; - - printf("printing all system connections\n"); - itr = list_iterator_create(global_sys->connection_list); - while((conn = (connection_t*) list_next(itr))){ - printf("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - \n"); - print_connection(conn); - } - list_iterator_destroy(itr); - printf("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - \n"); -} - -/** */ -void print_system(system_t* sys) -{ - ListIterator itr; - node_t* node; - switch_t* my_switch; - connection_t* conn; - - /** print out all the nodes */ - printf("-----------------------------\n"); - printf("number of nodes in system: %d\n", - list_count(sys->node_list)); - itr = list_iterator_create(sys->node_list); - while ((node = (node_t*) list_next(itr))) { - print_node(node); - } - list_iterator_destroy(itr); - - /** print out all the switches */ - printf("--------------------------------\n"); - printf("number of switches in system: %d\n", - list_count(sys->switch_list)); - itr = list_iterator_create(sys->switch_list); - while ((my_switch = (switch_t*) list_next(itr))) { - print_node(my_switch); - } - list_iterator_destroy(itr); - - printf("\n--------------------------------\n"); - printf("external connections in system:\n"); - itr = list_iterator_create(sys->connection_list); - while ((conn = (connection_t*) list_next(itr))) { - if (conn->place == EXTERNAL) - print_connection(conn); - } - list_iterator_destroy(itr); -} - -/** */ -void _join_ext_connections(switch_t* switchA, int port_numA, - switch_t* switchB, int port_numB, - connection_t** conn) -{ - /* FIXME 2 and 5 should read in from somewhere, and not hardcoded here*/ - int PORT_MIN, PORT_MAX; - PORT_MIN = 2; - PORT_MAX = 5; - - if (!switchA || port_numA < PORT_MIN || port_numA > PORT_MAX || - !switchB || port_numB < PORT_MIN || port_numB > PORT_MAX || - !(*conn)){ - printf("error, _join_ext_connection input incomplete\n"); - return; - } - - /* join the connections to the node ports */ - (*conn)->ep0 = &(switchA->ports[port_numA]); - (*conn)->ep1 = &(switchB->ports[port_numB]); - - /* join the node ports to the connections */ - switchA->ports[port_numA].conn_ext = (*conn); - switchB->ports[port_numB].conn_ext = (*conn); -} - -/** - * the definition of a valid node is in reference to toridal connects: - * - * valid: if both internal connections to the ports with the BP - * connect to valid external ports (non-NULL) and it has two or more - * of these types of connections. - * - * RETURN - TRUE (0) if valid, FALSE (1) otherwise - */ -int _test_ext_connections(node_t* node) -{ - ListIterator int_conn_itr; - connection_t* conn; - int bp0, bp1, found_bp_conns; // boolean values for having found the two bp conns - - bp0 = bp1 = found_bp_conns = 0; - - int_conn_itr = list_iterator_create(node->connection_list); - while((conn = (connection_t*) list_next(int_conn_itr))){ - if (conn->ep0->conn_ext != NULL && conn->ep1->conn_ext != NULL){ - if (conn->ep0->conn_ext->id NOT_INDETERMINATE || - conn->ep0->conn_ext->id NOT_INDETERMINATE){ - found_bp_conns++; - if (!bp0) { - bp0 = 1; - } else { - bp1 = 1; - printf("test_ext_conn: found both BPs, this node valid"); - break; - } - } - } - - } - list_iterator_destroy(int_conn_itr); - - if (bp0 == 1 && bp1 == 1 && found_bp_conns > 1){ - return SUCCESS; - } else { - return ERROR; - } -} - -/** - * join the connections to internal ports of the given node. - * - * IN - node: node to wire up - * IN - port_numA: one side of the connection - * IN - port_numB: the other side of the connection - * IN - conn: connection to use - * RETURN - the success of the connection. - */ -int _join_int_connections(switch_t* my_switch, int port_numA, int port_numB, - connection_t** conn) -{ - /* FIXME 2 and 5 should read in from somewhere, and not hardcoded here */ - int PORT_MIN, PORT_MAX; - PORT_MIN = 0; - PORT_MAX = 5; - - /** don't touch the internal connections of a node*/ - if (my_switch->is_node){ -#ifdef DEBUG - printf("_join_int_connections: internal wires of node should not be changed\n"); -#endif - return SUCCESS; - } - - if (!my_switch){ - printf("error, _join_int_connection: given node null\n"); - return ERROR; - } - if (port_numA < PORT_MIN || port_numA > PORT_MAX || - port_numB < PORT_MIN || port_numB > PORT_MAX){ - printf("error, _join_int_connection: port numbers outside of allowable port" - " range: port 1: %d port 2: %d >< min: %d max: %d\n", - port_numA, port_numB, PORT_MIN, PORT_MAX); - return ERROR; - } - - if (!(*conn)){ - printf("error, _join_int_connection: connection null\n"); - return ERROR; - } - - /* join the connections to the node ports */ - (*conn)->ep0 = &(my_switch->ports[port_numA]); - (*conn)->ep1 = &(my_switch->ports[port_numB]); - - /* join the node ports to the connections */ - my_switch->ports[port_numA].conn_int = (*conn); - my_switch->ports[port_numB].conn_int = (*conn); - - return SUCCESS; -} - -/** - * the connection should have both endpoints as non NULL - * - * doesn't matter if both partitions have the same label or different - * labels. - */ -int _merge_connection(connection_t* conn, List partition_list) -{ - if (conn->place == INTERNAL){ - merge_partitions(conn->ep0->conn_ext->partition, - conn->ep1->conn_ext->partition, - partition_list); - conn->id = conn->ep0->conn_ext->id; - } else { - merge_partitions(conn->ep0->conn_int->partition, - conn->ep1->conn_int->partition, - partition_list); - conn->id = conn->ep0->conn_int->id; - } - - _get_connection_partition(conn, partition_list); - return SUCCESS; -} - -/** - * find all the possible wiring ups for a given node. This will not - * be the same for all nodes. For each of the precalculated port - * matches, we see if those ports are connected externally. if not, - * then that switch configuration doesn't work. - * - * OUT - List* nodes: - * - */ -int _find_all_switch_permutations(switch_t* my_switch, int* plus_ports, - List minus_ports_list) -{ - int *minus_ports; - ListIterator list_itr; - minus_ports = NULL; - - /** for each permutation, create a node of that permutation */ - list_itr = list_iterator_create(minus_ports_list); - while((minus_ports = (int*) list_next(list_itr))){ - printf("_find_all_node_permutations: plus port %d %d %d minus port %d %d %d\n", - plus_ports[0], plus_ports[1], plus_ports[2], - minus_ports[0], minus_ports[1], minus_ports[2]); - - _connect_switch(my_switch, plus_ports, minus_ports); - } - list_iterator_destroy(list_itr); - - return SUCCESS; -} - -/** - * find all the possible port permutations. So, for example in BGL, - * we have plus ports: 035 and minus ports: 124, and plus can only the - * plug into minus. This function finds all the permutations of that. - * To find all these, we basically hold one static (the plus ports) - * and change out the order of the minus ports. - * - * NOTE: this function seems pretty BGL specific - * - * IN - nothing at this point, but the plus/minus ports should be read - * in from a file - * - * OUT - int* plus_int: the plus ports in an int array - * OUT - List minus_int_list: the permutations of the minus ports in a - * list of int arrays - * - * NOTE: the outbound structures will be created by this function and - * must be freed by the caller. - */ -int _find_all_port_permutations(int** plus_ports, List* minus_int_list) -{ - int rc, string_size; - int *minus_ports = NULL; - char *plus_ports_str; - char *minus_ports_str; - List minus_str_list; - rc = SUCCESS; - - *plus_ports = NULL; - - /** FIXME: this should be input from the config file */ - plus_ports_str = xstrdup("035"); - minus_ports_str = xstrdup("124"); - // minus_ports_str = xstrdup("412"); - - /** we assume that the num of plus ports = minus ports, which - * may be incorrect */ - string_size = strlen(plus_ports_str); - if (string_size != strlen(minus_ports_str)){ - printf("ERROR! # plus ports != # minus ports"); - exit(0); - } - - /** - * we keep the plus ports static, and permute the minus - * ports. - */ - minus_str_list = list_create(delete_gen); - _enumerate(minus_ports_str, string_size, minus_str_list); - - /** convert the strings to a form we can use */ - *plus_ports = (int*) xmalloc(sizeof(int)*string_size); - if (!(*plus_ports)){ - printf("error, not enough mem for plus ports\n"); - exit(1); - } - - if (_convert_string_to_int_array(plus_ports_str, string_size, plus_ports)){ - printf("ERROR! can't convert plus_port string to int array\n"); - exit(0); - } - - *minus_int_list = list_create(delete_gen); - - ListIterator itr; - char* minus_string; - itr = list_iterator_create(minus_str_list); - while((minus_string = (char*) list_next(itr))){ - minus_ports = (int*) xmalloc(sizeof(int) * string_size); - if (_convert_string_to_int_array(minus_string, string_size, &minus_ports)){ - printf("ERROR! can't convert string to int array\n"); - exit(0); - } - list_append(*minus_int_list, minus_ports); - } - list_iterator_destroy(itr); - - xfree(plus_ports_str); - xfree(minus_ports_str); - list_destroy(minus_str_list); - - return rc; -} - -/** - * initialize as: - * 0 1 - * /--|--|--\ - * | \--/ | - * 5 --\ /-- 2 - * | \ / | - * \__|__|__/ - * 4 3 - */ -void _init_internal_connections(system_t *sys) -{ - ListIterator node_itr, conn_itr; - node_t* node; - connection_t* conn; - - node_itr = list_iterator_create(global_sys->node_list); - while ((node = (node_t*) list_next(node_itr))) { - - conn_itr = list_iterator_create(global_sys->connection_list); - while ((conn = (connection_t*) list_next(conn_itr))) { - _join_int_connections(node, 0, 1, &conn); - _join_int_connections(node, 3, 2, &conn); - _join_int_connections(node, 5, 4, &conn); - } - list_iterator_destroy(conn_itr); - - } - list_iterator_destroy(node_itr); -} - -/** - * ListDelF for a List of Lists of nodes - */ -void delete_list(void* object) -{ - ListIterator itr; - node_t* node; - List list = (List) object; - itr = list_iterator_create(list); - while ((node = (node_t*) list_next(itr))) { - delete_node(node); - } - list_iterator_destroy(itr); -} - -/** - * resursive implementation of solutiion to enumerate all the - * permutations of a string - * - * IN - string to enumerate - * IN - size of string - * OUT - results: List of strings. This list must already be - * initialized - */ -void _enumerate(char* enum_string, int string_size, List results) -{ - int i; - char *full_string = NULL; - /* base case of recursion */ - if (string_size == 0) { - full_string = xstrdup(enum_string); - list_push(results, full_string); - // printf("%s\n", enum_string); - - } else { - for (i=0; i<string_size; i++){ - char tmp; - /* swap (1, n-1) */ - SWAP(enum_string[i], enum_string[string_size-1], tmp); - // _swap(enum_string, i, string_size-1); - /* recursive call on n-1 elements */ - _enumerate(enum_string, string_size-1, results); - /* put it all back together */ - SWAP(enum_string[string_size-1], enum_string[i], tmp); - // _swap(enum_string, string_size-1, i); - } - } -} - -/** - * helper swap function used by enumerate - */ -void _swap(char* a, int i, int j) -{ - char tmp; - tmp = a[i]; - a[i] = a[j]; - a[j] = tmp; -} - -/* result_array must be initializd before passing into this function - */ -int _convert_string_to_int_array(char* string, int size, int** result_array) -{ - char zero = '0'; - int i; - - /* printf("converting string %s to array\n", string); */ - if (!result_array){ - printf("Error, result array not initialized\n"); - return ERROR; - } - - for (i=0; i<size; i++){ - (*result_array)[i] = (int)(string[i]-zero); - } - /* printf("array %d %d %d\n", (*result_array)[0], (*result_array)[1], (*result_array)[2]); */ - - return SUCCESS; -} - -/** - * - */ -void _connect_switch(switch_t* my_switch, int* plus_ports, int* minus_ports) -{ - connection_t* conn; - ListIterator itr; - int i; - - itr = list_iterator_create(my_switch->connection_list); - for (i=0; i<INTERNAL_CONNECTIONS_PER_NODE; i++){ - conn = (connection_t*) list_next(itr); - _join_int_connections(my_switch, plus_ports[i], minus_ports[i], &conn); - } - list_iterator_destroy(itr); -} - -/** - * Shallow copy list A to List B. List A should be preinitialized - * (obviously) but List B will be created here and freed by caller. - */ -void list_copy(List A, List* B) -{ - ListIterator itr; - void* object; - - *B = list_create(NULL); - itr = list_iterator_create(A); - while ((object = list_next(itr))) { - list_append(*B, object); - } - list_iterator_destroy(itr); -} - -/** - * Comparator used for sorting connections by label - * - * returns: -1: A internal && B external 0: A equal to B 1: A ext && B int - * - */ -int _connection_t_cmpf(connection_t* A, connection_t* B) -{ - if (A->place == B->place) - return 0; - else if (A->place == INTERNAL) - return -1; - else - return 1; -} - - -/* note that we initialize all the partitions as starting - * off as toridal connections */ -void _init_local_partition(List result_partitions) -{ - partition_t *new_part, *old_part; - ListIterator part_itr; - - if (!result_partitions){ - printf("_init_local_partition ERROR, list is unintialized\n"); - exit(0); - } - - part_itr = list_iterator_create(global_sys->partition_list); - while ((old_part = (partition_t*) list_next(part_itr))){ - copy_partition(old_part, &new_part); - new_part->conn_type = SELECT_TORUS; - list_append(result_partitions, new_part); - } - list_iterator_destroy(part_itr); -} - -char* convert_label(int label) -{ - switch (label){ - case LABEL_IGNORE: return "LABEL_IGNORE"; - case LABEL_FOUND: return "LABEL_FOUND"; - case LABEL_RECYCLE: return "LABEL_RECYCLE"; - case LABEL_MERGE: return "LABEL_MERGE"; - default: return "UNKNOWN LABEL???"; - } -} - -int _get_connection_partition(connection_t* conn, List partition_list) -{ - partition_t* part = find_partition(partition_list, conn->id); - -#ifdef DEBUG - printf("_get_connection_partition for partition label %d\n", conn->id); -#endif - - if (!part){ - printf("_get_connection_partition error, partition <%d> not found\n", conn->id); - exit(0); - } - - add_connection_to_partition(conn, part); - return SUCCESS; -} - -/** */ -void create_config_9_2d(List configs) -{ - switch_config_t* conf; - conf = (switch_config_t*) xmalloc(sizeof(switch_config_t)); - - /** - * remember that connections are bidirectional, so we only - * have a connection between nodes once - */ - /* first X row */ - new_switch_config(conf, NO_VAL, X, 0, 3, 1, 4); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, X, 0, 4, 2, 3); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, X, 1, 3, 2, 4); - list_append(configs, conf); - - /* second X row */ - new_switch_config(conf, NO_VAL, X, 3, 3, 4, 4); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, X, 3, 4, 5, 3); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, X, 4, 3, 5, 4); - list_append(configs, conf); - - /* third X row */ - new_switch_config(conf, NO_VAL, X, 6, 3, 7, 4); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, X, 6, 4, 8, 3); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, X, 7, 3, 8, 4); - list_append(configs, conf); - - /* first Y column */ - - new_switch_config(conf, NO_VAL, Y, 0, 3, 3, 4); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, Y, 0, 4, 6, 3); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, Y, 3, 3, 6, 4); - list_append(configs, conf); - - /* second Y column */ - new_switch_config(conf, NO_VAL, Y, 1, 3, 4, 4); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, Y, 1, 4, 7, 3); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, Y, 4, 3, 7, 4); - list_append(configs, conf); - - /* third Y column */ - new_switch_config(conf, NO_VAL, Y, 2, 3, 5, 4); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, Y, 2, 4, 8, 3); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, Y, 5, 3, 8, 4); - list_append(configs, conf); -} - -/** tested, working */ -void create_config_3_1d(List configs) -{ - switch_config_t* conf; - conf = (switch_config_t*) xmalloc(sizeof(switch_config_t)); - - /* first X row */ - new_switch_config(conf, NO_VAL, X, 0, 3, 1, 4); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, X, 0, 4, 2, 3); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, X, 1, 3, 2, 4); - list_append(configs, conf); - -} - -/* */ -void create_config_4_2d(List configs) -{ - switch_config_t* conf; - conf = (switch_config_t*) xmalloc(sizeof(switch_config_t)); - - /** - * remember that connections are bidirectional, so we only - * have a connection between nodes once - */ - /* first X row */ - new_switch_config(conf, NO_VAL, X, 0, 3, 1, 4); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, X, 0, 4, 1, 3); - list_append(configs, conf); - - /* second X row */ - new_switch_config(conf, NO_VAL, X, 2, 3, 3, 4); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, X, 2, 4, 3, 3); - list_append(configs, conf); - - - /* first Y column */ - new_switch_config(conf, NO_VAL, Y, 0, 3, 2, 4); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, Y, 0, 4, 2, 3); - list_append(configs, conf); - - /* second Y column */ - new_switch_config(conf, NO_VAL, Y, 1, 3, 3, 4); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, Y, 1, 4, 3, 3); - list_append(configs, conf); -} - -/* */ -void create_config_4_1d(List configs) -{ - switch_config_t* conf; - conf = (switch_config_t*) xmalloc(sizeof(switch_config_t)); - - /** - * remember that connections are bidirectional, so we only - * have a connection between nodes once - */ - /* first X row */ - new_switch_config(conf, NO_VAL, X, 0, 3, 1, 4); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, X, 1, 3, 2, 4); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, X, 2, 3, 3, 4); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, X, 3, 3, 0, 4); - list_append(configs, conf); -} - -/* */ -void create_config_8_1d(List configs) -{ - switch_config_t* conf; - conf = (switch_config_t*) xmalloc(sizeof(switch_config_t)); - - /** - * remember that connections are bidirectional, so we only - * have one connection between nodes - */ - /* top row, horizontal connections */ - new_switch_config(conf, NO_VAL, X, 0, 3, 2, 4); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, X, 2, 3, 4, 4); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, X, 4, 3, 6, 4); - list_append(configs, conf); - - /* bottom row, horizontal connections */ - new_switch_config(conf, NO_VAL, X, 1, 4, 3, 3); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, X, 3, 4, 5, 3); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, X, 5, 4, 7, 3); - list_append(configs, conf); - - /* 1st column, vertical connections */ - new_switch_config(conf, NO_VAL, X, 0, 2, 1, 5); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, X, 1, 3, 0, 4); - list_append(configs, conf); - - /* 2nd column, vertical connections */ - new_switch_config(conf, NO_VAL, X, 2, 2, 3, 5); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, X, 3, 2, 2, 5); - list_append(configs, conf); - - /* 3rd column, vertical connections */ - new_switch_config(conf, NO_VAL, X, 4, 2, 5, 5); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, X, 5, 2, 4, 5); - list_append(configs, conf); - - /* 4th column, vertical connections */ - new_switch_config(conf, NO_VAL, X, 6, 3, 7, 4); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, X, 7, 2, 6, 5); - list_append(configs, conf); -} - - -/* */ -void create_config_8_3d(List configs) -{ - switch_config_t* conf; - conf = (switch_config_t*) xmalloc(sizeof(switch_config_t)); - - /** - * remember that connections are bidirectional, so we only - * have a connection between nodes once - */ - /****************************************/ - /* first X row Z0 */ - new_switch_config(conf, NO_VAL, X, 0, 3, 1, 4); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, X, 0, 4, 1, 3); - list_append(configs, conf); - - /* second X row Z0*/ - new_switch_config(conf, NO_VAL, X, 2, 3, 3, 4); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, X, 2, 4, 3, 3); - list_append(configs, conf); - - - /* first X row Z1 */ - new_switch_config(conf, NO_VAL, X, 4, 3, 5, 4); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, X, 4, 4, 5, 3); - list_append(configs, conf); - - /* second X row Z1 */ - new_switch_config(conf, NO_VAL, X, 6, 3, 7, 4); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, X, 6, 4, 7, 3); - list_append(configs, conf); - - /****************************************/ - /* first Y column Z0 */ - new_switch_config(conf, NO_VAL, Y, 0, 3, 2, 4); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, Y, 0, 4, 2, 3); - list_append(configs, conf); - - /* second Y column Z0 */ - new_switch_config(conf, NO_VAL, Y, 1, 3, 3, 4); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, Y, 1, 4, 3, 3); - list_append(configs, conf); - - /* first Y column Z1 */ - new_switch_config(conf, NO_VAL, Y, 4, 3, 6, 4); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, Y, 4, 4, 6, 3); - list_append(configs, conf); - - /* second Y column Z1 */ - new_switch_config(conf, NO_VAL, Y, 5, 3, 7, 4); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, Y, 5, 4, 7, 3); - list_append(configs, conf); - - /****************************************/ - /* */ - new_switch_config(conf, NO_VAL, Z, 0, 3, 4, 4); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, Z, 0, 4, 4, 3); - list_append(configs, conf); - - /* */ - new_switch_config(conf, NO_VAL, Z, 1, 3, 5, 4); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, Z, 1, 4, 5, 3); - list_append(configs, conf); - - /* */ - new_switch_config(conf, NO_VAL, Z, 2, 3, 6, 4); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, Z, 2, 4, 6, 3); - list_append(configs, conf); - - /* */ - new_switch_config(conf, NO_VAL, Z, 3, 3, 7, 4); - list_append(configs, conf); - new_switch_config(conf, NO_VAL, Z, 3, 4, 7, 3); - list_append(configs, conf); -} diff --git a/src/partition_allocator/graph_solver.h b/src/partition_allocator/graph_solver.h deleted file mode 100644 index 64f5aa374ed2a552490dc4ed0fe941f95095d996..0000000000000000000000000000000000000000 --- a/src/partition_allocator/graph_solver.h +++ /dev/null @@ -1,135 +0,0 @@ -/*****************************************************************************\ - * graph_solver.h - * - ***************************************************************************** - * 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> - * - * 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. -\*****************************************************************************/ - -#ifndef _GRAPH_SOLVER_H_ -#define _GRAPH_SOLVER_H_ - -#include "graph_structs.h" - -#define LARGE_PART 2 -#define NUM_NODES 3 -#define NUM_INTERNAL_CONNECTIONS 3 /* per node */ -#define NUM_EXTERNAL_CONNECTIONS 3 -#define WHITE -2 -#define NUM_MINUS_PORTS 3 -#define NUM_PLUS_PORTS 3 - -/** - * conf_data holds a port configuration's emergent information, namely - * the number of partitions, the partition sizes, the partition types - * and the nodes' relative number in the configuration - * - */ -typedef struct conf_data { - /** number of partitions in this configuration */ - int num_partitions; - /** partition sizes */ - int* partition_sizes; - /** partition types corresponding to the partition sizes (by index) */ - conn_type_t* partition_type; - /* the node id's corresponding to each of the partition sizes. - * so if there is a conf_data with partition_sizes: 2 1 1, then - * node_id might have something like [ 0/1,2,3 ] - */ - int** node_id; -} conf_data_t; - -/** - * a port configuration where the plus ports match up to the minus - * ports by index. e.g. for plus_ports = 035 and minus ports 241, the - * connections will be matched up 02, 34, 51 - */ -typedef struct port_conf { - int* plus_ports; - int* minus_ports; -} port_conf_t; - -/** - * conf_result holds the results of the graph solver search for each - * configuration instance. So for example, for a 3x1 system, a - * conf_result will hold in port_conf_list the port configurations - * (e.g. 421 412 142) and the conf_data that corresponds to that - * configuration - */ -typedef struct conf_result { - List port_conf_list; - conf_data_t* conf_data; -} conf_result_t; - -/** create a conf_result_t */ -void new_conf_result(conf_result_t** conf_result, conf_data_t* conf_data); -/** delete a conf_result_t */ -void delete_conf_result(void* object); -/** print out a conf_result */ -void print_conf_result(conf_result_t* conf_result); -/* */ -void print_conf_result_list(List conf_result_list); -/** create a conf_data_t */ -void new_conf_data(conf_data_t** conf_data, int num_partitions); -/** delete a conf_data_t */ -void delete_conf_data(void* object); -/** create a port_conf_t */ -void new_port_conf(port_conf_t** port_conf, int* plus_ports, int* minus_ports); -/** delete a port_conf_t */ -void delete_port_conf(void* object); -/* print out a port conf*/ -void print_port_conf(port_conf_t* port_conf); -/* print out a port conf list*/ -void print_port_conf_list(List current_configs); - -/** */ -void list_copy(List A, List* B); -/** */ -void delete_list(void* object); -/** */ -int find_all_tori(List part_config_list); - -/** */ -void print_system(system_t* sys); -/** */ -int gs_init(List port_config_list, int num_nodes); -/** */ -void gs_fini(); -/* */ -void sort_node_id(int* node_id, int size); - -/* any size */ -/** 3x3x1 */ -void create_config_9_2d(List switch_config_list); -/** 2x2x2 */ -void create_config_8_3d(List switch_config_list); -/** 8x1x1 */ -void create_config_8_1d(List switch_config_list); -/** 2x2x1 */ -void create_config_4_2d(List switch_config_list); -/** 4x1x1 */ -void create_config_4_1d(List switch_config_list); -/** 3x1x1 */ -void create_config_3_1d(List switch_config_list); - -#endif /* _GRAPH_SOLVER_H_ */ - - diff --git a/src/partition_allocator/graph_structs.c b/src/partition_allocator/graph_structs.c deleted file mode 100644 index 08accea684f40158b7b49ed58f7f5c0846683d9d..0000000000000000000000000000000000000000 --- a/src/partition_allocator/graph_structs.c +++ /dev/null @@ -1,938 +0,0 @@ -/*****************************************************************************\ - * graph_structs.c - ***************************************************************************** - * 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> - * - * 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. -\*****************************************************************************/ - -#include <unistd.h> -#include <stdlib.h> -#include "slurm.h" -#include "graph_structs.h" - -// #define DEBUG -/** - * user must call delete_system when finished - */ -int new_system() { - if (!__initialized){ - global_sys = (system_t*) xmalloc(sizeof(system_t)); - if (!global_sys){ - printf("init_sys: error, not enough memory for the system\n"); - exit(1); - } - global_sys->node_list = list_create(delete_node); - global_sys->switch_list = list_create(delete_node); - global_sys->connection_list = list_create(delete_connection); - global_sys->partition_list = list_create(delete_partition); - - __initialized = true; - return 0; - } - return 1; -} - -/** - * create a node and initialize it's internal structures - * - * each node has 2 special connections that are only connected on one - * end to the external endpoint of a port. these special connections - * 1) already have their labels = id of the node - * 2) are already assigned to partitions. - * - */ -int new_node(node_t** node, Label id) -{ - connection_t* conn; - partition_t* part; - int i; - - if (!__initialized){ - new_system(); - } - - (*node) = (node_t*) xmalloc(sizeof(node_t)); - if (!(*node)){ - printf("error, not enough mem for more nodes\n"); - exit(1); - } - - (*node)->id = id; - (*node)->is_node = true; - (*node)->dim = NO_VAL; - for (i=0; i<NUM_PORTS_PER_NODE; i++){ - (*node)->ports[i].node = *node; - (*node)->ports[i].id = i; - (*node)->ports[i].conn_int = NULL; - (*node)->ports[i].conn_ext = NULL; - } - - /* intialize some port characteristics */ - (*node)->ports[0].type = (*node)->ports[3].type = (*node)->ports[5].type = PLUS; - (*node)->ports[1].type = (*node)->ports[2].type = (*node)->ports[4].type = MINUS; - - /** - * create the partition that will include the new node/connection connections. - */ - new_partition(&part, id); - - /** create the special connections that represent inclusion of - * the base partitions (nodes) in partitions */ - (*node)->connection_list = list_create(NULL); - - /* CONNECTION for X dimension */ - new_connection(&conn); - conn->original_id = id; - conn->id = id; - conn->place = INTERNAL; - conn->node = *node; - /* connect the endoints of the conn to the node ports */ - conn->ep0 = &((*node)->ports[0]); - conn->ep1 = &((*node)->ports[1]); - /* connect the node ports to the connection */ - (*node)->ports[0].conn_int = conn; - (*node)->ports[1].conn_int = conn; - list_append(global_sys->connection_list, conn); - list_append((*node)->connection_list, conn); - add_connection_to_partition(conn, part); - - if (SYSTEM_DIMENSIONS > 1){ - /* CONNECTION for Y dimension */ - new_connection(&conn); - conn->original_id = id; - conn->id = id; - conn->place = INTERNAL; - conn->node = *node; - /* connect the endoints of the conn to the node ports */ - conn->ep0 = &((*node)->ports[2]); - conn->ep1 = &((*node)->ports[3]); - /* connect the node ports to the connection */ - (*node)->ports[2].conn_int = conn; - (*node)->ports[3].conn_int = conn; - list_append(global_sys->connection_list, conn); - list_append((*node)->connection_list, conn); - add_connection_to_partition(conn, part); - } - - if (SYSTEM_DIMENSIONS > 2){ - /* CONNECTION for Z dimension */ - new_connection(&conn); - conn->original_id = id; - conn->id = id; - conn->place = INTERNAL; - conn->node = *node; - /* connect the endoints of the conn to the node ports */ - conn->ep0 = &((*node)->ports[4]); - conn->ep1 = &((*node)->ports[5]); - /* connect the node ports to the connection */ - (*node)->ports[4].conn_int = conn; - (*node)->ports[5].conn_int = conn; - list_append(global_sys->connection_list, conn); - add_connection_to_partition(conn, part); - list_append((*node)->connection_list, conn); - } - - /** add the partition to the global list of partitions */ - list_append(global_sys->partition_list, part); - /** add the node to the partition, and vice versa*/ - (*node)->partition = part; - add_node_to_partition(part, *node); - list_append(global_sys->node_list, *node); - - return 0; -} - -/** - * creates another type of node_t, this time a switch, and connects it - * to the master node. - */ -int new_switch(switch_t** my_switch, node_t* master, Label id, - dimension_t dim) -{ - connection_t* conn; - int i, port_numA, port_numB; - - if (!__initialized){ - new_system(); - } - - (*my_switch) = (switch_t*) xmalloc(sizeof(switch_t)); - if (!(*my_switch)){ - printf("error, not enough mem for more switches\n"); - exit(1); - } - - /* initialize the switch innards */ - (*my_switch)->id = id; - (*my_switch)->is_node = false; - (*my_switch)->dim = dim; - for (i=0; i<NUM_PORTS_PER_NODE; i++){ - (*my_switch)->ports[i].node = *my_switch; - (*my_switch)->ports[i].id = i; - (*my_switch)->ports[i].conn_int = NULL; - (*my_switch)->ports[i].conn_ext = NULL; - } - - - /* internal connections for the switch, we make 3 connections - * for each switch. - */ - /* add internal connetions to actual switches */ - (*my_switch)->connection_list = list_create(NULL); - for (i=0; i<INTERNAL_CONNECTIONS_PER_NODE; i++){ - new_connection(&conn); - conn->place = INTERNAL; - conn->node = *my_switch; - /* give the connection to the node */ - list_push((*my_switch)->connection_list, conn); - /* also give a pointer to the system */ - list_push(global_sys->connection_list, conn); - } - - /* create the set of external connections that connect the - * switch to the node - */ - - /* - * connecting a switch to a node - * ------------| |----------- - * (switch) | | (node) - * | (connection_t) | - * [conn_int]--port-[conn_ext] ==[ep0]---[ep1]== [conn_ext]-port--[conn_int] - * | | - * [conn_int]--port-[conn_ext] ==[ep0]---[ep1]== [conn_ext]-port--[conn_int] - * | | - * | | - * ------------| |----------- - */ - - /* FIXME: find some elegant way of setting this */ - /* these are the ports for the nodes, switches always use port 0-1 - * to connect to the nodes - */ - if (dim == X){ - port_numA = 0; - port_numB = 1; - } else if (dim == Y) { - port_numA = 2; - port_numB = 3; - } else {/* dim == Z */ - port_numA = 4; - port_numB = 5; - } - - /* first of the external connections from switch to node */ - new_connection(&conn); - conn->original_id = id; - conn->id = id; - conn->place = EXTERNAL; - /* connect the endoints of the conn to the node/switch ports */ - conn->ep0 = &((*my_switch)->ports[0]); - conn->ep1 = &(master->ports[port_numA]); - /* connect the node/switch ports to the connection */ - (*my_switch)->ports[0].conn_ext = conn; - master->ports[port_numA].conn_ext = conn; - list_append(global_sys->connection_list, conn); - add_connection_to_partition(conn, master->partition); - - /* second of the external connections from switch to node */ - new_connection(&conn); - conn->original_id = id; - conn->id = id; - conn->place = EXTERNAL; - /* connect the endoints of the conn to the node/switch ports */ - conn->ep0 = &((*my_switch)->ports[1]); - conn->ep1 = &(master->ports[port_numB]); - /* connect the node/switch ports to the connection */ - (*my_switch)->ports[1].conn_ext = conn; - master->ports[port_numB].conn_ext = conn; - list_append(global_sys->connection_list, conn); - add_connection_to_partition(conn, master->partition); - - list_append(global_sys->switch_list, *my_switch); - - return 0; -} - -/** - * here I could've used the listfindf thing with the list functions - * (to find the switch). - */ -switch_t* get_switch(Label node_id, dimension_t dim) -{ - ListIterator itr; - switch_t* my_switch = NULL;; - if (!global_sys->switch_list){ - printf("get_switch: Error, node_list uninitialized\n"); - return NULL; - } - - itr = list_iterator_create(global_sys->switch_list); - while((my_switch = (switch_t*) list_next(itr))){ - if (!my_switch->is_node && - my_switch->id == node_id && - my_switch->dim == dim){ - break; - } - } - list_iterator_destroy(itr); -#ifdef DEBUG -#endif - if (my_switch == NULL){ - printf("get_switch: Error, no switch with node id <%d> and dim %d\n", node_id, dim); - } - - return my_switch; -} - -/** */ -void print_node(node_t* node) -{ - connection_t* conn; - ListIterator itr = list_iterator_create(node->connection_list); - - if (node->is_node) { - printf("node_t id:\t%d\n", node->id); - } else { - printf("switch_t id:\t%d\n", node->id); - printf(" dim:\t%s\n", convert_dim(node->dim)); - } - if (node->partition) - printf(" part id:\t%d\n", node->partition->id); - else - printf(" part id:\tNULL\n"); - if (list_count(node->connection_list) != 0) - printf(" connections:\n"); - else - printf(" no connections!\n"); - while((conn = (connection_t*) list_next(itr))){ - print_connection(conn); - } - list_iterator_destroy(itr); -} - -char* convert_dim(dimension_t dim) -{ - switch(dim){ - case X: return "X"; - case Y: return "Y"; - case Z: return "Z"; - default: return "unknown"; - } -} - -/** - * delete a node and cleanly remove it's internal structures - */ -void delete_node(void* object) -{ - node_t* node = (node_t*) object; - list_destroy(node->connection_list); - xfree (node); -} - -/** - * create a connection and initialize it's internal structures - */ -int new_connection(connection_t** connection) -{ - (*connection) = (connection_t*) xmalloc(sizeof(connection_t)); - if (!(*connection)){ - printf("error, not enough mem for more connections\n"); - exit(1); - } - - (*connection)->original_id = NO_VAL; - (*connection)->id = NO_VAL; - (*connection)->place = EXTERNAL; - (*connection)->ep0 = NULL; - (*connection)->ep1 = NULL; - (*connection)->partition = NULL; - (*connection)->node = NULL; - - return 0; -} - -/** - * delete a connection - */ -void delete_connection(void* object) -{ - connection_t* connection = (connection_t*) object; - xfree(connection); -} - -/** */ -void print_connection(connection_t* conn) -{ - if (!conn){ - printf("print_connection error, connection given is NULL\n"); - return; - } - - printf("connection_t old label:\t%d\n", conn->original_id); - printf(" connection_t label:\t%d\n", conn->id); - printf(" connection_t place:\t%s\n", convert_place(conn->place)); - if (conn->place == INTERNAL && conn->node != NULL) - printf(" connection_t has node:\tTRUE\n"); - else - printf(" connection_t has node:\tFALSE\n"); - - if (conn->place == INTERNAL){ - /* print out what's connected to the first endpoint */ - if (!conn->ep0) - printf(" ep0 is NULL\n"); - else { - if (!conn->node){ - printf("print_connection error, internal connection has NULL ref to node\n"); - } - - if (conn->node->is_node){ - printf(" ep0 is connected to node "); - } else { - printf(" ep0 is connected to switch(%s) ", - convert_dim(conn->node->dim)); - } - if (conn->ep0->conn_ext) { - printf("%d port %d ext conn w/ label <%d>\n", - conn->node->id, - conn->ep0->id, conn->ep0->conn_ext->id); - } else { - printf("%d port %d ext conn is NULL\n", - conn->node->id, conn->ep0->id); - } - } - /* print out what's connected to the second endpoint */ - if (!conn->ep1) - printf(" ep1 is NULL\n"); - else { - if (!conn->node){ - printf("print_connection error, internal connection has NULL ref to node\n"); - } - - if (conn->node->is_node){ - printf(" ep1 is connected to node "); - } else { - printf(" ep1 is connected to switch(%s) ", - convert_dim(conn->node->dim)); - } - if (conn->ep1->conn_ext) { - printf("%d port %d ext conn w/ label <%d>\n", - conn->node->id, - conn->ep1->id, conn->ep1->conn_ext->id); - - } else { - printf("%d port %d ext conn is NULL\n", - conn->node->id, conn->ep1->id); - } - } - } else { - /* print out what's connected to the first endpoint */ - if (!conn->ep0) - printf(" ep0 is NULL\n"); - else { - if (!conn->ep0->node){ - printf("print_connection error, port has NULL ref to node\n"); - } - - if (conn->ep0->node->is_node){ - printf(" ep0 is connected to node "); - } else { - printf(" ep0 is connected to switch(%s) ", - convert_dim(conn->ep0->node->dim)); - } - if (conn->ep0->conn_int) { - printf("%d port %d int conn w/ label <%d>\n", - conn->ep0->node->id, - conn->ep0->id, conn->ep0->conn_int->id); - } else { - printf("%d port %d int conn is NULL\n", - conn->ep0->node->id, conn->ep0->id); - } - } - /* print out what's connected to the second endpoint */ - if (!conn->ep1) - printf(" ep1 is NULL\n"); - else { - if (!conn->ep1->node){ - printf("print_connection error, port has NULL ref to node\n"); - } - - if (conn->ep1->node->is_node){ - printf(" ep1 is connected to node "); - } else { - printf(" ep1 is connected to switch(%s) ", - convert_dim(conn->ep0->node->dim)); - } - if (conn->ep1->conn_int) { - printf("%d port %d int conn w/ label <%d>\n", - conn->ep1->node->id, - conn->ep1->id, conn->ep1->conn_int->id); - - } else { - printf("%d port %d int conn is NULL\n", - conn->ep1->node->id, conn->ep1->id); - } - } - } - - /* print out connection partition */ - if (conn->partition){ - printf(" connection is a part of partition %d\n", conn->partition->id); - } else { - printf(" connection is a not a part of a partition\n"); - } -} - - -/** */ -int new_port(port_t** port, int id) -{ - (*port) = (port_t*) xmalloc(sizeof(port_t)); - if (!(*port)){ - printf("error, not enough mem for more ports\n"); - exit(1); - } - - (*port)->node = NULL; - (*port)->id = id; - (*port)->type = PLUS; - (*port)->conn_int = NULL; - (*port)->conn_ext = NULL; - - return 0; -} - -/** */ -void delete_port(void* object) -{ - port_t* port = (port_t*) object; - xfree (port); -} - -/** */ -int new_partition(partition_t** partition, Label label) -{ - (*partition) = (partition_t*) xmalloc(sizeof(partition_t)); - if (!(*partition)){ - printf("error, not enough mem for more partitions\n"); - exit(1); - } - -#ifdef DEBUG - printf("new_partition %d\n", label); -#endif - - (*partition)->id = label; - (*partition)->num_connections = 0; - (*partition)->node_list = list_create(NULL); - (*partition)->connection_list = list_create(NULL); - // (*partition)->is_torus = true; - (*partition)->conn_type = TORUS; - return 0; -} - -/** add a node to the partition */ -int add_node_to_partition(partition_t* part, node_t* node) -{ - if (!node || !part){ - printf("add_node_to_partition: error, given node or part is NULL\n"); - return 1; - } - if (!node->is_node){ - printf("add_node_to_partition: error, given structure is not a node\n"); - return 1; - } - - /* first we see if the node is already a part of the partition */ - // if (list_find_first(part->node_list, (ListFindF) listfindf_node, node)){ - if (!node_not_in_list(part->node_list, node)){ -#ifdef DEBUG - printf("add_node_to_partition: node <%d> is already in list\n", node->id); -#endif - return 0; - } -#ifdef DEBUG - printf("add_node_to_partition: node <%d> added to list\n", node->id); -#endif - /* if not, then we go ahead and insert it */ - list_append(part->node_list, node); - return 0; -} - -/** */ -int add_connection_to_partition(connection_t* conn, partition_t* part) -{ - if (!conn || !part){ - printf("add_connection_to_partition: Error, partition or connection NULL\n"); - return 1; - } - - if (part->id != conn->id){ - printf("add_connection_to_partition: Error, partition and connection have different labels\n"); - return 1; - } - - list_append(part->connection_list, conn); - part->num_connections++; - conn->partition = part; - - /* check if this connection violates the toroidal - * property of the partition. - * - * this partition is a torus if the number of - * non-toroidal connections == 0 - */ - if (!is_node_connection(conn)){ - if (conn->place == INTERNAL){ - if (conn->ep0->conn_ext == NULL || - conn->ep1->conn_ext == NULL) { - part->conn_type = SELECT_MESH; - } - } else { - if (conn->ep0->conn_int == NULL || - conn->ep1->conn_int == NULL) { - part->conn_type = SELECT_MESH; - } - } - } - /* if this connection is part of a node (as opposed to switch) - * add the node to the partition node_list - */ - else { - add_node_to_partition(part, conn->node); - } - -#ifdef DEBUG - printf("add_connection_to_partition: added connection %d to partition %d\n", - conn->id, part->id); -#endif - - return 0; -} - -/** - * copy the partition info and make a shallow copy (only copy the mem - * addresses) of the connections - */ -void copy_partition(partition_t* old_part, partition_t** new_part) -{ - ListIterator itr; - connection_t* conn; - node_t* node; - - new_partition(new_part, old_part->id); - (*new_part)->conn_type = old_part->conn_type; - - /* copy the references from the connection list over*/ - itr = list_iterator_create(old_part->connection_list); - while((conn = (connection_t*) list_next(itr))){ - /* make sure that connection is pointing to new partition*/ - conn->partition = *new_part; - list_append((*new_part)->connection_list, conn); - } - list_iterator_destroy(itr); - - /* copy the references from the node list over*/ - itr = list_iterator_create(old_part->node_list); - while((node = (node_t*) list_next(itr))){ - list_append((*new_part)->node_list, node); - } - list_iterator_destroy(itr); -} - -/** - * - * merge the two partitions, where the smaller one is merged into the - * larger. we merge from the smaller one because hopefully that will - * take less time. if partition labels are the same, they both get - * merged into one. if both partitions addresses are the same, then - * they are the same partition and nothing happens. if both partition - * labels are different, then we merge the smallest into the largest. - * - * also removes the smaller partition from the global partition list - * - * - */ -int merge_partitions(partition_t* A, partition_t* B, List partition_list) -{ - connection_t* conn; - ListIterator itr; - partition_t* smaller_part; - partition_t* larger_part; - int sizeA, sizeB; - - if (!A || !B){ - printf("_merge_partitions: error one of the partitions NULL\n"); - return 1; - } - - /** if both addresses the same */ - if (A == B){ -#ifdef DEBUG - printf("_merge_partitions: both end partitions the same, no need to do anything\n"); -#endif - return 0; - } - - sizeA = list_count(A->node_list); - sizeB = list_count(B->node_list); - if (sizeA < 1 || sizeB < 1){ - printf("_merge_partitions: error one of the partitions has no size\n"); - return 1; - } - -#ifdef DEBUG - printf("graph_structs: merging partition %d to %d\n", A->id, B->id); -#endif - /* sort out who's bigger */ - if (sizeA < sizeB){ - smaller_part = A; - larger_part = B; - } else { - smaller_part = B; - larger_part = A; - } - - /* copy all the elements out from the smaller list to the - * larger one - */ - itr = list_iterator_create(smaller_part->connection_list); - while ((conn = (connection_t*) list_next(itr))) { - conn->id = larger_part->id; - conn->partition = larger_part; - add_connection_to_partition(conn, larger_part); - list_remove(itr); - } - list_iterator_destroy(itr); - - /** remove the old partition from the list */ - remove_partition(partition_list, smaller_part); -#ifdef DEBUG - printf("graph_structs: merging partitions done, new size of %d is %d\n", - larger_part->id, list_count(larger_part->node_list)); - - - printf("done merging, new global partition list size: %d\n", - list_count(partition_list)); -#endif - return 0; -} - -/** - * remove the partition from the list. this function removes the - * partition with the same memory location as the one given. - */ - -void remove_partition(List part_list, partition_t* rm_part) -{ - ListIterator itr; - partition_t* next_part; - int found = 0; - itr = list_iterator_create(part_list); - while ((next_part = (partition_t*) list_next(itr))) { - /* if the addresses match */ - if (next_part == rm_part){ - /* simply remove it from the list */ - list_remove(itr); - delete_partition(next_part); - found = 1; - break; - } - } - -#ifdef DEBUG - if (found){ - printf("remove_partition: partition found and removed from list\n"); - } else { - printf("remove_partition: partition NOT found in list\n"); - } -#endif -} - -/** - * note that we do _not_ clean up the node_list and connection_list, - * b/c those should get deleted when nodes and the system get - * destroyed. - */ -void delete_partition(void* object) -{ - partition_t* part = (partition_t*) object; - list_destroy(part->node_list); - list_destroy(part->connection_list); - xfree(part); - part = NULL; -} - -/** */ -void print_partition(partition_t* part) -{ - ListIterator itr; - connection_t* conn; - if (!part){ - printf("print_partition error, partition is NULL\n"); - } - - printf("partition label:\t%d\n", part->id); - printf("partition size :\t%d\n", list_count(part->node_list)); - printf("partition num conn:\t%d\n", part->num_connections); - if (part->conn_type == TORUS) - printf("partition conn type:\ttoroidal\n"); - else - printf("partition conn type:\tnon-toroidal\n"); - - itr = list_iterator_create(part->connection_list); - while((conn = (connection_t*) list_next(itr))){ - print_connection(conn); - } - list_iterator_destroy(itr); -} - -/** */ -int partition_size(partition_t* partition) -{ - if (!partition){ - printf("partition_size: Error, partition is NULL\n"); - return -1; - } - return list_count(partition->node_list); -} - -/** */ -partition_t* find_partition(List l, Label id) -{ - return (partition_t*) list_find_first(l, (ListFindF) listfindf_partition, &id); -} - -/** - * compares labels and tries to find the correct partition - */ -int listfindf_partition(partition_t* part, Label *id) -{ - return (part->id == *id); -} - -/** - * - */ -int listfindf_node(node_t* A, node_t *B) -{ - if (A->id == B->id){ - return 0; - } - return 1; -} - - -/** - * - */ -int node_not_in_list(List node_list, node_t *node) -{ - node_t *n; - ListIterator itr = list_iterator_create(node_list); - while((n = (node_t*)list_next(itr))){ - if (n->id == node->id){ - return 0; - } - } - list_iterator_destroy(itr); - return 1; -} - -/** - */ -char* convert_place(int place) -{ - if (place == INTERNAL) - return "INTERNAL"; - else - return "EXTERNAL"; -} - - -/** - */ -char* convert_conn_type(conn_type_t conn_type) -{ - return (conn_type == TORUS) ? "T" : "M"; -} - -/** */ -void delete_system() -{ - list_destroy(global_sys->node_list); - list_destroy(global_sys->switch_list); - list_destroy(global_sys->connection_list); - list_destroy(global_sys->partition_list); - xfree(global_sys); - __initialized = false; -} - -/** returns true if this is a "node" connection */ -bool is_node_connection(connection_t* conn) -{ - /* only if the connection is internal does it have a - * pointer to its node - */ - if (conn->place == INTERNAL && - conn->node != NULL && - conn->node->is_node) - return true; - else - return false; -} - -/** */ -void delete_gen(void* object) -{ - xfree(object); -} - -void new_switch_config(switch_config_t* config, Label id, dimension_t dim, - Label node_src, int port_src, - Label node_tar, int port_tar) -{ - - config->id = id; - config->dim = dim; - config->node_src = node_src; - config->port_src = port_src; - config->node_tar = node_tar; - config->port_tar = port_tar; -} - -void delete_switch_config(void* object) -{ - - switch_config_t* conf = (switch_config_t*) object; - xfree(conf); -} - -/** - */ -void print_switch_config(switch_config_t* config) -{ - printf("switch_config id:\t%d\n", config->id); - printf(" dim:\t%d\n", config->dim); - printf(" source:\t%d: %d \n", config->node_src, config->port_src); - printf(" target:\t%d: %d \n", config->node_tar, config->port_tar); -} diff --git a/src/partition_allocator/graph_structs.h b/src/partition_allocator/graph_structs.h deleted file mode 100644 index c2e9cce27fa312ef7185e4059f12c7e89b3da969..0000000000000000000000000000000000000000 --- a/src/partition_allocator/graph_structs.h +++ /dev/null @@ -1,293 +0,0 @@ -/*****************************************************************************\ - * graph_structs.h - ***************************************************************************** - * 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> - * - * 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. -\*****************************************************************************/ - -#ifndef _GRAPH_STRUCTS_H_ -#define _GRAPH_STRUCTS_H_ - -/* for use of lists */ -#include "src/common/list.h" -/* for bool */ -#include "src/common/macros.h" -/* malloc and free, but safer */ -#include "src/common/xmalloc.h" - -#ifndef NO_VAL -#define NO_VAL -2 -#endif -#define PA_SYSTEM_DIMENSIONS 3 -#define NUM_PORTS_PER_NODE 6 -#define NUM_ENDPOINTS_PER_CONNECTION 2 -#define NUM_CONNECTIONS_PER_PORT 2 -#define INTERNAL_CONNECTIONS_PER_NODE NUM_PORTS_PER_NODE/2 - -#ifndef SYSTEM_DIMENSIONS -// #undef SYSTEM_DIMENSIONS -#define SYSTEM_DIMENSIONS 1 // 999 -#endif - -/* a connection could be an internal or external wire */ -typedef enum placement {INTERNAL, EXTERNAL} placement_t; -/* a port could be of type PLUS or MINUS */ -enum type_t {PLUS, MINUS}; -/* dimensionality */ -typedef enum dimension_type {X, Y, Z} dimension_t; - -/* */ -typedef enum conn_type {MESH, TORUS} conn_type_t; - - typedef int Label; -// typedef int dimension_t; - -bool __initialized; -/** - * - * A system is composed of a set of nodes connected by a set of - * external connections. - * - */ -typedef struct system -{ - List node_list; - List switch_list; - List connection_list; - List partition_list; -} system_t; -system_t* global_sys; - -/** - * A connection can either be internal or external to a node and has - * two endpoints and a label. The label informs what partition it is - * a part of. - */ -typedef struct connection -{ - Label original_id; - Label id; - int place; /* internal or external, see enum placement */ - struct port* ep0; - struct port* ep1; - struct partition* partition; /** a link to the corresponding partition */ - struct node* node; /* pointer to the node we belong to, if INTERNAL */ -} connection_t; - -/** - * A port is the junction for connections that allows one connection - * to connect to another. - * - * if the port is connected to the base partition compute nodes, - * meaning ports 0,1, then the external connections will be special - * ones such that the other ends (of the connection) are NULL && and - * the label of that connection is set to BPXXX, where XXX = the - * coordinates of the partition. - */ -typedef struct port -{ - struct node* node; - int id; - int type; - connection_t* conn_int; - connection_t* conn_ext; -} port_t; - -/** - * a "node" both a BGL base partition (BP) or a switch, depending on - * whether is_node is set. - * - * - * NODE schematic: currently hard wired for 3 dims - * - * /---|---|---\ - * | 5 4 | - * | \---/ | - * | /-3- - * | | | - * | \-2- - * | /---\ | - * | 0 1 | - * \---|---|---/ - * - * SWITCH schematic - * - * 0 1 - * /--|--|--\ - * | | - * 5 - - 2 - * | | - * \__|__|__/ - * 4 3 - - */ -typedef struct node -{ - /* unique id for this node */ - Label id; - /** - * list of internal connections belonging to this node - */ - List connection_list; - - /** - * list of ports of this node - */ - // List port_list; - port_t ports[NUM_PORTS_PER_NODE]; - - /** true if this is node, else this represents a switch */ - bool is_node; - - /** partition that this node belongs to */ - struct partition* partition; - - /* if this node is !is_node => switch_t, then dimension applies*/ - dimension_t dim; - -} node_t; -typedef node_t switch_t; - -/** - * structure that holds the configuration settings for each switch - * - * - dimension - * - from node, to node - * - from port, to port - * - */ -typedef struct switch_config -{ - /* might get used...*/ - Label id; - - /* dimension */ - dimension_t dim; - int *node_src; // source - int *node_tar; // target - int port_src; - int port_tar; - -} switch_config_t; - -/** - * - */ -typedef struct partition -{ - /* */ - Label id; - /* for debugging */ - int num_connections; - /* */ - List node_list; - /* */ - List connection_list; - /* true if no non-toridal connections included in partition */ - // bool is_torus; - conn_type_t conn_type; - -} partition_t; - -/** creator/destructor fxns */ - -/** */ -// int new_node(node_t** node, char* id); -int new_node(node_t** node, Label id); -/** */ -int new_switch(switch_t** node, node_t* master, Label id, - dimension_t dim); -/** */ -switch_t* get_switch(Label node_id, dimension_t dim); -/** */ -void delete_node(void* object); -/** */ -void print_node(node_t* node); -/** returns true if this is a "node" connection */ -bool is_node_connection(connection_t* conn); -/** - * compares memory address of the nodes - */ -int listfindf_node(node_t* A, node_t *B); -int node_not_in_list(List node_list, node_t *node); - -/** */ -int new_connection(connection_t** connection); -/** */ -void delete_connection(void* object); -/** */ -void print_connection(connection_t* conn); - -/** */ -int new_port(port_t** port, int id); -/** */ -void delete_port(void* object); - -/** */ -int new_partition(partition_t** partition, Label id); -/** */ -int add_node_to_partition(partition_t* part, node_t* node); -/** */ -int add_connection_to_partition(connection_t* connection, partition_t* partition); -/** */ -void copy_partition(partition_t* old_part, partition_t** new_part); -/** */ -int merge_partitions(partition_t* A, partition_t* B, List partition_list); -/** */ -void delete_partition(void* object); -/** */ -void print_partition(partition_t* partition); -/** */ -partition_t* find_partition(List l, Label id); -/** */ -int partition_size(partition_t* partition); -/** - * compares labels and tries to find the correct partition - */ -int listfindf_partition(partition_t* part, Label *id); - -/** */ -int new_system(); -/** */ -void delete_system(); - -/** */ -char* convert_conn_type(conn_type_t conn_type); - -char* convert_place(int place); -/** remove the given partition address from the list of partitions */ -void remove_partition(List part_list, partition_t* part); - -/** free a generic object (ie, char*, int*, config_t*) */ -void delete_gen(void* object); - -char* convert_dim(dimension_t dim); - -/** */ -void new_switch_config(switch_config_t* config, Label id, dimension_t dim, - Label node_src, int port_src, - Label node_tar, int port_tar); -/** */ -void delete_switch_config(void* object); -/** */ -void print_switch_config(switch_config_t* config); - -#endif /* _GRAPH_STRUCTS_H_ */ diff --git a/src/partition_allocator/partition_allocator.c b/src/partition_allocator/partition_allocator.c index a38bf70ccfe11067dfbbebe19845b6b01da6a107..c1cd5d481e9ded4eaa4eb5d4183c7582fbce950a 100644 --- a/src/partition_allocator/partition_allocator.c +++ b/src/partition_allocator/partition_allocator.c @@ -53,7 +53,7 @@ int color_count = 0; /** internal helper functions */ /** */ static void _new_pa_node(pa_node_t *pa_node, - int coordinates[PA_SYSTEM_DIMENSIONS]); + int *coord); /** */ //static void _print_pa_node(pa_node_t* pa_node); /** */ @@ -79,11 +79,7 @@ static void _set_external_wires(int dim, int count, pa_node_t* source, pa_node_t* target_first, pa_node_t* target_second); /* */ static char *_set_internal_wires(List nodes, int size, int conn_type); -/* */ -#if 0 -static int _set_internal_port(pa_switch_t *curr_switch, int check_port, - int *coord, int dim); -#endif + /* */ static int _find_one_hop(pa_switch_t *curr_switch, int source_port, int *target, int *target2, int dim); @@ -97,6 +93,8 @@ static int _configure_dims(int *coord, int *start, int *end); /* */ static int _set_one_dim(int *start, int *end, int *coord); +static int _append_geo(int *geo, List geos, int rotate); + /** * create a partition request. Note that if the geometry is given, * then size is ignored. @@ -117,116 +115,170 @@ int new_pa_request(pa_request_t* pa_request) int i, i2, i3, picked, total_sz=1 , size2, size3; float sz=1; int checked[8]; + int *geo_ptr; + int geo[PA_SYSTEM_DIMENSIONS] = {0,0,0}; + ListIterator itr; 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]; - - /* size will be overided by geometry size if given */ - if (pa_request->geometry[0] != -1){ + if(geo[0] != -1) { for (i=0; i<PA_SYSTEM_DIMENSIONS; i++){ - if ((pa_request->geometry[i] < 1) - || (pa_request->geometry[i] > DIM_SIZE[i])){ + if ((geo[i] < 1) + || (geo[i] > DIM_SIZE[i])){ printf("new_pa_request Error, request geometry is invalid\n"); return 0; } } - } else { + _append_geo(geo, pa_request->elongate_geos, pa_request->rotate); + 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]; - pa_request->geometry[i] = 1; + geo[i] = 1; } - - if(pa_request->size==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); + } if(pa_request->size>total_sz || pa_request->size<1) { printf("new_pa_request ERROR, requested size must be\ngreater than 0 and less than %d.\n",total_sz); return 0; } - + 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); + + } + _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; } - size3=pa_request->size; + if(i<PA_SYSTEM_DIMENSIONS-1) { - i3=i; /* we found something that looks like a cube! */ - for (i=0; i<PA_SYSTEM_DIMENSIONS-i3; i++) { - if(sz<=DIM_SIZE[i]) { - pa_request->geometry[i] = sz; - size3 /= sz; - picked++; - } else - goto tryagain; - } - } else { - 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) { - pa_request->geometry[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]) - pa_request->geometry[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 { - pa_request->geometry[i] = sz; - break; - } - } - } - } + 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; + _append_geo(geo, pa_request->elongate_geos, pa_request->rotate); + } + } + + 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]; + printf("picking %d%d%d\n",pa_request->geometry[X],pa_request->geometry[Y],pa_request->geometry[Z]); + sz=1; for (i=0; i<PA_SYSTEM_DIMENSIONS; i++) sz *= pa_request->geometry[i]; endit: pa_request->size = sz; - - //printf("geometry: %d %d %d size = %d\n", pa_request->geometry[0],pa_request->geometry[1],pa_request->geometry[2], pa_request->size); - return 1; } @@ -235,8 +287,14 @@ endit: */ 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); } @@ -391,9 +449,6 @@ void pa_set_node_down(int c[PA_SYSTEM_DIMENSIONS]) printf("pa_set_node_down: node to set down: [%d%d%d]\n", c[0], c[1], c[2]); #endif - /* first we make a copy of the current system */ - // _backup_pa_system(); - /* basically set the node as used */ pa_system_ptr->grid[c[0]][c[1]][c[2]].used = true; } @@ -423,10 +478,10 @@ int allocate_part(pa_request_t* pa_request, List results) // _backup_pa_system(); if (_find_match(pa_request, results)){ - //printf("hey I am returning 1\n"); + printf("hey I am returning 1\n"); return 1; } else { - //printf("hey I am returning 0\n"); + printf("hey I am returning 0\n"); return 0; } } @@ -569,6 +624,20 @@ int set_bgl_part(List nodes, int size, int conn_type) _set_internal_wires(nodes, size, conn_type); return 1; } + +int reset_pa_system() +{ + int x, 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++) { + int coord[PA_SYSTEM_DIMENSIONS] = {x,y,z}; + _new_pa_node(&pa_system_ptr->grid[x][y][z], coord); + } + + return 1; +} /* _init_grid - set values of every grid point */ void init_grid(node_info_msg_t * node_info_ptr) { @@ -588,7 +657,9 @@ void init_grid(node_info_msg_t * node_info_ptr) 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); + 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) || @@ -616,8 +687,14 @@ void init_grid(node_info_msg_t * node_info_ptr) } z = 0; for (x = 0; x < pa_system_ptr->num_of_proc; x++) { - y = x % (sizeof(letter_array) - 1); - pa_system_ptr->fill_in_value[x].letter = letter_array[y]; + if (y == 91) + y = 97; + else if(y == 123) + y = 48; + else if(y == 58) + y = 65; + pa_system_ptr->fill_in_value[x].letter = y; + if(z == 4) z++; z = z % 7; @@ -631,12 +708,11 @@ void init_grid(node_info_msg_t * node_info_ptr) } /** */ -static void _new_pa_node(pa_node_t *pa_node, int coord[PA_SYSTEM_DIMENSIONS]) +static void _new_pa_node(pa_node_t *pa_node, int *coord) { int i,j; pa_node->used = false; - - // pa_node = (pa_node_t*) xmalloc(sizeof(pa_node_t)); + for (i=0; i<PA_SYSTEM_DIMENSIONS; i++){ pa_node->coord[i] = coord[i]; @@ -699,7 +775,7 @@ static void _create_pa_system(void) static void _delete_pa_system(void) { int x, y; - + if (!pa_system_ptr){ return; } @@ -709,6 +785,7 @@ static void _delete_pa_system(void) xfree(pa_system_ptr->grid[x][y]); xfree(pa_system_ptr->grid[x]); } + xfree(pa_system_ptr->grid); xfree(pa_system_ptr->fill_in_value); xfree(pa_system_ptr); @@ -717,16 +794,20 @@ static void _delete_pa_system(void) static int _check_for_options(pa_request_t* pa_request) { int temp; + int set=0; + int *geo; + ListIterator itr; + if(pa_request->rotate) { - //printf("Rotating! %d%d%d \n",pa_request->geometry[X], - // pa_request->geometry[Y],pa_request->geometry[Z]); + rotate_again: + //printf("Rotating! %d\n",pa_request->rotate_count); + if (pa_request->rotate_count==(PA_SYSTEM_DIMENSIONS-1)) { - //printf("Special!\n"); temp=pa_request->geometry[X]; pa_request->geometry[X]=pa_request->geometry[Z]; pa_request->geometry[Z]=temp; pa_request->rotate_count++; - return 1; + set=1; } else if(pa_request->rotate_count<(PA_SYSTEM_DIMENSIONS*2)) { temp=pa_request->geometry[X]; @@ -734,15 +815,46 @@ static int _check_for_options(pa_request_t* pa_request) pa_request->geometry[Y]=pa_request->geometry[Z]; pa_request->geometry[Z]=temp; pa_request->rotate_count++; - return 1; + 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 && pa_request->elongate_count<PA_SYSTEM_DIMENSIONS) { + if(pa_request->elongate) { + elongate_again: + //printf("Elongating! %d\n",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++; - printf("Elongating! not working yet\n"); - return 0; + 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]) { + printf("picking %d%d%d\n",pa_request->geometry[X],pa_request->geometry[Y],pa_request->geometry[Z]); + + return 1; + } else + goto elongate_again; + } return 0; } @@ -754,119 +866,104 @@ static int _find_match(pa_request_t *pa_request, List results) { int x=0, y=0, z=0; int *geometry = pa_request->geometry; - int start_x=0, start_y=0, start_z=0; - int find_x=0, find_y=0, find_z=0; + int start[PA_SYSTEM_DIMENSIONS] = {0,0,0}; + int find[PA_SYSTEM_DIMENSIONS] = {0,0,0}; pa_node_t* pa_node; int found_one=0; char *name=NULL; start_again: - //printf("starting looking for a grid of %d%d%d\n",pa_request->geometry[X],pa_request->geometry[Y],pa_request->geometry[Z]); - //printf("\n"); - for (z=0; z<geometry[Z]; z++) { + for (x=0; x<geometry[X]; x++) { for (y=0; y<geometry[Y]; y++) { - for (x=0; x<geometry[X]; x++) { - pa_node = &pa_system_ptr->grid[find_x][find_y][find_z]; + 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)) { - - //printf("Yeap, I found one at %d%d%d\n", find_x, find_y, find_z); - //_insert_result(results, pa_node); + // printf("found at %d%d%d\n",find[X],find[Y],find[Z]); list_append(results, pa_node); - find_x++; + find[Z]++; found_one=1; + //printf("next %d%d%d\n",find[X],find[Y],find[Z]); } else { - //printf("hey I am used! %d%d%d\n", find_x, find_y, find_z); if(found_one) { list_destroy(results); results = list_create(NULL); found_one=0; } - if((DIM_SIZE[X]-find_x-1)>=geometry[X]) { - find_x++; - start_x=find_x; + + if((DIM_SIZE[Z]-find[Z]-1)>=geometry[Z]) { + find[Z]++; + start[Z]=find[Z]; } else { - find_x=0; - start_x=find_x; - if((DIM_SIZE[Y]-find_y-1)>=geometry[Y]) { - /* if(find_y<(DIM_SIZE[Y]-1)) { */ - //find_y=0; - //printf("incrementing find_y from %d to %d\n",find_z,find_z+1); - find_y++; - start_y=find_y; + 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[Z]-find_z-1)>=geometry[Z]) { - /* if (find_z<(DIM_SIZE[Z]-1)) { */ - find_z++; - start_z=find_z; - //printf("incrementing find_Z from %d to %d\n",find_y,find_y+1); + find[Y]=0; + start[Y]=find[Y]; + if ((DIM_SIZE[X]-find[X]-1)>=geometry[X]) { + find[X]++; + start[X]=find[X]; } else { - //printf("couldn't find it\n"); 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; + find[X]=0; + find[Y]=0; + find[Z]=0; + start[X]=0; + start[Y]=0; + start[Z]=0; goto start_again; } } } - //printf("x= %d, y= %d, z= %d\n", x, y, z); } goto start_again; } } - //printf("looking at %d%d%d\n",x,y,z); - find_x=start_x; + find[Z]=start[Z]; if(y<(geometry[Y]-1)) { - if(find_y<(DIM_SIZE[Y]-1)) { - find_y++; + 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; + find[X]=0; + find[Y]=0; + find[Z]=0; + start[X]=0; + start[Y]=0; + start[Z]=0; goto start_again; } } } - //start_y=find_y; } - find_y=start_y; - if(z<(geometry[Z]-1)) { - if(find_z<(DIM_SIZE[Z]-1)) { - find_z++; + 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; + find[X]=0; + find[Y]=0; + find[Z]=0; + start[X]=0; + start[Y]=0; + start[Z]=0; goto start_again; } } } - //start_z=find_z; } if(found_one) { - /** THIS IS where we might should call the graph - * solver to see if the allocation can be wired, - * before returning a definitive TRUE */ if(pa_request->conn_type==TORUS) name = _set_internal_wires(results, pa_request->size, TORUS); else @@ -891,8 +988,6 @@ static bool _node_used(pa_node_t* pa_node, int *geometry) int i=0; pa_switch_t* pa_switch; - - /* printf("_node_used: node to check against %s %d\n", convert_dim(dim), cur_node_id); */ /* if we've used this node in another partition already */ if (!pa_node || pa_node->used) return true; @@ -1046,7 +1141,6 @@ static void _set_external_wires(int dim, int count, pa_node_t* source, static char *_set_internal_wires(List nodes, int size, int conn_type) { pa_node_t* pa_node[size+1]; - //pa_switch_t *next_switch; int count=0, i, set=0; int *start; int *end; @@ -1062,10 +1156,8 @@ static char *_set_internal_wires(List nodes, int size, int conn_type) start = pa_node[0]->coord; end = pa_node[count-1]->coord; - //printf("hey %d\n",count); sprintf(name, "%d%d%dx%d%d%d",start[0],start[1],start[2],end[0],end[1],end[2]); - //printf("the name = %s\n",name); - + for(i=0;i<count;i++) { if(!pa_node[i]->used) { if(size!=1) @@ -1075,6 +1167,7 @@ static char *_set_internal_wires(List nodes, int size, int conn_type) if(pa_node[i]->letter == '.') { pa_node[i]->letter = pa_system_ptr->fill_in_value[color_count].letter; + pa_node[i]->color = pa_system_ptr->fill_in_value[color_count].color; set=1; @@ -1085,69 +1178,15 @@ static char *_set_internal_wires(List nodes, int size, int conn_type) } } - //printf("Start = %d%d%d, End = %d%d%d\n",start[X],start[Y],start[Z],end[X],end[Y],end[Z]); for(i=0;i<count;i++) { _set_one_dim(start, end, pa_node[i]->coord); } if(set) color_count++; -/* int i; */ -/* itr = list_iterator_create(nodes); */ -/* while((pa_node = (pa_node_t*) list_next(itr))){ */ -/* for(i=0;i<PA_SYSTEM_DIMENSIONS;i++) { */ -/* printf("dim %d O set %d -> %d - %d%d%d\n",i,pa_node->axis_switch[i].int_wire[0].port_tar, pa_node->axis_switch[i].ext_wire[pa_node->axis_switch[i].int_wire[0].port_tar].port_tar, pa_node->axis_switch[i].ext_wire[pa_node->axis_switch[i].int_wire[0].port_tar].node_tar[X],pa_node->axis_switch[i].ext_wire[pa_node->axis_switch[i].int_wire[0].port_tar].node_tar[Y],pa_node->axis_switch[i].ext_wire[pa_node->axis_switch[i].int_wire[0].port_tar].node_tar[Z]); */ -/* printf("dim %d 1 set %d -> %d - %d%d%d\n",i,pa_node->axis_switch[i].int_wire[1].port_tar, pa_node->axis_switch[i].ext_wire[pa_node->axis_switch[i].int_wire[1].port_tar].port_tar, pa_node->axis_switch[i].ext_wire[pa_node->axis_switch[i].int_wire[1].port_tar].node_tar[X],pa_node->axis_switch[i].ext_wire[pa_node->axis_switch[i].int_wire[1].port_tar].node_tar[Y],pa_node->axis_switch[i].ext_wire[pa_node->axis_switch[i].int_wire[1].port_tar].node_tar[Z]); */ -/* } */ -/* for(i=0;i<NUM_PORTS_PER_NODE;i++) { */ -/* printf("Port %d -> %d Used = %d\n",i,pa_node->axis_switch[X].int_wire[i].port_tar,pa_node->axis_switch[X].int_wire[i].used); */ -/* } */ - -/* } */ -/* list_iterator_destroy(itr); */ return name; } -#if 0 -static int _set_internal_port(pa_switch_t *curr_switch, int check_port, - int *coord, int dim) -{ - pa_switch_t *next_switch; - int port_tar; - int source_port=1; - int target_port=0; - int *node_tar; - - if(!(check_port%2)) { - source_port=0; - target_port=1; - } - - /* if(coord[X]==0 && coord[Y]==2 && coord[Z]==0) { */ -/* printf("1 hey I am messing with it right here! dim %d %d -> %d\n", dim,source_port,check_port); */ -/* } */ - curr_switch->int_wire[source_port].used = 1; - curr_switch->int_wire[source_port].port_tar = check_port; - curr_switch->int_wire[check_port].used = 1; - curr_switch->int_wire[check_port].port_tar = source_port; - - node_tar = curr_switch->ext_wire[check_port].node_tar; - port_tar = curr_switch->ext_wire[check_port].port_tar; - next_switch = &pa_system_ptr-> - grid[node_tar[X]][node_tar[Y]][node_tar[Z]].axis_switch[dim]; - /* if(node_tar[X]==0 && node_tar[Y]==2 && node_tar[Z]==0) { */ -/* printf("1 %d%d%d hey I am messing with it right here! dim %d %d -> %d\n",coord[X], coord[Y], coord[Z], dim,source_port,check_port); */ -/* printf("2 hey I am messing with it right here! dim %d %d -> %d\n", dim,port_tar,target_port); */ -/* } */ - next_switch->int_wire[port_tar].used = 1; - next_switch->int_wire[port_tar].port_tar = port_tar; - next_switch->int_wire[target_port].used = 1; - next_switch->int_wire[target_port].port_tar = port_tar; - - return 1; -} -#endif - static int _find_one_hop(pa_switch_t *curr_switch, int source_port, int *target, int *target2, int dim) { @@ -1169,8 +1208,6 @@ static int _find_one_hop(pa_switch_t *curr_switch, int source_port, /* 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; - /* if(dim==Z) */ -/* printf("I am at %d%d%d port %d looking at %d%d%d port %d, looking for %d%d%d port %d\n",curr_switch->int_wire[0].node_tar[X],curr_switch->int_wire[0].node_tar[Y],curr_switch->int_wire[0].node_tar[Z],source_port,node_tar[X],node_tar[Y],node_tar[Z],ports_to_try[i],target[X],target[Y],target[Z],target_port); */ if((node_tar[X]==target[X] && node_tar[Y]==target[Y] && node_tar[Z]==target[Z]) || (node_tar[X]==target2[X] && node_tar[Y]==target2[Y] && node_tar[Z]==target2[Z])) { curr_switch->int_wire[source_port].used = 1; @@ -1185,23 +1222,11 @@ static int _find_one_hop(pa_switch_t *curr_switch, int source_port, 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; - /* if(dim!=X) */ -/* printf("I choose this combo %d -> %d\n", source_port, ports_to_try[i]); */ return 1; } } } -/* printf("suck, I didn't find it in one hop dim = %d from port %d\n",dim,source_port); */ -/* printf("targets from %d%d%d are %d%d%d and %d%d%d\n", */ -/* node_tar[X], */ -/* node_tar[Y], */ -/* node_tar[Z], */ -/* target[X], */ -/* target[Y], */ -/* target[Z], */ -/* target2[X], */ -/* target2[Y], */ -/* target2[Z]); */ + return 0; } @@ -1246,13 +1271,7 @@ static int _find_best_path(pa_switch_t *start, int source_port, int *target, //printf("count = %d\n",count); itr = list_iterator_create(path); while((path_switch = (pa_path_switch_t*) list_next(itr))){ - /* if(dim == Y) */ -/* printf("%d%d%d %d - %d\n", */ -/* path_switch->geometry[X], */ -/* path_switch->geometry[Y], */ -/* path_switch->geometry[Z], */ -/* path_switch->in, */ -/* path_switch->out); */ + temp_switch = (pa_path_switch_t *) xmalloc(sizeof(pa_path_switch_t)); temp_switch->geometry[X] = path_switch->geometry[X]; @@ -1278,7 +1297,7 @@ static int _find_best_path(pa_switch_t *start, int source_port, int *target, if(!start->int_wire[ports_to_try[i]].used) { itr = list_iterator_create(path); while((path_switch = (pa_path_switch_t*) list_next(itr))){ - //printf("%d%d%d %d%d%d %d %d - %d\n", path_switch->geometry[X], path_switch->geometry[Y], path_switch->geometry[Z], node_src[X], node_src[Y], node_src[Z], ports_to_try[i], path_switch->in, path_switch->out); + if(((path_switch->geometry[X] == node_src[X]) && (path_switch->geometry[Y] == node_src[Y]) && (path_switch->geometry[Z] == node_tar[Z]))) { @@ -1300,10 +1319,8 @@ static int _find_best_path(pa_switch_t *start, int source_port, int *target, count++; path_add->out = ports_to_try[i]; list_push(path, path_add); - //printf("%d%d%d %d - %d\n", path_add->geometry[X], path_add->geometry[Y], path_add->geometry[Z], path_add->in, path_add->out); _find_best_path(next_switch, port_tar, target, target2, dim, count); - //printf("popping %d%d%d %d - %d\n", path_add->geometry[X], path_add->geometry[Y], path_add->geometry[Z], path_add->in, path_add->out); while(list_pop(path) != path_add){ } } @@ -1321,17 +1338,13 @@ static int _set_best_path(void) itr = list_iterator_create(best_path); while((path_switch = (pa_path_switch_t*) list_next(itr))) { - //if(path_switch->dim==Z) - //printf("final %d%d%d %d - %d\n", path_switch->geometry[X], path_switch->geometry[Y], path_switch->geometry[Z], path_switch->in, path_switch->out); curr_switch = &pa_system_ptr-> grid [path_switch->geometry[X]] [path_switch->geometry[Y]] [path_switch->geometry[Z]]. axis_switch[path_switch->dim]; - /* if(path_switch->geometry[X]==0 && path_switch->geometry[Y]==2 && path_switch->geometry[Z]==0) { */ -/* printf("hey I am messing with it right here! dim %d %d -> %d\n",path_switch->dim,path_switch->in,path_switch->out); */ -/* } */ + curr_switch->int_wire[path_switch->in].used = 1; curr_switch->int_wire[path_switch->in].port_tar = path_switch->out; @@ -1406,7 +1419,8 @@ static int _configure_dims(int *coord, int *start, int *end) } else if(coord[dim]==(end[dim]-1)) { /* if(dim == Y) { */ -/* printf("hey I am looking at %d%d%d as a target from %d%d%d\n",target[X],target[Y],target[Z],coord[X],coord[Y],coord[Z]); */ +/* printf("hey I am looking at %d%d%d as a target from %d%d%d\n", + target[X],target[Y],target[Z],coord[X],coord[Y],coord[Z]); */ /* } */ @@ -1445,13 +1459,55 @@ static int _set_one_dim(int *start, int *end, int *coord) } return 1; } + +static int _append_geo(int *geometry, List geos, int rotate) +{ + ListIterator itr; + int *geo_ptr; + int *geo; + 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]; + + printf("pushing %d%d%d\n",geometry[X],geometry[Y],geometry[Z]); + list_append(geos, geo); + } + 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)); - time_t start, end; + List results; // List results2; // int i,j; @@ -1464,29 +1520,48 @@ int main(int argc, char** argv) request->co_proc = true; request->geometry[0]=-1; //printf("geometry: %d %d %d size = %d\n", request->geometry[0], request->geometry[1], request->geometry[2], request->size); -#ifdef HAVE_SLURM - error_code = slurm_load_node((time_t) NULL, &node_info_ptr, 0); - if (error_code) { - slurm_perror("slurm_load_node"); - exit(0); - } else { - pa_init(node_info_ptr); - } -/* #else */ -/* printf("This will only run on a BGL system right now.\n"); */ -/* exit(0); */ -#endif +/* #ifdef HAVE_SLURM */ +/* error_code = slurm_load_node((time_t) NULL, &node_info_ptr, 0); */ +/* if (error_code) { */ +/* slurm_perror("slurm_load_node"); */ +/* exit(0); */ +/* } else { */ +/* pa_init(node_info_ptr); */ +/* } */ +/* /\* #else *\/ */ +/* /\* printf("This will only run on a BGL system right now.\n"); *\/ */ +/* /\* exit(0); *\/ */ +/* #endif */ pa_init(NULL); results = list_create(NULL); - request->geometry[0] = 1; - request->geometry[1] = 3; - request->geometry[2] = 1; - request->size = -1; //atoi(argv[1]); + request->geometry[0] = -1; + request->size = 16; //atoi(argv[1]); new_pa_request(request); - time(&start); print_pa_request(request); allocate_part(request, results); - time(&end); + + results = list_create(NULL); + request->geometry[0] = -1; + request->size = 8; //atoi(argv[1]); + new_pa_request(request); + print_pa_request(request); + allocate_part(request, results); + +/* results = list_create(NULL); */ +/* request->geometry[0] = -1; */ +/* request->size = 12; //atoi(argv[1]); */ +/* new_pa_request(request); */ +/* print_pa_request(request); */ +/* allocate_part(request, results); */ + +/* results = list_create(NULL); */ +/* request->geometry[0] = -1; */ +/* request->size = 4; //atoi(argv[1]); */ +/* new_pa_request(request); */ +/* print_pa_request(request); */ +/* if(!allocate_part(request, results)) */ +/* printf("Hey, I didn't allocate\n"); */ + //printf("allocate_part: %ld\n", (end-start)); /* //list_destroy(results); */ /* printf("name = %s\n",request->save_name); */ @@ -1539,27 +1614,34 @@ int main(int argc, char** argv) /* allocate_part(request, results); */ /* list_destroy(results); */ - int dim,j; - int x,y,z; - int startx=0; - int starty=0; - int startz=0; - int endx=0; - int endy=3; - int endz=0; - for(x=startx;x<=endx;x++) { - for(y=starty;y<=endy;y++) { - for(z=startz;z<=endz;z++) { - printf("Node %d%d%d Used = %d Letter = %c\n",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++) { - printf("Dim %d\n",dim); - pa_switch_t *wire = &pa_system_ptr->grid[x][y][z].axis_switch[dim]; - for(j=0;j<6;j++) - printf("\t%d -> %d -> %d Used = %d\n", j, wire->int_wire[j].port_tar, wire->ext_wire[wire->int_wire[j].port_tar].port_tar, wire->int_wire[j].used); - } - } - } - } +/* int dim,j; */ +/* int x,y,z; */ +/* int startx=0; */ +/* int starty=0; */ +/* int startz=0; */ +/* int endx=0; */ +/* int endy=3; */ +/* int endz=0; */ +/* for(x=startx;x<=endx;x++) { */ +/* for(y=starty;y<=endy;y++) { */ +/* for(z=startz;z<=endz;z++) { */ +/* printf("Node %d%d%d Used = %d Letter = %c\n", */ +/* 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++) { */ +/* printf("Dim %d\n",dim); */ +/* pa_switch_t *wire = */ +/* &pa_system_ptr-> */ +/* grid[x][y][z].axis_switch[dim]; */ +/* for(j=0;j<6;j++) */ +/* printf("\t%d -> %d -> %d Used = %d\n", */ +/* j, wire->int_wire[j].port_tar, */ +/* wire->ext_wire[wire->int_wire[j].port_tar].port_tar, */ +/* wire->int_wire[j].used); */ +/* } */ +/* } */ +/* } */ +/* } */ list_destroy(results); //list_destroy(results2); @@ -1576,4 +1658,6 @@ int main(int argc, char** argv) return 0; } + + #endif diff --git a/src/partition_allocator/partition_allocator.h b/src/partition_allocator/partition_allocator.h index 471fea1c8d240d9cedce3b127783905b77b68345..48e457ba5cd67998764e048a12b9d019e1a10350 100644 --- a/src/partition_allocator/partition_allocator.h +++ b/src/partition_allocator/partition_allocator.h @@ -93,6 +93,7 @@ typedef struct { bool elongate; bool force_contig; bool co_proc; + List elongate_geos; } pa_request_t; /** @@ -252,6 +253,8 @@ int redo_part(List nodes, int conn_type, int new_count); int set_bgl_part(List nodes, int size, int conn_type); +int reset_pa_system(); + void init_grid(node_info_msg_t *node_info_ptr); #endif /* _PARTITION_ALLOCATOR_H_ */