// File: 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
movq %rsp, %rbp
subq $0x180, %rsp            # imm = 0x180
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0xc8(%rbp)
addq $0x14c0, %rdi           # imm = 0x14C0
addq $0x100, %rdi            # imm = 0x100
callq 0x45170
movq %rax, %rcx
movq -0xc8(%rbp), %rax
movl %ecx, -0xc(%rbp)
cmpl $0x1, 0x1614(%rax)
jb 0x1038ed
movq 0x1d16c6(%rip), %rdi    # 0x2d4f50
leaq 0xde6eb(%rip), %rsi     # 0x1e1f7c
callq 0x2ff50
movq %rax, %rdi
movq -0xc8(%rbp), %rax
movl 0x13e8(%rax), %esi
callq 0x30640
movq %rax, %rdi
leaq 0xde6db(%rip), %rsi     # 0x1e1f90
callq 0x2ff50
movq %rax, %rdi
movq -0xc8(%rbp), %rax
movl 0x1620(%rax), %esi
callq 0x2f800
movq %rax, %rdi
leaq 0xde6be(%rip), %rsi     # 0x1e1f97
callq 0x2ff50
movq %rax, %rdi
movq 0x1d16e0(%rip), %rsi    # 0x2d4fc8
callq 0x30c10
leaq -0x30(%rbp), %rdi
callq 0xb2010
movq -0xc8(%rbp), %rdi
movl $0x0, -0x18(%rbp)
addq $0x1b70, %rdi           # imm = 0x1B70
callq 0x1232c0
movq -0xc8(%rbp), %rdi
addq $0x1c30, %rdi           # imm = 0x1C30
callq 0x1232c0
movq -0xc8(%rbp), %rdi
addq $0x18c0, %rdi           # imm = 0x18C0
callq 0x1232e0
movq -0xc8(%rbp), %rdi
addq $0x1890, %rdi           # imm = 0x1890
callq 0x1232e0
movq -0xc8(%rbp), %rdi
movl 0x1620(%rdi), %eax
movl %eax, -0xd4(%rbp)
addq $0x15c0, %rdi           # imm = 0x15C0
movq %rdi, -0xe0(%rbp)
callq 0x45170
movq -0xe0(%rbp), %rdi
decl %eax
movl %eax, -0xd0(%rbp)
callq 0x45170
movl -0xd4(%rbp), %edi
movl -0xd0(%rbp), %esi
movl %eax, %edx
callq 0x17d3a0
movl %eax, -0xcc(%rbp)
jmp 0x10399e
movq -0xc8(%rbp), %rax
movl -0xcc(%rbp), %ecx
movl %ecx, -0x34(%rbp)
movl $0x0, -0x48(%rbp)
cmpl $0x4, 0x1620(%rax)
jge 0x103a61
movq -0xc8(%rbp), %rdi
callq 0xf8ca0
jmp 0x1039d0
leaq -0x69(%rbp), %rdi
movq %rdi, -0xe8(%rbp)
callq 0x30a70
movq -0xe8(%rbp), %rdx
leaq 0xde727(%rip), %rsi     # 0x1e2115
leaq -0x68(%rbp), %rdi
callq 0x44470
jmp 0x1039f9
movq -0xc8(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0xeada0
jmp 0x103a0b
leaq -0x68(%rbp), %rdi
callq 0x311e8
leaq -0x69(%rbp), %rdi
callq 0x311c0
jmp 0x103a61
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x103ff8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x103a53
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x311e8
leaq -0x69(%rbp), %rdi
callq 0x311c0
jmp 0x103ff8
jmp 0x103a63
movq -0xc8(%rbp), %rdi
addq $0x18c0, %rdi           # imm = 0x18C0
callq 0x123340
movq %rax, %rcx
movq -0xc8(%rbp), %rax
movl 0x1620(%rax), %eax
movl $0x2, %esi
cltd
idivl %esi
movl %eax, %eax
movl %eax, %edx
movb $0x1, %al
cmpq %rdx, %rcx
movb %al, -0xe9(%rbp)
jbe 0x103abf
movq -0xc8(%rbp), %rdi
addq $0x18c0, %rdi           # imm = 0x18C0
callq 0x123340
cmpq $0x2, %rax
setbe %al
movb %al, -0xe9(%rbp)
movb -0xe9(%rbp), %al
testb $0x1, %al
jne 0x103ace
jmp 0x103e88
jmp 0x103ad0
movq -0xc8(%rbp), %rdi
addq $0x1820, %rdi           # imm = 0x1820
callq 0x123340
movq %rax, %rcx
movq -0xc8(%rbp), %rax
movl 0x1628(%rax), %eax
movl %eax, %edx
xorl %eax, %eax
cmpq %rdx, %rcx
movb %al, -0xea(%rbp)
jae 0x103b11
movl -0x18(%rbp), %eax
cmpl -0x34(%rbp), %eax
setb %al
movb %al, -0xea(%rbp)
movb -0xea(%rbp), %al
testb $0x1, %al
jne 0x103b1d
jmp 0x103b7f
movl -0x18(%rbp), %eax
incl %eax
movl %eax, -0x18(%rbp)
movl -0x18(%rbp), %edi
movl -0xc(%rbp), %esi
callq 0x17d3f0
movl %eax, -0xf0(%rbp)
jmp 0x103b38
movl -0xf0(%rbp), %eax
movl %eax, -0x10(%rbp)
movl -0x18(%rbp), %edi
movl -0xc(%rbp), %esi
callq 0x17d3d0
movl %eax, -0xf4(%rbp)
jmp 0x103b54
movq -0xc8(%rbp), %rdi
movl -0xf4(%rbp), %eax
movl %eax, -0x14(%rbp)
movl -0x10(%rbp), %esi
movl -0x14(%rbp), %edx
xorl %ecx, %ecx
callq 0x100000
jmp 0x103b73
movl $0x0, -0x48(%rbp)
jmp 0x103ad0
movq -0xc8(%rbp), %rsi
leaq -0x88(%rbp), %rdi
callq 0x101490
jmp 0x103b94
leaq -0x30(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x122bc0
leaq -0x88(%rbp), %rdi
callq 0xb2400
movq -0xc8(%rbp), %rax
cmpl $0x3, 0x1614(%rax)
jb 0x103c3a
movq 0x1d1389(%rip), %rdi    # 0x2d4f50
leaq 0xde5ba(%rip), %rsi     # 0x1e2188
callq 0x2ff50
movq %rax, -0x100(%rbp)
jmp 0x103bdc
movq -0xc8(%rbp), %rdi
addq $0x1c30, %rdi           # imm = 0x1C30
callq 0x122680
movq -0x100(%rbp), %rdi
movq %rax, %rsi
callq 0x30cf0
movq %rax, -0x108(%rbp)
jmp 0x103c07
movq -0x108(%rbp), %rdi
leaq 0xde5a0(%rip), %rsi     # 0x1e21b5
callq 0x2ff50
movq %rax, -0x110(%rbp)
jmp 0x103c23
movq -0x110(%rbp), %rdi
movq 0x1d1397(%rip), %rsi    # 0x2d4fc8
callq 0x30c10
jmp 0x103c38
jmp 0x103c3a
leaq -0x30(%rbp), %rdi
callq 0xb46f0
movq %rax, %rdx
movq -0xc8(%rbp), %rax
movl 0x1d84(%rax), %ecx
addq %rdx, %rcx
movl %ecx, 0x1d84(%rax)
cmpl $0x32, -0x48(%rbp)
jle 0x103db5
movq 0x1d12e3(%rip), %rdi    # 0x2d4f50
leaq 0xde398(%rip), %rsi     # 0x1e200c
callq 0x2ff50
movq %rax, -0x118(%rbp)
jmp 0x103c82
movq -0xc8(%rbp), %rdi
addq $0x1820, %rdi           # imm = 0x1820
callq 0x123340
movq -0x118(%rbp), %rdi
movq %rax, %rsi
callq 0x30cf0
movq %rax, -0x120(%rbp)
jmp 0x103cad
movq -0x120(%rbp), %rdi
leaq 0xde359(%rip), %rsi     # 0x1e2014
callq 0x2ff50
movq %rax, -0x128(%rbp)
jmp 0x103cc9
movq -0x128(%rbp), %rdi
movq -0xc8(%rbp), %rax
movl 0x13e8(%rax), %esi
callq 0x30640
movq %rax, -0x130(%rbp)
jmp 0x103ceb
movq -0x130(%rbp), %rdi
movq 0x1d12cf(%rip), %rsi    # 0x2d4fc8
callq 0x30c10
jmp 0x103d00
movq -0xc8(%rbp), %rdi
addq $0x1820, %rdi           # imm = 0x1820
callq 0x123360
movq %rax, -0x90(%rbp)
movq -0xc8(%rbp), %rdi
addq $0x1820, %rdi           # imm = 0x1820
callq 0x1233c0
movq %rax, -0x98(%rbp)
leaq -0x90(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x123390
testb $0x1, %al
jne 0x103d4d
jmp 0x103dae
movq -0xc8(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x138(%rbp)
leaq -0x90(%rbp), %rdi
callq 0x1233f0
movq -0x138(%rbp), %rdi
movq %rax, %rcx
movq -0xc8(%rbp), %rax
movl (%rcx), %edx
movq (%rax), %r9
movq %rsp, %rax
movl $0xffffffff, (%rax)     # imm = 0xFFFFFFFF
movl $0x12, %ecx
xorl %r8d, %r8d
movl %r8d, %esi
callq 0xcd520
jmp 0x103d9b
jmp 0x103d9d
leaq -0x90(%rbp), %rdi
callq 0x123410
jmp 0x103d1a
movl $0x0, -0x48(%rbp)
movq -0xc8(%rbp), %rax
cmpl $0x3, 0x1614(%rax)
jb 0x103e83
movq 0x1d1180(%rip), %rdi    # 0x2d4f50
leaq 0xde3f7(%rip), %rsi     # 0x1e21ce
callq 0x2ff50
movq %rax, -0x140(%rbp)
jmp 0x103de5
movq -0xc8(%rbp), %rdi
addq $0x1890, %rdi           # imm = 0x1890
callq 0x123340
movq -0x140(%rbp), %rdi
movq %rax, %rsi
callq 0x30cf0
movq %rax, -0x148(%rbp)
jmp 0x103e10
movq -0x148(%rbp), %rdi
movq 0x1d11aa(%rip), %rsi    # 0x2d4fc8
callq 0x30c10
jmp 0x103e25
movq 0x1d1124(%rip), %rdi    # 0x2d4f50
leaq 0xde3b3(%rip), %rsi     # 0x1e21e6
callq 0x2ff50
movq %rax, -0x150(%rbp)
jmp 0x103e41
movq -0xc8(%rbp), %rdi
addq $0x18c0, %rdi           # imm = 0x18C0
callq 0x123340
movq -0x150(%rbp), %rdi
movq %rax, %rsi
callq 0x30cf0
movq %rax, -0x158(%rbp)
jmp 0x103e6c
movq -0x158(%rbp), %rdi
movq 0x1d114e(%rip), %rsi    # 0x2d4fc8
callq 0x30c10
jmp 0x103e81
jmp 0x103e83
jmp 0x103a63
movq -0xc8(%rbp), %rax
cmpl $0x3, 0x1614(%rax)
jb 0x103ef6
movq 0x1d10b1(%rip), %rdi    # 0x2d4f50
leaq 0xde355(%rip), %rsi     # 0x1e21fb
callq 0x2ff50
movq %rax, -0x160(%rbp)
jmp 0x103eb4
movq -0xc8(%rbp), %rdi
addq $0x18c0, %rdi           # imm = 0x18C0
callq 0x123340
movq -0x160(%rbp), %rdi
movq %rax, %rsi
callq 0x30cf0
movq %rax, -0x168(%rbp)
jmp 0x103edf
movq -0x168(%rbp), %rdi
movq 0x1d10db(%rip), %rsi    # 0x2d4fc8
callq 0x30c10
jmp 0x103ef4
jmp 0x103ef6
movq -0xc8(%rbp), %rdi
addq $0x19d0, %rdi           # imm = 0x19D0
callq 0x123340
movq -0xc8(%rbp), %rcx
movl 0x1620(%rcx), %ecx
subl $0x3, %ecx
movl %ecx, %ecx
cmpq %rcx, %rax
jbe 0x103fc4
movq -0xc8(%rbp), %rdi
callq 0xf8ca0
jmp 0x103f32
leaq -0xb9(%rbp), %rdi
movq %rdi, -0x170(%rbp)
callq 0x30a70
movq -0x170(%rbp), %rdx
leaq 0xde160(%rip), %rsi     # 0x1e20b3
leaq -0xb8(%rbp), %rdi
callq 0x44470
jmp 0x103f61
movq -0xc8(%rbp), %rdi
leaq -0xb8(%rbp), %rsi
callq 0xeada0
jmp 0x103f76
leaq -0xb8(%rbp), %rdi
callq 0x311e8
leaq -0xb9(%rbp), %rdi
callq 0x311c0
jmp 0x103fc4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x103fb6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0xb8(%rbp), %rdi
callq 0x311e8
leaq -0xb9(%rbp), %rdi
callq 0x311c0
jmp 0x103ff8
movq -0xc8(%rbp), %rdi
movl 0x13e8(%rdi), %eax
addl $0x1, %eax
movl %eax, 0x13e8(%rdi)
addq $0x1890, %rdi           # imm = 0x1890
callq 0x1232e0
leaq -0x30(%rbp), %rdi
callq 0xb2400
addq $0x180, %rsp            # imm = 0x180
popq %rbp
retq
leaq -0x30(%rbp), %rdi
callq 0xb2400
movq -0x40(%rbp), %rdi
callq 0x30170
nopw (%rax,%rax)