// File: /workspace/github_cpp_makefile_star2_O3/richardposner[P]BioNetFit2/src/code/Swarm.cpp
// Function: Swarm::runAsyncGeneration()
void Swarm::runAsyncGeneration() {   //Raquel: added new function to run assynchronous generations
	// TODO: Implement walltime
	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


	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.swarmSize<4){

		finishFit();
		outputError("Error: If running an asynchronous run please set a swarm size of at least 4, otherwise run the synchronous method.");


	}

	while ( (finishedParticles_.size() <= (unsigned) (options.swarmSize/2) || finishedParticles_.size() <= 2 ) ) { //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();
		if(options.verbosity>=3){

			cout << "@@@@@@@@@@@@@@ SIZE AFTER CHECKING MESSAGES " <<  currentsubswarmBestFits_.size() << " @@@@@@@@@@@@@@@@@@@@@@@" <<endl;

		}
		flightCounter_ += newFinishedParticles.size();
		//cout << "RAQUEL Done checkMasterMessages newFinishedParticles.size() " << newFinishedParticles.size() << endl;
		//cout << "Flight counter = " << flightCounter_ << 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(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 >= 3){
			cout << "FINISHED SUBPARTICLES: " << finishedSubParticles_.size() << endl;
			cout << "FINISHED PARTICLES: " << finishedParticles_.size() << endl;
		}

	}



	/*
	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 .... Particles finished: " << finishedParticles_.size() << endl;}

	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;



		//finishedParticles_.clear();
		finishedSubParticles_.clear(); //Raquel added to solve problem of less and less result files as generations go




}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movq %rdi, %rbx
movq 0x15c8(%rdi), %r13
subq 0x15c0(%rdi), %r13
cmpl $0x0, 0x1614(%rdi)
je 0x8fdcd
movq 0xe6260(%rip), %r14     # 0x175fa8
leaq 0x6f75d(%rip), %rsi     # 0xff4ac
movl $0x13, %edx
movq %r14, %rdi
callq 0x22ab0
movl 0x13e8(%rbx), %esi
movq %r14, %rdi
callq 0x22650
movq %rax, %r14
leaq 0x6f74c(%rip), %rsi     # 0xff4c0
movl $0x6, %edx
movq %rax, %rdi
callq 0x22ab0
movl 0x1620(%rbx), %esi
movq %r14, %rdi
callq 0x231e0
movq %rax, %r14
leaq 0x6f72e(%rip), %rsi     # 0xff4c7
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
leaq 0x1b70(%rbx), %rdi
callq 0xafaaa
leaq 0x1c30(%rbx), %rdi
callq 0xafaaa
leaq 0x18c0(%rbx), %rdi
callq 0xafad8
leaq 0x1890(%rbx), %rdi
movq %rdi, 0x28(%rsp)
callq 0xafad8
movl 0x1620(%rbx), %edi
movq 0x15c8(%rbx), %rdx
subq 0x15c0(%rbx), %rdx
shrq $0x3, %rdx
leal -0x1(%rdx), %esi
callq 0xbe989
movl %eax, %ebp
movl 0x1620(%rbx), %eax
cmpl $0x4, %eax
jl 0x9013c
movq 0x18e8(%rbx), %rcx
movl %eax, %edx
shrl %edx
cmpq %rdx, %rcx
seta %dl
cmpq $0x3, %rcx
setae %cl
xorl %r15d, %r15d
testb %dl, %cl
jne 0x90074
shrq $0x3, %r13
xorl %r12d, %r12d
movq $0x0, 0x8(%rsp)
movq 0x8(%rsp), %rax
movq %rax, 0x18(%rsp)
movq %r12, 0x20(%rsp)
movl 0x1628(%rbx), %eax
cmpq %rax, 0x1848(%rbx)
jae 0x8feb6
cmpl %ebp, %r15d
jae 0x8feb6
incl %r15d
movl %r15d, %edi
movl %r13d, %esi
callq 0xbe99e
movl %eax, %r14d
movl %r15d, %edi
movl %r13d, %esi
callq 0xbe994
movq %rbx, %rdi
movl %r14d, %esi
movl %eax, %edx
xorl %ecx, %ecx
callq 0x8bf54
jmp 0x8fe75
leaq 0x30(%rsp), %rdi
movq %rbx, %rsi
callq 0x8d5d8
movq 0x30(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x38(%rsp), %r12
movq 0x40(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0x20(%rsp), %rdi
testq %rdi, %rdi
je 0x8fef3
movq 0x18(%rsp), %rsi
subq %rdi, %rsi
callq 0x229c0
cmpl $0x2, 0x1614(%rbx)
jbe 0x90034
movl $0x2c, %edx
movq 0xe609c(%rip), %rdi     # 0x175fa8
leaq 0x6f779(%rip), %rsi     # 0xff68c
callq 0x22ab0
movq 0x1c58(%rbx), %rsi
movq 0xe6082(%rip), %rdi     # 0x175fa8
callq 0x22650
movq %rax, %r14
movl $0x18, %edx
movq %rax, %rdi
leaq 0x6f77c(%rip), %rsi     # 0xff6b9
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
movl 0x1614(%rbx), %eax
subq 0x10(%rsp), %r12
shrq $0x2, %r12
addl %r12d, 0x1d84(%rbx)
cmpl $0x3, %eax
jb 0x90044
movl $0x17, %edx
movq 0xe6014(%rip), %rdi     # 0x175fa8
leaq 0x6f737(%rip), %rsi     # 0xff6d2
callq 0x22ab0
movq 0x18b8(%rbx), %rsi
movq 0xe5ffa(%rip), %rdi     # 0x175fa8
callq 0x22650
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
movl $0x14, %edx
movq 0xe5fbf(%rip), %rdi     # 0x175fa8
leaq 0x6f6fa(%rip), %rsi     # 0xff6ea
callq 0x22ab0
movq 0x18e8(%rbx), %rsi
movq 0xe5fa5(%rip), %rdi     # 0x175fa8
callq 0x22650
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
jmp 0x90044
subq 0x10(%rsp), %r12
shrq $0x2, %r12
addl %r12d, 0x1d84(%rbx)
movq 0x18e8(%rbx), %rcx
cmpq $0x3, %rcx
movq 0x10(%rsp), %r12
jb 0x8fe66
movl 0x1620(%rbx), %eax
movl %eax, %edx
shrl $0x1f, %edx
addl %eax, %edx
sarl %edx
cmpq %rdx, %rcx
jbe 0x8fe66
jmp 0x90080
movq $0x0, 0x8(%rsp)
xorl %r12d, %r12d
cmpl $0x3, 0x1614(%rbx)
jb 0x900e4
movq 0xe5f18(%rip), %rdi     # 0x175fa8
leaq 0x6f668(%rip), %rsi     # 0xff6ff
movl $0x3d, %edx
callq 0x22ab0
movq 0x18e8(%rbx), %rsi
movq 0xe5ef9(%rip), %rdi     # 0x175fa8
callq 0x22650
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
movl 0x1620(%rbx), %eax
addl $-0x3, %eax
cmpq %rax, 0x19f8(%rbx)
ja 0x9017f
incl 0x13e8(%rbx)
movq 0x28(%rsp), %rdi
callq 0xafad8
testq %r12, %r12
je 0x9012a
movq 0x8(%rsp), %rsi
subq %r12, %rsi
movq %r12, %rdi
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x229c0
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq $0x0, 0x8(%rsp)
xorl %r12d, %r12d
movq %rbx, %rdi
callq 0x86314
leaq 0x78(%rsp), %r15
movq %r15, -0x10(%r15)
leaq 0x6f4b9(%rip), %rsi     # 0xff619
leaq 0x6f524(%rip), %rdx     # 0xff68b
leaq 0x68(%rsp), %r14
movq %r14, %rdi
callq 0x321d2
movq %rbx, %rdi
movq %r14, %rsi
callq 0x784c2
movq %rbx, %rdi
callq 0x86314
leaq 0x58(%rsp), %r14
movq %r14, -0x10(%r14)
leaq 0x6f420(%rip), %rsi     # 0xff5b7
leaq 0x6f47a(%rip), %rdx     # 0xff618
leaq 0x48(%rsp), %rdi
callq 0x321d2
leaq 0x48(%rsp), %rsi
movq %rbx, %rdi
callq 0x784c2
movq %rax, %rbx
movq 0x48(%rsp), %rdi
cmpq %r14, %rdi
je 0x9020d
movq 0x58(%rsp), %rsi
incq %rsi
callq 0x229c0
jmp 0x9020d
jmp 0x901ea
movq %rax, %rbx
movq 0x68(%rsp), %rdi
cmpq %r15, %rdi
je 0x90222
movq 0x78(%rsp), %rsi
incq %rsi
jmp 0x9021d
movq %rax, %rbx
jmp 0x9020d
jmp 0x901fb
movq %rax, %rbx
movq 0x10(%rsp), %r12
jmp 0x9020d
movq %rax, %rbx
movq 0x18(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0x20(%rsp), %r12
testq %r12, %r12
je 0x90222
movq 0x8(%rsp), %rsi
subq %r12, %rsi
movq %r12, %rdi
callq 0x229c0
movq %rbx, %rdi
callq 0x23240