
// Kernel invocation: spx <<POP_SIZE/2,MAX_THREADS_PER_BLOCK>>> (oldpop,newpop,positions,randomPC,randomPoint,
// CHROM_LEN,PROB_CROSS); 
// POP_SIZE: number of individuals of the population.
// MAX_THREADS_PER_BLOCK: constant with the maximum number of threads per block. 
// oldpop: pointer to global memory that stores the old population. 
// newpop: pointer to global memory that stores the new population.
// positions: pointer to global memory that stores the indexes of individuals for crossover
// randomPC: pointer to global memory that stores the random values for crossover.
// randomPoint: pointer to global memory that stores the random points for crossover.
// CHROM_LEN: length of the chromosome.
// PROB_CROSS: crossover probability. 

__global__ void spx(bool *pop, bool *npop, int *pos, float *randomPC, int *randomPoint, int length, float PROB_CROSS){

  int idx = blockIdx.x; // the number of the individual is indicated by the block number
  int ind1 = pos[2*idx]; // index of first individual for crossover
  int ind2 = pos[2*idx+1]; // index of second individual for crossover
  float pc = randomPC[idx]; // value for crossover
  int pnt = randomPoint[idx]; // crossover point
  int i;
	
  if (pc <= PROB_CROSS) {
     // Cross individuals
     for(i=threadIdx.x;i<length;i=i+MAX_THREADS_PER_BLOCK) {
	  if (i<pnt) {
                //copy bit from parent ind1 to child 2*idx
	  	npop[2*idx*length+i] = pop[ind1*length+i];
		//copy bit from parent ind2 to child 2*idx + 1
                npop[(2*idx+1)*length+i] = pop[ind2*length+i];
	  } else {
	        //copy bit from parent ind2 to child 2*idx
                npop[2*idx*length+i] = pop[ind2*length+i];
		//copy bit from parent ind1 to child 2*idx + 1
                npop[(2*idx+1)*length+i] = pop[ind1*length+i];
	  }
      }
   } else {
      // Copy individuals
      for(i=threadIdx.x;i<length;i=i+MAX_THREADS_PER_BLOCK) {
           //copy bit from parent ind1 to child 2*idx
	   npop[(2*idx)*length+i] = pop[ind1*length+i];
	   //copy bit from parent ind2 to child 2*idx + 1
	   npop[(2*idx+1)*length+i] = pop[ind2*length+i];
      }
   }

}
