/** * Associates the specified value with the specified key in this map. * * If the map previously contained a mapping for the key, the old value is replaced by the specified value. * (A map m is said to contain a mapping for a key k if and only if pblMapContainsKey(k) would return true.) * * For hash maps this method has a time complexity of O(1). * For tree maps this method has a time complexity of O(Log N). * * @return int rc > 0: The map did not already contain a mapping for the key. * @return int rc == 0: The map did already contain a mapping for the key. * @return int rc < 0: An error, see pbl_errno: * * <BR>PBL_ERROR_OUT_OF_MEMORY - Out of memory. * <BR>PBL_ERROR_OUT_OF_BOUNDS - Maximum capacity of the hash set exceeded. */ int pblMapAdd( /* */ PblMap * map, /** The map to add to */ void * key, /** Key to add a mapping for */ size_t keyLength, /** Length of the key */ void * value, /** Value of the new mapping */ size_t valueLength /** Length of the value */ ) { int rc; PblMapEntry * mapEntry; PblMapEntry * newEntry = pblMapEntryNew( key, keyLength, value, valueLength ); if( !newEntry ) { return -1; } mapEntry = (PblMapEntry *)pblSetReplaceElement( map->entrySet, newEntry ); if( mapEntry ) { PBL_FREE( mapEntry ); return 0; } rc = pblSetAdd( map->entrySet, newEntry ); if( rc < 0 ) { PBL_FREE(newEntry); return -1; } return 1; }
void greedy_parallel(int pid) { int nodes, node, i, tmp; int color, othernode; MPI_Status status; MPI_Request req; int * indexes, *colors, *madjacency; PblSet * psetcolors = (PblSet *) pblSetNewHashSet(); MPI_Recv( &nodes, 1, MPI_INT, 0, TAG, MPI_COMM_WORLD, &status ); //printf("[rank %d] NODES: %d\n", pid, nodes); srand( time(NULL) / pid ); indexes = (int*) malloc(nodes*sizeof(int)); colors = (int*) malloc(nodes*sizeof(int)); madjacency = (int*) malloc(nodes*nodes*sizeof(int)); MPI_Recv(madjacency, nodes*nodes, MPI_INT, 0, TAG, MPI_COMM_WORLD, &status); for (i = 0; i < nodes; i++) indexes[i] = i; for (i = nodes-1; i >= 0; i--) { tmp = rand_between(0, i); node = indexes[tmp]; indexes[tmp] = indexes[i]; pblSetClear(psetcolors); for (othernode = 0; othernode < nodes; othernode++) { if (othernode != node) { if (madjacency[POS(othernode, node, nodes)] == 1) { if (colors[othernode] != 0) /* the neighbor already has a color */ pblSetAdd(psetcolors, (void *) colors[othernode]); } } } colors[node] = find_my_color(psetcolors, nodes); } //printf("[rank %d] colors = ", pid); //for (i = 0; i < nodes; i++) // printf(" %d", colors[i]); //printf("\n"); MPI_Send(colors, nodes, MPI_INT, 0, TAG, MPI_COMM_WORLD); }
int color_node(int node, int pid, int nodes_per_block, int * madjacency, int* colors, PblSet * psetcolors, int nodes) { int othernode; pblSetClear(psetcolors); for (othernode = 0; othernode < nodes; othernode++) { if (othernode != (pid-1)*nodes_per_block + node) { if (madjacency[POS(othernode, node, nodes)] == 1) { if (colors[othernode] != 0) /* the neighbor already has a color */ pblSetAdd(psetcolors, (void *) colors[othernode]); } } } return find_my_color(psetcolors, nodes); }
void block_partition(int pid, int p, MPI_Comm * comm_workers) { int nodes, color; int my_nodes; int max_nodes_per_block, nodes_per_block; int * madjacency, *neighbours_colors, *my_colors, *conflicts; int n_conflicts = 0; int i, j, b, last_color = 0, neighbour_color = -1; MPI_Request req; MPI_Status status; char buffer[10000]; PblSet * psetcolors = (PblSet *) pblSetNewHashSet(); MPI_Recv( &nodes, 1, MPI_INT, 0, TAG, MPI_COMM_WORLD, &status ); //printf("[rank %d] nodes: %d\n", pid, nodes); nodes_per_block = get_nodes_per_process(nodes, p); max_nodes_per_block = nodes - (pid - 1) * nodes_per_block; if (pid < p) my_nodes = nodes_per_block; else my_nodes = max_nodes_per_block; //printf("[rank %d] my_nodes: %d | max_nodes: %d | nodes = %d\n", pid, my_nodes, max_nodes_per_block, nodes); // alloc space for the neighbours information madjacency = (int*) malloc( nodes * my_nodes * sizeof(int) ); neighbours_colors = (int*) malloc( nodes * sizeof(int) ); my_colors = (int*) malloc( my_nodes * sizeof(int) ); conflicts = (int*) malloc( nodes_per_block * sizeof(int) ); for ( i = 0; i < nodes; i++ ) neighbours_colors[i] = 0; MPI_Recv( madjacency, nodes*my_nodes, MPI_INT, 0, TAG, MPI_COMM_WORLD, &status ); // print_adjacency_matrix(pid, madjacency, my_nodes, nodes); last_color = 0; for ( i = 0; i < nodes_per_block; i++ ) { pblSetClear( psetcolors ); for ( j = 0; j < nodes; j++ ) { if (j == (pid-1)*nodes_per_block + i ) continue; if (madjacency[i*nodes + j] > 0 && neighbours_colors[j] > 0) { // printf("[rank %d] neighbour %d has color %d\n", pid, j, neighbours_colors[j]); pblSetAdd(psetcolors, (void *) neighbours_colors[j]); } } last_color = find_my_color(psetcolors, nodes); // printf("[rank %d] color of %d is now %d\n", pid, i, last_color); my_colors[i] = last_color; for ( b = 0; b < p; b++ ) { //printf("[rank %d] before - last_color = %d | neighbour_color = %d \n", pid, last_color, neighbour_color); if ( pid == b+1 ) neighbour_color = last_color; MPI_Bcast( &neighbour_color, 1, MPI_INT, b, *comm_workers ); neighbours_colors[b * nodes_per_block + i] = neighbour_color; //printf("[rank %d] received - neighbour %d has color %d\n", pid, b*nodes_per_block+i, neighbour_color); } } if (my_nodes > nodes_per_block){ for (i = nodes_per_block; i < max_nodes_per_block; i++){ pblSetClear( psetcolors ); //printf("[rank %d] neighbours =", pid); /*for ( j = 0; j < nodes; j++ ) printf(" %d", neighbours_colors[j]); printf("\n");*/ for ( j = 0; j < nodes; j++ ) { if (j == (pid-1)*nodes_per_block + i ) continue; if (madjacency[i*nodes + j] > 0 && neighbours_colors[j] > 0) { //printf("[rank %d] neighbour %d has color %d\n", pid, j, neighbours_colors[j]); pblSetAdd(psetcolors, (void *) neighbours_colors[j]); } } my_colors[i] = find_my_color(psetcolors, nodes); neighbours_colors[(pid-1)*nodes_per_block + i] = my_colors[i]; } } // STEP 2 for ( i = 0; i < nodes_per_block; i++ ) { for ( j = 0; j < nodes; j++ ) { if (j == (pid-1)*nodes_per_block + i ) { continue; } //printf("[rank %d] %d %d > adjacency %d > j mod nodes_per_block == i %d > neighbours_colors[j] = %d > my_colors[i] %d\n", // pid, (pid-1)*nodes_per_block + i, j, madjacency[i*nodes + j], (j % nodes_per_block == i), neighbours_colors[j], my_colors[i]); if (madjacency[i * nodes + j] > 0 && (j % nodes_per_block == i) && neighbours_colors[j] == my_colors[i]) { //printf("[rank %d] have conflict %d vs %d\n", pid, (pid-1)*nodes_per_block + i, j); if ( (pid-1) * nodes_per_block + i < j ) { //printf("[rank %d] conflict++\n", pid); conflicts[n_conflicts] = (pid-1)*nodes_per_block + i; n_conflicts++; break; } } } } /*printf("[rank %d] my_colors = ", pid); for (i = 0; i < my_nodes; i++) printf(" %d", my_colors[i]); printf("\n");*/ MPI_Send( my_colors, my_nodes, MPI_INT, 0, TAG, MPI_COMM_WORLD); MPI_Send( conflicts, n_conflicts, MPI_INT, 0, TAG, MPI_COMM_WORLD); }
void plassman_v_processors(int pid) { int nodes; int * madjacency; int weight, n_wait = 0, n_send = 0, i, neigbour_weight, tmp_color, color; int * send_to; int * receive_from; int * colors; MPI_Request req; MPI_Status status; MPI_Recv( &nodes, 1, MPI_INT, 0, TAG, MPI_COMM_WORLD, &status ); send_to = (int*) malloc( (nodes-1) * sizeof(int) ); receive_from = (int*) malloc( (nodes-1) * sizeof(int) ); colors = (int*) malloc( (nodes) * sizeof(int) ); madjacency = (int*)malloc(nodes * sizeof(int)); MPI_Recv( madjacency, nodes, MPI_INT, 0, TAG, MPI_COMM_WORLD, &status ); //defenir peso random srand( time( NULL ) * pid ); weight = rand(); // enviar peso para e receber peso dos vizinhos, definindo de quais vai esperar e de quais vai enviar for (i = 1; i <= nodes; i++) { if (i == pid || madjacency[i-1] == 0) continue; MPI_Isend( &weight, 1, MPI_INT, i, TAG, MPI_COMM_WORLD, &req ); MPI_Recv( &neigbour_weight, 1, MPI_INT, i, TAG, MPI_COMM_WORLD, &status ); if ( weight < neigbour_weight ) { receive_from[n_wait] = i; n_wait++; } else { send_to[n_send] = i; n_send++; } MPI_Wait(&req, &status); } PblSet * psetcolors = (PblSet *) pblSetNewHashSet(); // esperar pesos maiores for ( i = 0; i < n_wait; i++ ) { MPI_Recv( &tmp_color, 1, MPI_INT, receive_from[i], TAG, MPI_COMM_WORLD, &status ); pblSetAdd(psetcolors, (void *) tmp_color); } // definir cor do no color = find_my_color(psetcolors, nodes); // enviar aos pesos menores for ( i = 0; i < n_send; i++) { MPI_Send( &color, 1, MPI_INT, send_to[i], TAG, MPI_COMM_WORLD); } //enviar cor final para o master //printf("[rank %d] Send color %d to master\n", pid, color); MPI_Send( &color, 1, MPI_INT, 0, TAG, MPI_COMM_WORLD); }
/** * Associates the specified value with the specified key in this map. * * If the map previously contained a mapping for the key, the old value is replaced by the specified value. * (A map m is said to contain a mapping for a key k if and only if pblMapContainsKey(k) would return true.) * * Returns the previous value associated with key, NULL if there was no mapping for key * or (void*)-1 in case of an error. * * Note: If a valid pointer to a value is returned, the value returned is * malloced on the heap. It is the caller's responsibility to free that memory * once it is no longer needed. * * For hash maps this method has a time complexity of O(1). * For tree maps this method has a time complexity of O(Log N). * * @return void * retptr != (void*)-1: The previously associated value. * @return void * retptr == NULL: There was no previously associated value. * @return void * retptr == (void*)-1: An error, see pbl_errno: * * <BR>PBL_ERROR_OUT_OF_MEMORY - Out of memory. * <BR>PBL_ERROR_OUT_OF_BOUNDS - Maximum capacity of the hash set exceeded. */ void * pblMapPut( /* */ PblMap * map, /** The map to add to */ void * key, /** Key to add a mapping for */ size_t keyLength, /** Length of the key */ void * value, /** Value of the new mapping */ size_t valueLength, /** Length of the value */ size_t * valueLengthPtr /** Out: Length of the value returned */ ) { int rc; PblMapEntry * mapEntry; PblMapEntry * newEntry = pblMapEntryNew( key, keyLength, value, valueLength ); if( !newEntry ) { return (void*)-1; } mapEntry = (PblMapEntry *)pblSetReplaceElement( map->entrySet, newEntry ); if( mapEntry ) { void * retptr; if( mapEntry->valueLength > 0 ) { retptr = pbl_memdup( "pblMapPut", mapEntry->buffer + mapEntry->keyLength, mapEntry->valueLength ); } else { retptr = pbl_malloc0( "pblMapPut0", 1 ); } if( !retptr ) { if( valueLengthPtr ) { *valueLengthPtr = 0; } pblSetReplaceElement( map->entrySet, mapEntry ); PBL_FREE( newEntry ); return (void*)-1; } if( valueLengthPtr ) { *valueLengthPtr = mapEntry->valueLength; } PBL_FREE( mapEntry ); return retptr; } if( valueLengthPtr ) { *valueLengthPtr = 0; } rc = pblSetAdd( map->entrySet, newEntry ); if( rc < 0 ) { PBL_FREE(newEntry); return (void*)-1; } return NULL; }