I am doing small coding on Genetic Algorithm and the below is my main function :
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <mpi.h>
#include <limits.h>
#define N 8
#define POPULATION_SIZE 100
#define MUTATION_RATE 0.3
#define MAX_GENERATIONS 50
typedef struct {
int board[N];
int fitness;
} Individual;
int calculateFitness(int board[]) {
int conflicts = 0;
for (int i = 0; i < N; i++) {
for (int j = i + 1; j < N; j++) {
if (board[i] == board[j] || abs(board[i] - board[j]) == j - i) {
conflicts++;
}
}
}
return conflicts;
}
void initializePopulation(Individual population[]) {
for (int i = 0; i < POPULATION_SIZE; i++) {
for (int j = 0; j < N; j++) {
population[i].board[j] = rand() % N;
}
population[i].fitness = calculateFitness(population[i].board); // Calculate fitness for each individual
}
}
void selection(Individual population[], Individual matingPool[]) {
// Tournament selection
for (int i = 0; i < POPULATION_SIZE; i++) {
int idx1 = rand() % POPULATION_SIZE;
int idx2 = rand() % POPULATION_SIZE;
if (population[idx1].fitness < population[idx2].fitness) {
matingPool[i] = population[idx1];
} else {
matingPool[i] = population[idx2];
}
}
}
void crossover(Individual population[], Individual matingPool[]) {
// MPI_Barrier(MPI_COMM_WORLD);
for (int i = 0; i < POPULATION_SIZE; i += 2) {
int crossoverPoint = rand() % (N - 1) + 1; // Random crossover point
for (int j = 0; j < crossoverPoint; j++) {
population[i].board[j] = matingPool[i].board[j];
population[i + 1].board[j] = matingPool[i + 1].board[j];
}
for (int j = crossoverPoint; j < N; j++) {
population[i].board[j] = matingPool[i + 1].board[j];
population[i + 1].board[j] = matingPool[i].board[j];
}
population[i].fitness = calculateFitness(population[i].board); // Recalculate fitness after crossover
population[i + 1].fitness = calculateFitness(population[i + 1].board);
MPI_Barrier(MPI_COMM_WORLD);
}
}
void mutate(Individual population[]) {
for (int i = 0; i < POPULATION_SIZE; i++) {
if ((double)rand() / RAND_MAX < MUTATION_RATE) {
int mutationPoint = rand() % N; // Random mutation point
int newGene = rand() % N; // New random gene
population[i].board[mutationPoint] = newGene;
population[i].fitness = calculateFitness(population[i].board); // Recalculate fitness after mutation
}
}
}
Individual population[POPULATION_SIZE];
int main(int argc, char *argv[]) {
MPI_Init(&argc, &argv);
int rank, size;
// MPI_Comm_rank(MPI_COMM_WORLD, &rank);
// MPI_Comm_size(MPI_COMM_WORLD, &size);
// int totalPopulationSize = 100; // Replace with the actual total population size
int numProcesses;
int remainder;
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
int chunkSize = POPULATION_SIZE / size;
remainder = POPULATION_SIZE % size;
if (rank < remainder) {
chunkSize += 1;
}
printf("Process %d: Chunk size = %d\n", rank, chunkSize);
srand(time(NULL) + rank); // Adjust the random seed for each process
printf("rank : %d\n", rank);
// Divide the population among processes
// int chunkSize = POPULATION_SIZE / size;
Individual population[POPULATION_SIZE]; // Declare the population array
Individual localPopulation[chunkSize];
Individual localMatingPool[chunkSize];
MPI_Datatype individualType;
int blocklengths[2] = {N, 1};
MPI_Datatype types[2] = {MPI_INT, MPI_INT};
MPI_Aint offsets[2];
offsets[0] = offsetof(Individual, board);
offsets[1] = offsetof(Individual, fitness);
MPI_Type_create_struct(2, blocklengths, offsets, types, &individualType);
MPI_Type_commit(&individualType);
if (rank == 0) {
initializePopulation(population);
}
MPI_Scatter(population, chunkSize, individualType, localPopulation, chunkSize, individualType, 0, MPI_COMM_WORLD);
for (int generation = 1; generation <= MAX_GENERATIONS; generation++) {
// Perform selection, crossover, and mutation in parallel
selection(localPopulation, localMatingPool);
crossover(localPopulation, localMatingPool);
mutate(localPopulation);
// Synchronize results within each process
MPI_Gather(localPopulation, chunkSize, individualType, population, chunkSize, individualType, 0, MPI_COMM_WORLD);
// Exchange the best individuals among processes
Individual bestLocalIndividual;
int bestLocalFitness = INT_MAX;
for (int i = 0; i < chunkSize; i++) {
if (localPopulation[i].fitness < bestLocalFitness) {
bestLocalFitness = localPopulation[i].fitness;
bestLocalIndividual = localPopulation[i];
}
}
// Reduce the best fitness and individual across all MPI processes
Individual bestGlobalIndividual;
int bestGlobalFitness;
MPI_Reduce(&bestLocalFitness, &bestGlobalFitness, 1, MPI_INT, MPI_MIN, 0, MPI_COMM_WORLD);
MPI_Gather(&bestLocalIndividual, sizeof(Individual), MPI_BYTE, &bestGlobalIndividual, sizeof(Individual), MPI_BYTE, 0, MPI_COMM_WORLD);
// Exchange the best individuals between processes
if (rank == 0) {
for (int i = 0; i < size; i++) {
if (i != rank) {
MPI_Send(&bestGlobalIndividual, 1, individualType, i, 0, MPI_COMM_WORLD);
}
}
} else {
MPI_Recv(&bestGlobalIndividual, 1, individualType, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}
// Synchronize generation number
MPI_Bcast(&generation, 1, MPI_INT, 0, MPI_COMM_WORLD);
// Print the current generation and fitness of the best individual
if (rank == 0) {
printf("Generation %d, Best Fitness: %d, Solution: ", generation, bestGlobalFitness);
for (int j = 0; j < N; j++) {
printf("%d ", bestGlobalIndividual.board[j]);
}
printf("\n");
if (bestGlobalFitness == 0) {
printf("Solution found in generation %d\n", generation);
break;
} else if (generation == MAX_GENERATIONS) {
printf("Solution exceeds %d generations\n", MAX_GENERATIONS);
}
}
}
MPI_Type_free(&individualType);
MPI_Finalize();
return 0;
}
===================================================================
when i run this code for np > 1;
segmentation fault!!
==============================================================================
can anyone pls help me with this problem !!

Nelements on rank0, the receive buffer must be large enough to containN * sizeelements. The way you handlebestGlobalIndividualis clearly wrong.crossover()andselection()work onPOPULATION_SIZEelements, but there are onlychunkSize