/** * Returns a pblHashSet with a shallow copy of this collection instance. * An application specific hash value function can be set. * * The elements themselves are not copied. * * NULL elements contained in the collection are silently ignored. * * This method has a memory and time complexity of O(N), * with N being the number of elements in the collection. * * @return PblSet * retPtr != NULL: A pointer to the new set. * @return PblSet * retPtr == NULL: An error, see pbl_errno: * * <BR>PBL_ERROR_OUT_OF_MEMORY - Out of memory. * <BR>PBL_ERROR_PARAM_COLLECTION - The collection cannot be iterated. * <BR>PBL_ERROR_CONCURRENT_MODIFICATION - The collection was modified concurrently. * <BR>PBL_ERROR_OUT_OF_BOUNDS - Maximum capacity of the hash set exceeded. */ PblSet * pblCollectionConvertToHashSet( PblCollection * collection, /** The collection to convert */ int ( *hashValue ) /** The hash value function for the new set, may be NULL */ ( const void* element /** The element to get the hash value for */ )) { PblSet * set = pblSetNewHashSet(); if( !set ) { return NULL; } set->compare = collection->compare; if( hashValue ) { ( (PblHashSet*)set )->hashValue = hashValue; } else if( PBL_SET_IS_HASH_SET( collection ) ) { ( (PblHashSet*)set )->hashValue = ( (PblHashSet*)collection )->hashValue; } if( pblSetAddAll( set, collection ) < 0 ) { pblSetFree( set ); return NULL; } return set; }
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); }
/** * Creates a new hash map. * * This method has a time complexity of O(1). * * @return PblMap * retPtr != NULL: A pointer to the new map. * @return PblMap * retPtr == NULL: An error, see pbl_errno: * * <BR>PBL_ERROR_OUT_OF_MEMORY - Out of memory. */ PblMap * pblMapNewHashMap( void ) { PblMap * pblMap = (PblMap *)pbl_malloc0( "pblMapNewHashMap", sizeof(PblMap) ); if( !pblMap ) { return NULL; } pblMap->entrySet = pblSetNewHashSet(); if( !pblMap->entrySet ) { PBL_FREE( pblMap ); return NULL; } pblSetSetCompareFunction( pblMap->entrySet, pblMapEntryCompareFunction ); pblSetSetHashValueFunction( pblMap->entrySet, pblMapEntryHashValue ); return pblMap; }
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_p_processors(int pid, int p, MPI_Comm * comm_workers) { int nodes; int * madjacency; int * all_weights, i, j; int my_nodes, nodes_per_block, max_nodes_per_block, n_locals; int * send_to, * n_wait, * n_send, * locals; int * receive_from, ended = 0; int * colors, my_colors[2], tmp = 0; MPI_Request req; MPI_Status status; PblSet * psetcolors = (PblSet *) pblSetNewHashSet(); int good = 1; MPI_Recv( &nodes, 1, MPI_INT, 0, TAG, MPI_COMM_WORLD, &status ); nodes_per_block = get_nodes_per_process(nodes, p); max_nodes_per_block = nodes - (p - 1) * nodes_per_block; //printf("[rank %d] nodes: %d | nodes_per_block: %d | max_nodes_per_block: %d\n", pid, nodes, nodes_per_block, max_nodes_per_block); if (pid < p) my_nodes = nodes_per_block; else my_nodes = max_nodes_per_block; n_locals = 0; //printf("[rank %d] nodes: %d\n", pid, nodes); n_wait = (int*) malloc( my_nodes * sizeof(int) ); n_send = (int*) malloc( my_nodes * sizeof(int) ); send_to = (int*) malloc( my_nodes*(nodes-1) * sizeof(int) ); receive_from = (int*) malloc( my_nodes*(nodes-1) * sizeof(int) ); colors = (int*) malloc( (nodes) * sizeof(int) ); all_weights = (int*) malloc( (nodes) * sizeof(int) ); madjacency = (int*) malloc( nodes * my_nodes * sizeof(int) ); locals = (int*) malloc( my_nodes * sizeof(int) ); MPI_Recv( madjacency, nodes*my_nodes, MPI_INT, 0, TAG, MPI_COMM_WORLD, &status ); //defenir peso random srand( time( NULL ) / pid ); for (i = 0; i < my_nodes; i++){ all_weights[(pid-1)*nodes_per_block +i] = rand(); n_wait[i] = 0; n_send[i] = 0; //print-f("[rank %d] weight[%d]: %d\n", pid, (pid-1)*nodes_per_block + i, all_weights[(pid-1)*nodes_per_block +i]); } //printf("[rank %d] will exchange weights\n", pid); //exchange all weights for ( i = 0; i < p-1; i++) MPI_Bcast( &all_weights[i*nodes_per_block], nodes_per_block, MPI_INT, i, *comm_workers ); MPI_Bcast( &all_weights[(p-1)*nodes_per_block], max_nodes_per_block, MPI_INT, p-1, *comm_workers ); //printf("[rank %d] weights exchanged\n", pid); fflush(stdout); for ( i = 0; i < my_nodes; i++ ) { for (j = 0; j < nodes; j++) { if ((pid-1)*nodes_per_block + i == j || madjacency[i*nodes + j] <= 0 || pid == get_pid_of_node(j, nodes, p)) continue; if ( all_weights[(pid-1)*nodes_per_block + i] < all_weights[j] ) { receive_from[i*(nodes-1) + n_wait[i]] = j; n_wait[i]++; } else { send_to[i*(nodes-1) + n_send[i]] = j; n_send[i]++; } } locals[i] = is_local( (pid-1)*nodes_per_block+i, i, madjacency, nodes, p); if (locals[i]) { n_locals++; continue; } //printf("[rank %d] vertice[%d]: wait %d | send %d\n", pid, (pid-1)*nodes_per_block+i, n_wait[i], n_send[i]); if(n_wait[i] == 0 ){ colors[(pid-1)*nodes_per_block+i] = color_node(i, pid,nodes_per_block, madjacency, colors, psetcolors, nodes); ended++; my_colors[0] = (pid-1)*nodes_per_block+i; my_colors[1] = colors[my_colors[0]]; for (j = 0; j < n_send[i]; j++) { //printf("[rank %d] send color %d do vertice %d para o %d do rank %d\n", pid, my_colors[1], (pid-1)*nodes_per_block+i, // send_to[i*(nodes-1) +j], get_pid_of_node(send_to[i*(nodes-1) +j],nodes,p)); MPI_Isend(my_colors, 2, MPI_INT, get_pid_of_node(send_to[i*(nodes-1) + j], nodes, p), TAG, MPI_COMM_WORLD, &req); } } } //print_adjacency_matrix(pid, madjacency, my_nodes, nodes); //printf("[rank %d] locals"); //for (i = 0; i < my_nodes; i++) //printf(" %d", locals[i]); //printf("\n"); //printf("[rank %d] ended: %d | locals = %d\n", pid, ended, n_locals); while(ended != my_nodes-n_locals) { //printf("[rank %d] mais uma voltinha...\n", pid); MPI_Recv(my_colors, 2, MPI_INT, MPI_ANY_SOURCE, TAG, MPI_COMM_WORLD, &status); colors[my_colors[0]] = my_colors[1]; //printf("[rank %d] Reiceived color %d from vertice %d\n", pid, my_colors[1], my_colors[0]); //printf("[rank %d]", pid); //for( i = 0; i < nodes; i++) //printf(" %d", colors[i]); //printf("\n"); for ( i = 0; i < my_nodes; i++ ) { if (n_wait[i] == 0 || locals[i]) continue; //printf("[rank %d] %d not done...\n", pid, i); for (j = 0; j < n_wait[i]; j++) if (receive_from[i*(nodes-1)+j] == my_colors[0] ) { receive_from[i*(nodes-1)+j] = receive_from[i*(nodes-1)+n_wait[i]-1]; n_wait[i]--; break; } if (n_wait[i] > 0) continue; //printf("[rank %d] %d done...\n", pid, i); colors[(pid-1)*nodes_per_block+i] = color_node(i, pid,nodes_per_block, madjacency, colors, psetcolors, nodes); ended++; my_colors[0] = (pid-1)*nodes_per_block+i; my_colors[1] = colors[my_colors[0]]; for (j = 0; j < n_send[i]; j++) { //printf("[rank %d] send color do vertice %d para o %d do rank %d\n", pid, (pid-1)*nodes_per_block+i, // send_to[i*(nodes-1) +j], get_pid_of_node(send_to[i*(nodes-1) +j],nodes,p)); MPI_Isend(my_colors, 2, MPI_INT, get_pid_of_node(send_to[i*(nodes-1) + j], nodes, p), TAG, MPI_COMM_WORLD, &req); } } } for(i = 0; i < my_nodes; i++) if (locals[i]) colors[(pid-1)*nodes_per_block + i] = color_node(i, pid,nodes_per_block, madjacency, colors, psetcolors, nodes); //enviar cor final para o master // for(i = 0; i < my_nodes; i++) //printf("[rank %d] color[%d] = %d\n", pid, i, colors[(pid-1)*nodes_per_block + i]); //printf("[rank %d] Send colors to master\n", pid); MPI_Send( &colors[(pid-1)*nodes_per_block], my_nodes, 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); }