ElfPSP_ParallelABC
Protein Structure Prediction using Parallel Artificial Bee Colony Optimization
solution_mpi.h
Go to the documentation of this file.
1 #ifndef SOLUTION_PARALLEL_H
2 #define SOLUTION_PARALLEL_H
3 
6 #include <mpi/mpi.h>
8 #include "solution.h"
9 
10 #ifndef SOLUTION_PARALLEL_SOURCE_CODE
11  #define SOLUTION_PARALLEL_INLINE inline
12 #else
13  #define SOLUTION_PARALLEL_INLINE extern inline
14 #endif
15 
17 SOLUTION_PARALLEL_INLINE
18 void Solution_pack(Solution sol, int hpSize, void *buf, int maxSize, int *position, MPI_Comm comm){
19  MPI_Pack(&sol.fitness, 1, MPI_DOUBLE, buf, maxSize, position, comm);
20  MPI_Pack(sol.chain, hpSize-1, MPI_CHAR, buf, maxSize, position, comm);
21 }
22 
24 SOLUTION_PARALLEL_INLINE
25 Solution Solution_unpack(int hpSize, void *buf, int maxSize, int *position, MPI_Comm comm){
26  Solution sol = Solution_blank(hpSize);
27  MPI_Unpack(buf, maxSize, position, &sol.fitness, 1, MPI_DOUBLE, comm);
28  MPI_Unpack(buf, maxSize, position, sol.chain, hpSize-1, MPI_CHAR, comm);
29  return sol;
30 }
31 
35 SOLUTION_PARALLEL_INLINE
36 void Solution_calculate_fitness_master(Solution *sols, int nSols, int hpSize, MPI_Comm comm){
37  int i, j;
38 
39  int commSize;
40  MPI_Comm_size(comm, &commSize);
41 
42  // Allocate buffer for MPI_Scatter / Gather
43  int buffSize = commSize * (hpSize - 1);
44  MovElem *buff = malloc(buffSize); // We send mov chains
45  double recvBuff[commSize]; // And receive fitnesses
46 
47  for(i = 0; i < nSols; i += commSize){
48  // Build scatter buffer content
49  for(j = 0; j < commSize; j++){
50  if((i+j) < nSols){
51  memcpy(buff + j*(hpSize-1), sols[i+j].chain, hpSize - 1);
52  } else {
53  memset(buff + j*(hpSize-1), 0xFEFEFEFE, hpSize - 1);
54  }
55  }
56 
57  // Scatter buffer
58  ElfTreeComm_scatter(buff, hpSize - 1, MPI_CHAR, comm);
59 
60  // Calculate own fitness
61  double fit = FitnessCalc_run2(buff);
62  sols[i].fitness = fit;
63 
64  // Gather fitnesses
65  ElfTreeComm_gather(recvBuff, 1, MPI_DOUBLE, comm);
66 
67  // Place fitnesses into the due solutions
68  for(j = 1; j < commSize && (i+j) < nSols; j++){
69  sols[i+j].fitness = recvBuff[j];
70 
71  // For verifying correctness of fitness
72  // int good = sols[i+j].fitness == FitnessCalc_run2(buff + j * (hpSize - 1));
73  }
74  }
75 
76  free(buff);
77 }
78 
81 SOLUTION_PARALLEL_INLINE
82 void Solution_calculate_fitness_master_kill_slaves(int hpSize, MPI_Comm comm){
83  int commSize;
84  MPI_Comm_size(comm, &commSize);
85 
86  int buffSize = commSize * (hpSize - 1);
87  void *buff = malloc(buffSize);
88  memset(buff, 0xFFFFFFFF, buffSize);
89  ElfTreeComm_scatter(buff, hpSize - 1, MPI_CHAR, comm);
90  free(buff);
91 }
92 
98 SOLUTION_PARALLEL_INLINE
99 void Solution_calculate_fitness_slave(const HPElem *hpChain, int hpSize, MPI_Comm comm){
100  int commSize;
101  MPI_Comm_size(comm, &commSize);
102 
103  // Create scatter/gather buffers
104  int buffSize = commSize * (hpSize - 1);
105  MovElem *buff = malloc(buffSize);
106  double sendBuff[commSize];
107 
108  while(true){
109  ElfTreeComm_scatter(buff, hpSize-1, MPI_CHAR, comm);
110  if(0xFF == buff[0]){ // Detect end of work
111  free(buff);
112  return;
113  }
114 
115  if(0xFE == buff[0]){ // Detect no-op
116  sendBuff[0] = 0;
117  } else {
118  sendBuff[0] = FitnessCalc_run2(buff);
119  }
120 
121  ElfTreeComm_gather(sendBuff, 1, MPI_DOUBLE, comm);
122  }
123 }
124 
125 
126 
127 #endif
Efficient scatter/gather routines that use a tree-like communication pattern.
Routines for manipulating Solution objects, such as creation, randomization, perturbation etc...
double fitness
Fitness of such solution.
Definition: solution_structure_private.h:7
SOLUTION_PARALLEL_INLINE void Solution_calculate_fitness_master(Solution *sols, int nSols, int hpSize, MPI_Comm comm)
Calculates the fitness for all solutions in the given vector, using all nodes in the MPI communicator...
Definition: solution_mpi.h:36
SOLUTION_INLINE Solution Solution_blank(int hpSize)
Returns a Solution whose fields are all uninitialized, but with due memory allocated.
Definition: solution.h:28
MovElem * chain
Position of such solution.
Definition: solution_structure_private.h:6
char HPElem
HPChain is how we call an array of HPElem.
Definition: hpchain.h:9
unsigned char MovElem
Type that holds 2 movements, one for the backbone and one for the side chain.
Definition: movelem.h:21
SOLUTION_PARALLEL_INLINE void Solution_calculate_fitness_slave(const HPElem *hpChain, int hpSize, MPI_Comm comm)
Procedure that the slave nodes should execute.
Definition: solution_mpi.h:99
SOLUTION_PARALLEL_INLINE Solution Solution_unpack(int hpSize, void *buf, int maxSize, int *position, MPI_Comm comm)
Unpacks a Solution and returns it.
Definition: solution_mpi.h:25
Encapsulates a solution, which is a protein conformation that is developed by a bee.
Definition: solution_structure_private.h:5
SOLUTION_PARALLEL_INLINE void Solution_calculate_fitness_master_kill_slaves(int hpSize, MPI_Comm comm)
Tells slaves to return Allocate buffer for MPI_Scatter / Gather.
Definition: solution_mpi.h:82
SOLUTION_PARALLEL_INLINE void Solution_pack(Solution sol, int hpSize, void *buf, int maxSize, int *position, MPI_Comm comm)
Packs a Solution in the given buffer.
Definition: solution_mpi.h:18