// File: /workspace/github_cpp_makefile_star2_O1/richardposner[P]BioNetFit2/src/code/Swarm.cpp
// Function: Swarm::runGeneration()
void Swarm::runGeneration () {   //razi: modified to include subparticles
	// TODO: Implement walltime

	//Raquel added, master will handle the directory creation
	string path = options.jobOutputDir + toString(currentGeneration) + "/";

	if (!checkIfFileExists(path)) {
		runCommand("mkdir " + path);
	}


	unsigned int nModels = options.models.size();
	if(options.verbosity >= 1) {
		cout << "Running generation " << currentGeneration << " with " << options.swarmSize << " particles..." << endl;
	}

	unsigned int numFinishedParticles = 0;

//	vector<unsigned int, vector<bool> > runningParticles;
//vector<unsigned int, vector<bool> > finishedParticles;
//	vector<unsigned int> runningSubParticles;
//	vector<unsigned int> finishedSubParticles;

	unsigned int p, mid, sp;
	vector<unsigned int> newFinishedParticles;
	// razi: handle running particles that include subparticles, dont exceed parallel count
	//we need to track number of completed particles which is not simply equal to (nModels * number of subParticles)
	//a particle is considered completed of all its subparticles are finished. XXXX
	if(options.verbosity>=3){

		cout << "@@@@@@@@@@@@@@@@@ size before cleaning " << currentsubswarmBestFits_.size() << " @@@@@@@@@@@@@@@@@@@@@@@@@@@@" << endl;

	}

	sp=0;
	currentsubparticleBestFitsByFit_.clear();
	currentsubswarmBestFits_.clear();
	finishedParticles_.clear();
	finishedSubParticles_.clear(); //Raquel added to solve problem of less and less result files as generations go
	unsigned int maxSubPar = fcalcsubParID(options.swarmSize, options.models.size()-1, options.models.size());
	int tries = 0;

	if(options.verbosity>=3){
		cout << "Maxsubpar = "  << maxSubPar << endl;

	}

	generationTime_.reset(); //Raquel implementing walltime

	while (finishedSubParticles_.size() < maxSubPar ) { //&& runningSubParticles_.size() < maxSubPar) { //razi: loop over particles, each particle includes nModels subPArticles

		while (runningSubParticles_.size()< options.parallelCount && sp < maxSubPar) {//razi: make sure the number of subparticles don't exceed parallel count limit
			sp++;
			p = fcalcParID(sp, nModels);
			mid = fcalcMID(sp, nModels);

			launchSubParticle(p, mid, false);
			//launchParticle(p, false);
			//cout << "RAQUEL runningSubParticles_.size() " << runningSubParticles_.size() << " options.parallelCount " << options.parallelCount << endl;

			tries = 0;
		}
		// Check for any messages from particles
		//usleep(250000);
		//cout << "RAQUEL Entering checkMasterMessages" << endl;
		newFinishedParticles = checkMasterMessages();
		//cout << "RAQUEL Done checkMasterMessages finishedSubParticles_.size() " << finishedSubParticles_.size() << endl;

		//cout << "finishedSubParticles_.size() " << finishedSubParticles_.size() << " runningSubParticles_.size() " << runningSubParticles_.size() << " maxSubPar " << maxSubPar << " sp " << sp << endl;
		numFinishedParticles = finishedParticles_.size();
		//cout << "RAQUEL rungeneration numFinishedParticles " << numFinishedParticles << endl;
		//tries++; // Enable this fix if the program stays stuck waiting for a message from the slave, even though the master already sent the message

		if(options.verbosity >= 5) {
			cout << numFinishedParticles << " finished particles" << endl;

		}
		if(tries > 50){

			cout << "RAQUEL " << runningSubParticles_.size() << " subparticles failed in generation " << currentGeneration << endl;
//			cout << "RAQUEL resending message NEXT_GENERATION to failed particles" << endl;
			for (auto stuckParticle = runningSubParticles_.begin(); stuckParticle != runningSubParticles_.end(); ++stuckParticle ){

				swarmComm->sendToSwarm(0, *stuckParticle, NEXT_GENERATION, false, swarmComm->univMessageSender);

			}

			tries = 0;
		}

	}

	if(options.verbosity >= 2) {

		cout << "Total time to run generation: " << generationTime_.elapsed() << " seconds." << endl;
		cout << "Max fit time: " << options.maxFitTime << endl;
		int convertedMaxFitTime = convertTimeToSeconds(options.maxFitTime);


		cout << "Max fit time converted: " << convertedMaxFitTime << endl;
	}
	finishedParticles_.clear();
	finishedSubParticles_.clear(); //Raquel added to solve problem of less and less result files as generations go



	/*
	while (numFinishedParticles < options.swarmSize) { //razi: loop over particles, each particle includes nModels subPArticles

		if ((runningSubParticles_.size()*nModels+nModels )<= options.parallelCount && numLaunchedParticles < options.swarmSize) {//razi: make sure subparticles don't exceed parallel count limit
			launchParticle(p);
			numLaunchedSubParticles += 1;
			++p;
		}

		// Check for any messages from particles
		usleep(10000);
		finishedSubParticles = checkMasterMessages();
		numFinishedSubParticles += finishedSubParticles.size();
		finishedSubParticles.clear();
	}
*/

	if ( options.verbosity >=3){ cout<< "running a swarm generation finished ....\n";}

	if (failedParticles_.size() > (unsigned) (options.swarmSize - 3) ) {
		finishFit();
		outputError("Error: You had too many failed runs. Check simulation output (.BNG_OUT files) or adjust walltime.");
	}
	currentGeneration += 1;



}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x118, %rsp            # imm = 0x118
movq %rdi, %rbx
movl 0x13e8(%rdi), %esi
leaq 0xf8(%rsp), %r14
movq %r14, %rdi
callq 0xc03b8
movq 0x1520(%rbx), %rcx
movq 0x1528(%rbx), %r8
movq %r14, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x22a80
leaq 0x30(%rsp), %r14
movq %r14, -0x10(%r14)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
je 0x8d6dd
movq %rdx, 0x20(%rsp)
movq (%rcx), %rdx
movq %rdx, 0x30(%rsp)
jmp 0x8d6e6
movupd (%rcx), %xmm0
movupd %xmm0, (%r14)
movq 0x8(%rax), %rdx
leaq 0x20(%rsp), %rdi
movq %rdx, 0x8(%rdi)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
leaq 0x720de(%rip), %rsi     # 0xff7e7
callq 0x233b0
leaq 0x58(%rsp), %rsi
movq %rsi, -0x10(%rsi)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
je 0x8d735
movq %rdx, 0x48(%rsp)
movq (%rcx), %rdx
movq %rdx, 0x58(%rsp)
jmp 0x8d73d
movupd (%rcx), %xmm0
movupd %xmm0, (%rsi)
movq 0x8(%rax), %rdx
movq %rdx, 0x50(%rsp)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
movq 0x20(%rsp), %rdi
cmpq %r14, %rdi
je 0x8d76c
movq 0x30(%rsp), %rsi
incq %rsi
callq 0x229c0
leaq 0x108(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x8d78d
movq 0x108(%rsp), %rsi
incq %rsi
callq 0x229c0
leaq 0xa8(%rsp), %r14
movq %r14, -0x10(%r14)
movq 0x48(%rsp), %rsi
movq 0x50(%rsp), %rdx
addq %rsi, %rdx
leaq 0x98(%rsp), %rdi
callq 0x32180
leaq 0x98(%rsp), %rdi
callq 0xbf2c2
movl %eax, %ebp
movq 0x98(%rsp), %rdi
cmpq %r14, %rdi
je 0x8d7df
movq 0xa8(%rsp), %rsi
incq %rsi
callq 0x229c0
testl %ebp, %ebp
jne 0x8d82a
leaq 0x6a7ad(%rip), %rsi     # 0xf7f97
leaq 0xb8(%rsp), %rdi
leaq 0x48(%rsp), %rdx
callq 0x319d8
leaq 0xb8(%rsp), %rdi
callq 0xc038e
leaq 0xc8(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x8d82a
movq 0xc8(%rsp), %rsi
incq %rsi
callq 0x229c0
movq 0x15c8(%rbx), %rbp
subq 0x15c0(%rbx), %rbp
cmpl $0x0, 0x1614(%rbx)
je 0x8d8d2
movq 0xe8744(%rip), %rdi     # 0x175f90
leaq 0x71be9(%rip), %rsi     # 0xff43c
movl $0x13, %edx
callq 0x22ab0
movl 0x13e8(%rbx), %esi
movq 0xe8726(%rip), %rdi     # 0x175f90
callq 0x22650
movq %rax, %r14
leaq 0x71bd7(%rip), %rsi     # 0xff450
movl $0x6, %edx
movq %rax, %rdi
callq 0x22ab0
movl 0x1620(%rbx), %esi
movq %r14, %rdi
callq 0x231e0
movq %rax, %r14
leaq 0x71bb9(%rip), %rsi     # 0xff457
movl $0xd, %edx
movq %rax, %rdi
callq 0x22ab0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x22940
movsbl %al, %esi
movq %r14, %rdi
callq 0x22050
movq %rax, %rdi
callq 0x22660
cmpl $0x3, 0x1614(%rbx)
jb 0x8d944
movq 0xe86ae(%rip), %rdi     # 0x175f90
leaq 0x71b7c(%rip), %rsi     # 0xff465
movl $0x27, %edx
callq 0x22ab0
movq 0x1c58(%rbx), %rsi
movq 0xe868f(%rip), %rdi     # 0x175f90
callq 0x22650
movq %rax, %r14
leaq 0x71b7d(%rip), %rsi     # 0xff48d
movl $0x1d, %edx
movq %rax, %rdi
callq 0x22ab0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x22940
movsbl %al, %esi
movq %r14, %rdi
callq 0x22050
movq %rax, %rdi
callq 0x22660
leaq 0x1b70(%rbx), %rdi
callq 0xb02de
leaq 0x1c30(%rbx), %rdi
callq 0xb02de
leaq 0x18c0(%rbx), %rdi
movq %rdi, 0x70(%rsp)
callq 0xb030c
leaq 0x1890(%rbx), %rdi
movq %rdi, 0x68(%rsp)
callq 0xb030c
movl 0x1620(%rbx), %edi
movq 0x15c8(%rbx), %rdx
subq 0x15c0(%rbx), %rdx
shrq $0x3, %rdx
leal -0x1(%rdx), %esi
callq 0xbf2a3
movl %eax, %r12d
cmpl $0x3, 0x1614(%rbx)
movl %eax, %eax
movq %rax, 0x10(%rsp)
jb 0x8da44
movq $0x0, 0x8(%rsp)
movq 0xe85cb(%rip), %rdi     # 0x175f90
leaq 0x71adf(%rip), %rsi     # 0xff4ab
movl $0xc, %edx
xorl %r13d, %r13d
callq 0x22ab0
movq $0x0, 0x8(%rsp)
movq 0xe85a7(%rip), %rdi     # 0x175f90
xorl %r13d, %r13d
movq 0x10(%rsp), %rsi
callq 0x22650
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movq $0x0, 0x8(%rsp)
xorl %r13d, %r13d
movl $0xa, %esi
callq 0x22940
movq $0x0, 0x8(%rsp)
movsbl %al, %esi
xorl %r13d, %r13d
movq %r14, %rdi
callq 0x22050
movq $0x0, 0x8(%rsp)
xorl %r13d, %r13d
movq %rax, %rdi
callq 0x22660
callq 0x220b0
movq %rax, 0x1db8(%rbx)
xorl %r14d, %r14d
movq 0x10(%rsp), %rax
cmpq %rax, 0x18b8(%rbx)
jae 0x8db89
shrq $0x3, %rbp
xorl %r13d, %r13d
movq $0x0, 0x8(%rsp)
movq 0x8(%rsp), %rax
movq %rax, 0x18(%rsp)
movq %r13, %r15
movl 0x1628(%rbx), %eax
cmpq %rax, 0x1848(%rbx)
jae 0x8dac1
cmpl %r12d, %r14d
jae 0x8dac1
incl %r14d
movl %r14d, %edi
movl %ebp, %esi
callq 0xbf2b8
movl %eax, %r13d
movl %r14d, %edi
movl %ebp, %esi
callq 0xbf2ae
movq %rbx, %rdi
movl %r13d, %esi
movl %eax, %edx
xorl %ecx, %ecx
callq 0x8c884
jmp 0x8da82
leaq 0x20(%rsp), %rdi
movq %rbx, %rsi
callq 0x8df1a
movq 0x20(%rsp), %r13
movq 0x30(%rsp), %rax
movq %rax, 0x8(%rsp)
xorpd %xmm0, %xmm0
movapd %xmm0, 0x20(%rsp)
movq $0x0, 0x30(%rsp)
testq %r15, %r15
je 0x8db05
movq 0x18(%rsp), %rsi
subq %r15, %rsi
movq %r15, %rdi
callq 0x229c0
movq 0x20(%rsp), %rdi
testq %rdi, %rdi
je 0x8db1c
movq 0x30(%rsp), %rsi
subq %rdi, %rsi
callq 0x229c0
cmpl $0x5, 0x1614(%rbx)
jb 0x8db75
movl 0x18e8(%rbx), %esi
movq 0xe845e(%rip), %rdi     # 0x175f90
callq 0x22650
movq %rax, %r15
movl $0x13, %edx
movq %rax, %rdi
leaq 0x7196f(%rip), %rsi     # 0xff4b8
callq 0x22ab0
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x22940
movsbl %al, %esi
movq %r15, %rdi
callq 0x22050
movq %rax, %rdi
callq 0x22660
movq 0x10(%rsp), %rax
cmpq %rax, 0x18b8(%rbx)
jb 0x8da75
jmp 0x8db95
movq $0x0, 0x8(%rsp)
xorl %r13d, %r13d
cmpl $0x2, 0x1614(%rbx)
jb 0x8dd19
movq 0xe83e7(%rip), %rdi     # 0x175f90
leaq 0x7191c(%rip), %rsi     # 0xff4cc
movl $0x1e, %edx
callq 0x22ab0
callq 0x220b0
subq 0x1db8(%rbx), %rax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
divsd 0x703da(%rip), %xmm0    # 0xfdfb0
movq 0xe83b3(%rip), %rdi     # 0x175f90
callq 0x23060
movq %rax, %r14
leaq 0x718ff(%rip), %rsi     # 0xff4eb
movl $0x9, %edx
movq %rax, %rdi
callq 0x22ab0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x22940
movsbl %al, %esi
movq %r14, %rdi
callq 0x22050
movq %rax, %rdi
callq 0x22660
movq 0xe8369(%rip), %rdi     # 0x175f90
leaq 0x718c7(%rip), %rsi     # 0xff4f5
movl $0xe, %edx
callq 0x22ab0
movq 0x1660(%rbx), %rsi
movq 0x1668(%rbx), %rdx
movq 0xe8343(%rip), %rdi     # 0x175f90
callq 0x22ab0
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x22940
movsbl %al, %esi
movq %r14, %rdi
callq 0x22050
movq %rax, %rdi
callq 0x22660
leaq 0x88(%rsp), %r14
movq %r14, -0x10(%r14)
movq 0x1660(%rbx), %rsi
movq 0x1668(%rbx), %rdx
addq %rsi, %rdx
leaq 0x78(%rsp), %rdi
callq 0x32180
leaq 0x78(%rsp), %rdi
callq 0xbe646
movl %eax, %ebp
movq 0x78(%rsp), %rdi
cmpq %r14, %rdi
je 0x8dcc9
movq 0x88(%rsp), %rsi
incq %rsi
callq 0x229c0
movq 0xe82c0(%rip), %rdi     # 0x175f90
leaq 0x7182d(%rip), %rsi     # 0xff504
movl $0x18, %edx
callq 0x22ab0
movq 0xe82a8(%rip), %rdi     # 0x175f90
movl %ebp, %esi
callq 0x231e0
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x22940
movsbl %al, %esi
movq %r14, %rdi
callq 0x22050
movq %rax, %rdi
callq 0x22660
movq 0x70(%rsp), %rdi
callq 0xb030c
movq 0x68(%rsp), %rdi
callq 0xb030c
cmpl $0x3, 0x1614(%rbx)
jb 0x8dd4e
movq 0xe8253(%rip), %rdi     # 0x175f90
leaq 0x717d9(%rip), %rsi     # 0xff51d
movl $0x29, %edx
callq 0x22ab0
movl 0x1620(%rbx), %eax
addl $-0x3, %eax
cmpq %rax, 0x19f8(%rbx)
ja 0x8dda9
incl 0x13e8(%rbx)
testq %r13, %r13
je 0x8dd7b
movq 0x8(%rsp), %rsi
subq %r13, %rsi
movq %r13, %rdi
callq 0x229c0
movq 0x48(%rsp), %rdi
leaq 0x58(%rsp), %rax
cmpq %rax, %rdi
je 0x8dd97
movq 0x58(%rsp), %rsi
incq %rsi
callq 0x229c0
addq $0x118, %rsp            # imm = 0x118
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rbx, %rdi
callq 0x86b24
leaq 0xe8(%rsp), %r14
movq %r14, -0x10(%r14)
leaq 0x71783(%rip), %rsi     # 0xff547
leaq 0x717dd(%rip), %rdx     # 0xff5a8
leaq 0xd8(%rsp), %rdi
callq 0x32210
leaq 0xd8(%rsp), %rsi
movq %rbx, %rdi
callq 0x78b66
movq %rax, %rbx
movq 0xd8(%rsp), %rdi
cmpq %r14, %rdi
je 0x8dece
movq 0xe8(%rsp), %rsi
jmp 0x8de46
jmp 0x8decb
movq %rax, %rbx
leaq 0xc8(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x8def5
movq 0xc8(%rsp), %rsi
jmp 0x8de6e
movq %rax, %rbx
movq 0x78(%rsp), %rdi
cmpq %r14, %rdi
je 0x8dece
movq 0x88(%rsp), %rsi
incq %rsi
callq 0x229c0
jmp 0x8dece
jmp 0x8deb1
movq %rax, %rbx
movq 0x98(%rsp), %rdi
cmpq %r14, %rdi
je 0x8def5
movq 0xa8(%rsp), %rsi
incq %rsi
jmp 0x8def0
movq %rax, %rbx
movq 0x20(%rsp), %rdi
cmpq %r14, %rdi
je 0x8de92
movq 0x30(%rsp), %rsi
incq %rsi
callq 0x229c0
jmp 0x8de92
movq %rax, %rbx
leaq 0x108(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x8df11
movq 0x108(%rsp), %rsi
jmp 0x8df09
jmp 0x8dec2
jmp 0x8decb
movq %rax, %rbx
movq $0x0, 0x8(%rsp)
xorl %r15d, %r15d
jmp 0x8dee0
movq %rax, %rbx
jmp 0x8def5
jmp 0x8decb
jmp 0x8ded3
movq %rax, %rbx
movq %r13, %r15
jmp 0x8dee0
movq %rax, %rbx
movq 0x18(%rsp), %rax
movq %rax, 0x8(%rsp)
testq %r15, %r15
je 0x8def5
movq 0x8(%rsp), %rsi
subq %r15, %rsi
movq %r15, %rdi
callq 0x229c0
movq 0x48(%rsp), %rdi
leaq 0x58(%rsp), %rax
cmpq %rax, %rdi
je 0x8df11
movq 0x58(%rsp), %rsi
incq %rsi
callq 0x229c0
movq %rbx, %rdi
callq 0x23240
nop