// File: 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
movq %rsp, %rbp
subq $0x290, %rsp            # imm = 0x290
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x180(%rbp)
movq %rax, %rcx
addq $0x1520, %rcx           # imm = 0x1520
movq %rcx, -0x178(%rbp)
movl 0x13e8(%rax), %esi
leaq -0x68(%rbp), %rdi
movq %rdi, -0x170(%rbp)
callq 0x17e460
movq -0x178(%rbp), %rsi
movq -0x170(%rbp), %rdx
leaq -0x48(%rbp), %rdi
callq 0xb3380
jmp 0x100a6a
leaq 0xe18e2(%rip), %rdx     # 0x1e2353
leaq -0x28(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x441f0
jmp 0x100a80
leaq -0x48(%rbp), %rdi
callq 0x311e8
leaq -0x68(%rbp), %rdi
callq 0x311e8
leaq -0x98(%rbp), %rdi
leaq -0x28(%rbp), %rsi
callq 0x2f300
jmp 0x100aa4
leaq -0x98(%rbp), %rdi
callq 0x17d410
movl %eax, -0x184(%rbp)
jmp 0x100ab8
movl -0x184(%rbp), %eax
cmpl $0x0, %eax
setne %al
xorb $-0x1, %al
movb %al, -0x185(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x311e8
movb -0x185(%rbp), %al
testb $0x1, %al
jne 0x100ae7
jmp 0x100b98
leaq 0xd9ca9(%rip), %rsi     # 0x1da797
leaq -0xb8(%rbp), %rdi
leaq -0x28(%rbp), %rdx
callq 0x44240
jmp 0x100b00
leaq -0xb8(%rbp), %rdi
callq 0x17e3f0
jmp 0x100b0e
leaq -0xb8(%rbp), %rdi
callq 0x311e8
jmp 0x100b98
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x100b3f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x311e8
leaq -0x68(%rbp), %rdi
callq 0x311e8
jmp 0x10147e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x101475
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x311e8
jmp 0x101475
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0xb8(%rbp), %rdi
callq 0x311e8
jmp 0x101475
movq -0x180(%rbp), %rdi
addq $0x14c0, %rdi           # imm = 0x14C0
addq $0x100, %rdi            # imm = 0x100
callq 0x45170
movq %rax, %rcx
movq -0x180(%rbp), %rax
movl %ecx, -0xbc(%rbp)
cmpl $0x1, 0x1614(%rax)
jb 0x100c7e
movq 0x1d437a(%rip), %rdi    # 0x2d4f50
leaq 0xe139f(%rip), %rsi     # 0x1e1f7c
callq 0x2ff50
movq %rax, -0x190(%rbp)
jmp 0x100beb
movq -0x190(%rbp), %rdi
movq -0x180(%rbp), %rax
movl 0x13e8(%rax), %esi
callq 0x30640
movq %rax, -0x198(%rbp)
jmp 0x100c0d
movq -0x198(%rbp), %rdi
leaq 0xe1375(%rip), %rsi     # 0x1e1f90
callq 0x2ff50
movq %rax, -0x1a0(%rbp)
jmp 0x100c29
movq -0x1a0(%rbp), %rdi
movq -0x180(%rbp), %rax
movl 0x1620(%rax), %esi
callq 0x2f800
movq %rax, -0x1a8(%rbp)
jmp 0x100c4b
movq -0x1a8(%rbp), %rdi
leaq 0xe133e(%rip), %rsi     # 0x1e1f97
callq 0x2ff50
movq %rax, -0x1b0(%rbp)
jmp 0x100c67
movq -0x1b0(%rbp), %rdi
movq 0x1d4353(%rip), %rsi    # 0x2d4fc8
callq 0x30c10
jmp 0x100c7c
jmp 0x100c7e
movl $0x0, -0xc0(%rbp)
leaq -0xe8(%rbp), %rdi
callq 0xb2010
movq -0x180(%rbp), %rax
cmpl $0x3, 0x1614(%rax)
jb 0x100d33
movq 0x1d42a1(%rip), %rdi    # 0x2d4f50
leaq 0xe12ef(%rip), %rsi     # 0x1e1fa5
callq 0x2ff50
movq %rax, -0x1b8(%rbp)
jmp 0x100cc4
movq -0x180(%rbp), %rdi
addq $0x1c30, %rdi           # imm = 0x1C30
callq 0x122680
movq -0x1b8(%rbp), %rdi
movq %rax, %rsi
callq 0x30cf0
movq %rax, -0x1c0(%rbp)
jmp 0x100cef
movq -0x1c0(%rbp), %rdi
leaq 0xe12d0(%rip), %rsi     # 0x1e1fcd
callq 0x2ff50
movq %rax, -0x1c8(%rbp)
jmp 0x100d0b
movq -0x1c8(%rbp), %rdi
movq 0x1d42af(%rip), %rsi    # 0x2d4fc8
callq 0x30c10
jmp 0x100d20
jmp 0x100d33
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x101469
movq -0x180(%rbp), %rdi
movl $0x0, -0xcc(%rbp)
addq $0x1b70, %rdi           # imm = 0x1B70
callq 0x1232c0
movq -0x180(%rbp), %rdi
addq $0x1c30, %rdi           # imm = 0x1C30
callq 0x1232c0
movq -0x180(%rbp), %rdi
addq $0x18c0, %rdi           # imm = 0x18C0
callq 0x1232e0
movq -0x180(%rbp), %rdi
addq $0x1890, %rdi           # imm = 0x1890
callq 0x1232e0
movq -0x180(%rbp), %rdi
movl 0x1620(%rdi), %eax
movl %eax, -0x1d4(%rbp)
addq $0x15c0, %rdi           # imm = 0x15C0
movq %rdi, -0x1e0(%rbp)
callq 0x45170
movq -0x1e0(%rbp), %rdi
decl %eax
movl %eax, -0x1d0(%rbp)
callq 0x45170
movl -0x1d4(%rbp), %edi
movl -0x1d0(%rbp), %esi
movl %eax, %edx
callq 0x17d3a0
movl %eax, -0x1cc(%rbp)
jmp 0x100dde
movq -0x180(%rbp), %rax
movl -0x1cc(%rbp), %ecx
movl %ecx, -0xec(%rbp)
movl $0x0, -0xf0(%rbp)
cmpl $0x3, 0x1614(%rax)
jb 0x100e52
movq 0x1d4145(%rip), %rdi    # 0x2d4f50
leaq 0xe11d9(%rip), %rsi     # 0x1e1feb
callq 0x2ff50
movq %rax, -0x1e8(%rbp)
jmp 0x100e20
movq -0x1e8(%rbp), %rdi
movl -0xec(%rbp), %esi
callq 0x30640
movq %rax, -0x1f0(%rbp)
jmp 0x100e3b
movq -0x1f0(%rbp), %rdi
movq 0x1d417f(%rip), %rsi    # 0x2d4fc8
callq 0x30c10
jmp 0x100e50
jmp 0x100e52
movq -0x180(%rbp), %rdi
addq $0x1db8, %rdi           # imm = 0x1DB8
callq 0x123300
jmp 0x100e67
jmp 0x100e69
movq -0x180(%rbp), %rdi
addq $0x1890, %rdi           # imm = 0x1890
callq 0x123340
movl -0xec(%rbp), %ecx
cmpq %rcx, %rax
jae 0x101178
jmp 0x100e8d
movq -0x180(%rbp), %rdi
addq $0x1820, %rdi           # imm = 0x1820
callq 0x123340
movq %rax, %rcx
movq -0x180(%rbp), %rax
movl 0x1628(%rax), %eax
movl %eax, %edx
xorl %eax, %eax
cmpq %rdx, %rcx
movb %al, -0x1f1(%rbp)
jae 0x100ed4
movl -0xcc(%rbp), %eax
cmpl -0xec(%rbp), %eax
setb %al
movb %al, -0x1f1(%rbp)
movb -0x1f1(%rbp), %al
testb $0x1, %al
jne 0x100ee3
jmp 0x100f66
movl -0xcc(%rbp), %eax
incl %eax
movl %eax, -0xcc(%rbp)
movl -0xcc(%rbp), %edi
movl -0xbc(%rbp), %esi
callq 0x17d3f0
movl %eax, -0x1f8(%rbp)
jmp 0x100f0a
movl -0x1f8(%rbp), %eax
movl %eax, -0xc4(%rbp)
movl -0xcc(%rbp), %edi
movl -0xbc(%rbp), %esi
callq 0x17d3d0
movl %eax, -0x1fc(%rbp)
jmp 0x100f2f
movq -0x180(%rbp), %rdi
movl -0x1fc(%rbp), %eax
movl %eax, -0xc8(%rbp)
movl -0xc4(%rbp), %esi
movl -0xc8(%rbp), %edx
xorl %ecx, %ecx
callq 0x100000
jmp 0x100f57
movl $0x0, -0xf0(%rbp)
jmp 0x100e8d
movq -0x180(%rbp), %rsi
leaq -0x108(%rbp), %rdi
callq 0x101490
jmp 0x100f7b
leaq -0xe8(%rbp), %rdi
leaq -0x108(%rbp), %rsi
callq 0x122bc0
leaq -0x108(%rbp), %rdi
callq 0xb2400
movq -0x180(%rbp), %rdi
addq $0x18c0, %rdi           # imm = 0x18C0
callq 0x123340
movq %rax, %rcx
movq -0x180(%rbp), %rax
movl %ecx, -0xc0(%rbp)
cmpl $0x5, 0x1614(%rax)
jb 0x101014
movl -0xc0(%rbp), %esi
movq 0x1d3f7d(%rip), %rdi    # 0x2d4f50
callq 0x30640
movq %rax, -0x208(%rbp)
jmp 0x100fe1
movq -0x208(%rbp), %rdi
leaq 0xe1009(%rip), %rsi     # 0x1e1ff8
callq 0x2ff50
movq %rax, -0x210(%rbp)
jmp 0x100ffd
movq -0x210(%rbp), %rdi
movq 0x1d3fbd(%rip), %rsi    # 0x2d4fc8
callq 0x30c10
jmp 0x101012
jmp 0x101014
cmpl $0x32, -0xf0(%rbp)
jle 0x101173
movq 0x1d3f28(%rip), %rdi    # 0x2d4f50
leaq 0xe0fdd(%rip), %rsi     # 0x1e200c
callq 0x2ff50
movq %rax, -0x218(%rbp)
jmp 0x10103d
movq -0x180(%rbp), %rdi
addq $0x1820, %rdi           # imm = 0x1820
callq 0x123340
movq -0x218(%rbp), %rdi
movq %rax, %rsi
callq 0x30cf0
movq %rax, -0x220(%rbp)
jmp 0x101068
movq -0x220(%rbp), %rdi
leaq 0xe0f9e(%rip), %rsi     # 0x1e2014
callq 0x2ff50
movq %rax, -0x228(%rbp)
jmp 0x101084
movq -0x228(%rbp), %rdi
movq -0x180(%rbp), %rax
movl 0x13e8(%rax), %esi
callq 0x30640
movq %rax, -0x230(%rbp)
jmp 0x1010a6
movq -0x230(%rbp), %rdi
movq 0x1d3f14(%rip), %rsi    # 0x2d4fc8
callq 0x30c10
jmp 0x1010bb
movq -0x180(%rbp), %rdi
addq $0x1820, %rdi           # imm = 0x1820
callq 0x123360
movq %rax, -0x110(%rbp)
movq -0x180(%rbp), %rdi
addq $0x1820, %rdi           # imm = 0x1820
callq 0x1233c0
movq %rax, -0x118(%rbp)
leaq -0x110(%rbp), %rdi
leaq -0x118(%rbp), %rsi
callq 0x123390
testb $0x1, %al
jne 0x101108
jmp 0x101169
movq -0x180(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x238(%rbp)
leaq -0x110(%rbp), %rdi
callq 0x1233f0
movq -0x238(%rbp), %rdi
movq %rax, %rcx
movq -0x180(%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 0x101156
jmp 0x101158
leaq -0x110(%rbp), %rdi
callq 0x123410
jmp 0x1010d5
movl $0x0, -0xf0(%rbp)
jmp 0x100e69
movq -0x180(%rbp), %rax
cmpl $0x2, 0x1614(%rax)
jb 0x10131a
movq 0x1d3dbd(%rip), %rdi    # 0x2d4f50
leaq 0xe0e9e(%rip), %rsi     # 0x1e2038
callq 0x2ff50
movq %rax, -0x240(%rbp)
jmp 0x1011a8
movq -0x180(%rbp), %rdi
addq $0x1db8, %rdi           # imm = 0x1DB8
callq 0x122d20
movsd %xmm0, -0x248(%rbp)
jmp 0x1011c5
movsd -0x248(%rbp), %xmm0
movq -0x240(%rbp), %rdi
callq 0x30710
movq %rax, -0x250(%rbp)
jmp 0x1011e2
movq -0x250(%rbp), %rdi
leaq 0xe0e67(%rip), %rsi     # 0x1e2057
callq 0x2ff50
movq %rax, -0x258(%rbp)
jmp 0x1011fe
movq -0x258(%rbp), %rdi
movq 0x1d3dbc(%rip), %rsi    # 0x2d4fc8
callq 0x30c10
jmp 0x101213
movq 0x1d3d36(%rip), %rdi    # 0x2d4f50
leaq 0xe0e40(%rip), %rsi     # 0x1e2061
callq 0x2ff50
movq %rax, -0x260(%rbp)
jmp 0x10122f
movq -0x260(%rbp), %rdi
movq -0x180(%rbp), %rsi
addq $0x1660, %rsi           # imm = 0x1660
callq 0x2f780
movq %rax, -0x268(%rbp)
jmp 0x101252
movq -0x268(%rbp), %rdi
movq 0x1d3d68(%rip), %rsi    # 0x2d4fc8
callq 0x30c10
jmp 0x101267
movq -0x180(%rbp), %rsi
addq $0x1660, %rsi           # imm = 0x1660
leaq -0x140(%rbp), %rdi
callq 0x2f300
jmp 0x101283
leaq -0x140(%rbp), %rdi
callq 0x17c700
movl %eax, -0x26c(%rbp)
jmp 0x101297
leaq -0x140(%rbp), %rdi
callq 0x311e8
movl -0x26c(%rbp), %eax
movl %eax, -0x11c(%rbp)
movq 0x1d3c9a(%rip), %rdi    # 0x2d4f50
leaq 0xe0db3(%rip), %rsi     # 0x1e2070
callq 0x2ff50
movq %rax, -0x278(%rbp)
jmp 0x1012cb
movq -0x278(%rbp), %rdi
movl -0x11c(%rbp), %esi
callq 0x2f800
movq %rax, -0x280(%rbp)
jmp 0x1012e6
movq -0x280(%rbp), %rdi
movq 0x1d3cd4(%rip), %rsi    # 0x2d4fc8
callq 0x30c10
jmp 0x1012fb
jmp 0x10131a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x140(%rbp), %rdi
callq 0x311e8
jmp 0x101469
movq -0x180(%rbp), %rdi
addq $0x18c0, %rdi           # imm = 0x18C0
callq 0x1232e0
movq -0x180(%rbp), %rdi
addq $0x1890, %rdi           # imm = 0x1890
callq 0x1232e0
movq -0x180(%rbp), %rax
cmpl $0x3, 0x1614(%rax)
jb 0x101367
movq 0x1d3bf9(%rip), %rdi    # 0x2d4f50
leaq 0xe0d2b(%rip), %rsi     # 0x1e2089
callq 0x2ff50
jmp 0x101365
jmp 0x101367
movq -0x180(%rbp), %rdi
addq $0x19d0, %rdi           # imm = 0x19D0
callq 0x123340
movq -0x180(%rbp), %rcx
movl 0x1620(%rcx), %ecx
subl $0x3, %ecx
movl %ecx, %ecx
cmpq %rcx, %rax
jbe 0x101435
movq -0x180(%rbp), %rdi
callq 0xf8ca0
jmp 0x1013a3
leaq -0x161(%rbp), %rdi
movq %rdi, -0x288(%rbp)
callq 0x30a70
movq -0x288(%rbp), %rdx
leaq 0xe0cef(%rip), %rsi     # 0x1e20b3
leaq -0x160(%rbp), %rdi
callq 0x44470
jmp 0x1013d2
movq -0x180(%rbp), %rdi
leaq -0x160(%rbp), %rsi
callq 0xeada0
jmp 0x1013e7
leaq -0x160(%rbp), %rdi
callq 0x311e8
leaq -0x161(%rbp), %rdi
callq 0x311c0
jmp 0x101435
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x101427
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x160(%rbp), %rdi
callq 0x311e8
leaq -0x161(%rbp), %rdi
callq 0x311c0
jmp 0x101469
movq -0x180(%rbp), %rax
movl 0x13e8(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x13e8(%rax)
leaq -0xe8(%rbp), %rdi
callq 0xb2400
leaq -0x28(%rbp), %rdi
callq 0x311e8
addq $0x290, %rsp            # imm = 0x290
popq %rbp
retq
leaq -0xe8(%rbp), %rdi
callq 0xb2400
leaq -0x28(%rbp), %rdi
callq 0x311e8
movq -0x70(%rbp), %rdi
callq 0x30170
nopw (%rax,%rax)