MPI coding error : program exiting without completing execution

118 Views Asked by At

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;

error img

segmentation fault!!

==============================================================================

can anyone pls help me with this problem !!

0

There are 0 best solutions below