// File: /workspace/github_cpp_makefile_star2_O2/richardposner[P]BioNetFit2/src/code/Swarm.cpp
// Function: Swarm::checkMasterMessagesDE()
unordered_map<unsigned int, vector<double> > Swarm::checkMasterMessagesDE() {

	unsigned int pID, subParID, mid=0; //Removed newlyFinishedParticles
	if (options.verbosity >= 3) { //razi: TODO test for multiple models
		//cout << "Checking messages DE, may need some modifications/test to support sbParticle" << endl;
	}

	unordered_map<unsigned int, vector<double> > subParticleParams;

	// First let's check interswarm communication
	int numMessages = swarmComm->recvMessage(-1, 0, -1, false, swarmComm->univMessageReceiver);

	if (numMessages >= 1) {
		if (options.verbosity >= 3) {
			//cout << "Found " << numMessages << " messages" << endl;
		}

		pair <Pheromones::swarmMsgHolderIt, Pheromones::swarmMsgHolderIt> smhRange;

		smhRange = swarmComm->univMessageReceiver.equal_range(SIMULATION_END);
		for (Pheromones::swarmMsgHolderIt sm = smhRange.first; sm != smhRange.second; ++sm) {
			subParID = sm->second.sender;
			pID = fcalcParID(subParID, options.models.size());
			mid= fcalcMID(subParID, options.models.size());

			if (options.verbosity >= 3) {
				//cout << "Particle " << pID << " finished simulation" << endl;
			}

			// Get an iterator to the particle in our list of running particles
			runningSubParticlesIterator_ = runningSubParticles_.find(subParID);
			// Then remove it
			if (runningSubParticlesIterator_ == runningSubParticles_.end()) {
				string errMsg = "Error: Couldn't remove subParticle " + toString(subParID) + " from runningParticle list.";
				cout << "Size of runningSubParticles_(2): " << runningSubParticles_.size() << endl;
				cout << "Subparticles in running list are: " << endl;
				for(auto myIt = runningSubParticles_.begin(); myIt != runningSubParticles_.end(); myIt++){
					cout << "first: " << *myIt << endl;

				}
				cout << "Done listing running particles. " << endl;
				outputError(errMsg);
			}
			runningSubParticles_.erase(runningSubParticlesIterator_);

			++particleIterationCounter_[pID][mid];
			update_finished_running_particles();

			/*
			// Only increment flight counter if we're finishing a trial set
			if (trial == true) {
				++flightCounter_;
			}
			 */

			/*
			unsigned int gen = currentGeneration;
			string paramsString;
			// Only output a run summary after a trial set has finished
			if (options.synchronicity == 1 && trial == true) {
				paramsString = "gen" + toString(static_cast<long long int>(gen)) + "perm" + toString(static_cast<long long int>(pID)) + " ";
			}
			else if (options.synchronicity == 0 && trial == true) {
				// TODO: This run summary contains 1 less particle than it should.
				// Output a run summary every outputEvery flights
				if (flightCounter_ % options.outputEvery == 0) {
					string outputPath = options.jobOutputDir + toString(static_cast<long long int>(flightCounter_)) + "_summary.txt";
					outputRunSummary(outputPath);
				}

				paramsString = toString(static_cast<long long int>(flightCounter_)) + " ";
			}
			 */

			double fitCalc = stod(sm->second.message[0]);

			/*
			bool replaceParams = false;
			if (trial == false) {
				particleBestFits_[pID] = fitCalc;
				insertKeyByValue(particleBestFitsByFit_, fitCalc, pID);
				replaceParams = true;
			}
			else if (trial == true && fitCalc < particleBestFits_.at(pID)) {
				cout << "replacing" << endl;
				particleBestFits_[pID] = fitCalc;
				insertKeyByValue(particleBestFitsByFit_, fitCalc, pID);
				replaceParams = true;
			}
			 */

			// Store the parameters given to us by the particle
			vector<double> paramsVec;
			paramsVec.push_back(fitCalc);
			//int i = 0;
			for (vector<string>::iterator m = sm->second.message.begin() + 1; m != sm->second.message.end(); ++m) {

				paramsVec.push_back(stod(*m));

				/*
				if (replaceParams) {
					//cout << "stored " << stod(*m) << " for particle " << pID << " as " << particleCurrParamSets_[pID][i] << endl;
					particleCurrParamSets_[pID][i] = stod(*m);
					paramsString += *m + " ";
				}
				else if (trial) {
					paramsString += toString(static_cast<long double>(particleCurrParamSets_[pID][i])) + " ";
				}
				 */

				//++i;
			}

			/*
			if (trial == true) {
				allGenFits.insert(pair<double, string>(particleBestFits_[pID], paramsString));
				swarmBestFits_.insert(pair<double, unsigned int>(fitCalc, pID));
			}
			 */

			subParticleParams.insert(pair<unsigned int, vector<double> >(subParID, paramsVec)); //razi: params for subparticle, then translate to particle params
			//cout << "done processing particle " << pID << endl;
		}

		// TODO: When sending NEXT_GENERATION, make sure failed particles have actually run again. If not, they need re-launched.
		smhRange = swarmComm->univMessageReceiver.equal_range(SIMULATION_FAIL);
		for (Pheromones::swarmMsgHolderIt sm = smhRange.first; sm != smhRange.second; ++sm) {

			subParID = sm->second.sender;
			pID = fcalcParID(subParID, options.models.size());
			mid= fcalcMID(subParID, options.models.size());

			// Get an iterator to the particle in our list of running particles
			runningSubParticlesIterator_ = runningSubParticles_.find(subParID);



			// Get an iterator to the particle in our list of running particles
			runningSubParticlesIterator_ = runningSubParticles_.find(subParID);
			if (runningSubParticlesIterator_ == runningSubParticles_.end()) {
				string errMsg = "Error: Couldn't remove particle " + toString(pID) +  "  SubParticle " + toString(subParID) + " from runningParticle list.";
				outputError(errMsg);
			}else
				runningSubParticles_.erase(runningSubParticlesIterator_);

			runningSubParticlesIterator_ = failedSubParticles_.find(subParID);
			if (runningSubParticlesIterator_== failedSubParticles_.end())  //add to the list of failed subparticles
				failedParticles_.insert(subParID);
			else{
				string errMsg = "Error: subParticle failed, but failure was already reported for particle " + toString(pID) +  "  SubParticle " + toString(subParID);
				outputError(errMsg);
			}
			update_finished_running_particles();



			// Increment our finished counter
			//finishedParticles.push_back(pID);
			subParticleParams.insert(pair<unsigned int, vector<double> >(subParID, vector<double>()));  //razi: params for subparticle, then translate to particle params
		}

		swarmComm->univMessageReceiver.clear();

	}

	return subParticleParams;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1a8, %rsp            # imm = 0x1A8
movq %rsi, %r14
andl $0x0, 0x1c(%rsp)
leaq 0x30(%rdi), %rax
movq %rax, (%rdi)
movq $0x1, 0x8(%rdi)
xorps %xmm0, %xmm0
movups %xmm0, 0x10(%rdi)
movl $0x3f800000, 0x20(%rdi) # imm = 0x3F800000
movq %rdi, 0x48(%rsp)
movups %xmm0, 0x28(%rdi)
movq (%rsi), %rdi
leaq 0x18(%rdi), %r9
orl $-0x1, 0x8(%rsp)
movl $0x1, (%rsp)
pushq $-0x1
popq %rcx
movl %ecx, %esi
xorl %edx, %edx
xorl %r8d, %r8d
callq 0x60fd6
testl %eax, %eax
jle 0x7c44a
movq (%r14), %rdi
addq $0x18, %rdi
leaq 0x50(%rsp), %rsi
movl $0xd, (%rsi)
callq 0x5da18
movq %rdx, 0x78(%rsp)
movq %rax, %r13
leaq 0x1820(%r14), %r12
leaq 0x1828(%r14), %rax
movq %rax, 0x80(%rsp)
leaq 0x1950(%r14), %rax
movq %rax, 0x70(%rsp)
leaq 0x20(%rsp), %rbx
leaq 0x50(%rsp), %rbp
cmpq 0x78(%rsp), %r13
je 0x7c2c7
movl 0x34(%r13), %edi
movl %edi, 0x14(%rsp)
movq 0x15c8(%r14), %rsi
subq 0x15c0(%r14), %rsi
shrq $0x3, %rsi
callq 0x9ec1e
movl %eax, 0x18(%rsp)
movl 0x14(%rsp), %edi
movq 0x15c8(%r14), %rsi
subq 0x15c0(%r14), %rsi
shrq $0x3, %rsi
callq 0x9ec14
movl %eax, 0x1c(%rsp)
movq %r12, %rdi
leaq 0x14(%rsp), %rsi
callq 0x8fa0c
movq %rax, 0x1850(%r14)
cmpq 0x80(%rsp), %rax
je 0x7c461
movq %r12, %rdi
movq %rax, %rsi
callq 0x8fa5e
movq 0x70(%rsp), %rdi
leaq 0x18(%rsp), %rsi
callq 0x865fc
movq %rax, %rdi
leaq 0x1c(%rsp), %rsi
callq 0x8665e
incl (%rax)
leaq 0x178(%rsp), %rdi
movq %r14, %rsi
callq 0x7bc26
leaq 0x178(%rsp), %rdi
callq 0x5b268
movq 0x38(%r13), %rdi
xorl %esi, %esi
callq 0x33525
movsd %xmm0, 0x88(%rsp)
xorps %xmm0, %xmm0
movaps %xmm0, 0x20(%rsp)
andq $0x0, 0x30(%rsp)
movq %rbx, %rdi
leaq 0x88(%rsp), %rsi
callq 0x5a080
movq 0x38(%r13), %r15
addq $0x20, %r15
cmpq 0x40(%r13), %r15
je 0x7c28a
movq %r15, %rdi
xorl %esi, %esi
callq 0x33525
movsd %xmm0, 0x50(%rsp)
movq %rbx, %rdi
movq %rbp, %rsi
callq 0x5c482
jmp 0x7c263
movl 0x14(%rsp), %eax
movl %eax, 0x50(%rsp)
leaq 0x58(%rsp), %rdi
movq %rbx, %rsi
callq 0x59fa2
movq 0x48(%rsp), %rdi
movq %rbp, %rsi
callq 0x8fd5e
leaq 0x58(%rsp), %rdi
callq 0x5c44e
movq %rbx, %rdi
callq 0x5c44e
movq (%r13), %r13
jmp 0x7c178
movq (%r14), %rdi
addq $0x18, %rdi
leaq 0x50(%rsp), %rsi
movl $0xe, (%rsi)
callq 0x5da18
movq %rdx, 0x78(%rsp)
movq %rax, %rbx
leaq 0x1858(%r14), %rax
movq %rax, 0x70(%rsp)
leaq 0x1860(%r14), %rax
movq %rax, 0xb0(%rsp)
leaq 0x19d0(%r14), %rax
movq %rax, 0xa8(%rsp)
leaq 0x14(%rsp), %rbp
leaq 0x190(%rsp), %r15
cmpq 0x78(%rsp), %rbx
je 0x7c43e
movl 0x34(%rbx), %edi
movl %edi, 0x14(%rsp)
movq 0x15c8(%r14), %rsi
subq 0x15c0(%r14), %rsi
shrq $0x3, %rsi
callq 0x9ec1e
movl %eax, 0x18(%rsp)
movl 0x14(%rsp), %edi
movq 0x15c8(%r14), %rsi
subq 0x15c0(%r14), %rsi
shrq $0x3, %rsi
callq 0x9ec14
movl %eax, 0x1c(%rsp)
movq %r12, %rdi
movq %rbp, %rsi
callq 0x8fa0c
movq %rax, 0x1850(%r14)
movq %r12, %rdi
movq %rbp, %rsi
callq 0x8fa0c
movq %rax, 0x1850(%r14)
cmpq 0x80(%rsp), %rax
je 0x7c60e
movq %r12, %rdi
movq %rax, %rsi
callq 0x8fa5e
movq 0x70(%rsp), %rdi
movq %rbp, %rsi
callq 0x8fa0c
movq %rax, 0x1850(%r14)
cmpq 0xb0(%rsp), %rax
jne 0x7c54d
movq 0xa8(%rsp), %rdi
movq %rbp, %rsi
callq 0x8f830
movq %r15, %rdi
movq %r14, %rsi
callq 0x7bc26
movq %r15, %r13
movq %r15, %rdi
callq 0x5b268
movl 0x14(%rsp), %eax
movl %eax, 0x50(%rsp)
leaq 0x58(%rsp), %r15
xorps %xmm0, %xmm0
movups %xmm0, (%r15)
andq $0x0, 0x10(%r15)
movaps %xmm0, 0x20(%rsp)
andq $0x0, 0x30(%rsp)
movq 0x48(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0x8fd5e
movq %r15, %rdi
callq 0x5c44e
leaq 0x20(%rsp), %rdi
callq 0x5c44e
movq (%rbx), %rbx
movq %r13, %r15
jmp 0x7c31d
movq (%r14), %rdi
addq $0x18, %rdi
callq 0x5d19a
movq 0x48(%rsp), %rax
addq $0x1a8, %rsp            # imm = 0x1A8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl 0x14(%rsp), %esi
leaq 0x88(%rsp), %rdi
callq 0x9f56b
leaq 0x61907(%rip), %rsi     # 0xddd80
leaq 0x20(%rsp), %rdi
leaq 0x88(%rsp), %rdx
callq 0x4933b
leaq 0x61912(%rip), %rdx     # 0xddda4
leaq 0x50(%rsp), %rdi
leaq 0x20(%rsp), %rsi
callq 0x3336c
leaq 0x20(%rsp), %rdi
callq 0x295a0
leaq 0x88(%rsp), %rdi
callq 0x295a0
movq 0xe9ad9(%rip), %rdi     # 0x165f98
leaq 0x61dd1(%rip), %rsi     # 0xde297
callq 0x289f0
movq 0x1848(%r14), %rsi
movq %rax, %rdi
callq 0x286e0
movq %rax, %rdi
callq 0x284a0
movq 0xe9aaf(%rip), %rdi     # 0x165f98
leaq 0x618ef(%rip), %rsi     # 0xddddf
callq 0x289f0
movq %rax, %rdi
callq 0x284a0
movq 0x1838(%r14), %r12
movq 0xe9a8d(%rip), %rbx     # 0x165f98
leaq 0x5b00f(%rip), %r15     # 0xd7521
cmpq 0x80(%rsp), %r12
je 0x7c6f8
movq %rbx, %rdi
movq %r15, %rsi
callq 0x289f0
movl 0x20(%r12), %esi
movq %rax, %rdi
callq 0x286e0
movq %rax, %rdi
callq 0x284a0
movq %r12, %rdi
callq 0x28b60
movq %rax, %r12
jmp 0x7c512
movl 0x18(%rsp), %esi
leaq 0xd8(%rsp), %rdi
callq 0x9f56b
leaq 0x61d54(%rip), %rsi     # 0xde2b9
leaq 0x88(%rsp), %rdi
leaq 0xd8(%rsp), %rdx
callq 0x4933b
leaq 0x61aff(%rip), %rdx     # 0xde080
leaq 0x20(%rsp), %rdi
leaq 0x88(%rsp), %rsi
callq 0x3336c
movl 0x14(%rsp), %esi
leaq 0xb8(%rsp), %rdi
callq 0x9f56b
leaq 0x50(%rsp), %rdi
leaq 0x20(%rsp), %rsi
leaq 0xb8(%rsp), %rdx
callq 0x4e6ed
leaq 0xb8(%rsp), %rdi
callq 0x295a0
leaq 0x20(%rsp), %rdi
callq 0x295a0
leaq 0x88(%rsp), %rdi
callq 0x295a0
leaq 0xd8(%rsp), %rdi
callq 0x295a0
leaq 0x118(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0x28dd0
leaq 0x118(%rsp), %rsi
movq %r14, %rdi
callq 0x6aed2
movl 0x18(%rsp), %esi
leaq 0xb8(%rsp), %rdi
callq 0x9f56b
leaq 0x61a39(%rip), %rsi     # 0xde05f
leaq 0xd8(%rsp), %rdi
leaq 0xb8(%rsp), %rdx
callq 0x4933b
leaq 0x61a3e(%rip), %rdx     # 0xde080
leaq 0x88(%rsp), %rdi
leaq 0xd8(%rsp), %rsi
callq 0x3336c
movl 0x14(%rsp), %esi
leaq 0xf8(%rsp), %rdi
callq 0x9f56b
leaq 0x20(%rsp), %rdi
leaq 0x88(%rsp), %rsi
leaq 0xf8(%rsp), %rdx
callq 0x4e6ed
leaq 0x6171b(%rip), %rdx     # 0xddda4
leaq 0x50(%rsp), %rdi
leaq 0x20(%rsp), %rsi
callq 0x3336c
leaq 0x20(%rsp), %rdi
callq 0x295a0
leaq 0xf8(%rsp), %rdi
callq 0x295a0
leaq 0x88(%rsp), %rdi
callq 0x295a0
leaq 0xd8(%rsp), %rdi
callq 0x295a0
leaq 0xb8(%rsp), %rdi
callq 0x295a0
leaq 0x138(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0x28dd0
leaq 0x138(%rsp), %rsi
movq %r14, %rdi
callq 0x6aed2
movq 0xe9899(%rip), %rdi     # 0x165f98
leaq 0x616fc(%rip), %rsi     # 0xdde02
callq 0x289f0
movq %rax, %rdi
callq 0x284a0
leaq 0x158(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0x28dd0
leaq 0x158(%rsp), %rsi
movq %r14, %rdi
callq 0x6aed2
movq %rax, %r14
leaq 0x158(%rsp), %rdi
jmp 0x7c770
jmp 0x7c7cd
movq %rax, %r14
leaq 0x138(%rsp), %rdi
jmp 0x7c770
jmp 0x7c7cd
movq %rax, %r14
leaq 0x20(%rsp), %rdi
callq 0x295a0
jmp 0x7c77c
movq %rax, %r14
leaq 0x118(%rsp), %rdi
callq 0x295a0
jmp 0x7c7d0
jmp 0x7c7cd
movq %rax, %r14
leaq 0xf8(%rsp), %rdi
callq 0x295a0
jmp 0x7c7af
movq %rax, %r14
leaq 0xb8(%rsp), %rdi
callq 0x295a0
jmp 0x7c7c1
jmp 0x7c863
jmp 0x7c863
jmp 0x7c863
movq %rax, %r14
leaq 0x88(%rsp), %rdi
callq 0x295a0
jmp 0x7c7da
movq %rax, %r14
leaq 0x20(%rsp), %rdi
callq 0x295a0
jmp 0x7c7ec
movq %rax, %r14
leaq 0x50(%rsp), %rdi
jmp 0x7c82f
movq %rax, %r14
leaq 0xd8(%rsp), %rdi
callq 0x295a0
jmp 0x7c80d
movq %rax, %r14
leaq 0x88(%rsp), %rdi
callq 0x295a0
jmp 0x7c81a
movq %rax, %r14
leaq 0x20(%rsp), %rdi
callq 0x295a0
jmp 0x7c827
movq %rax, %r14
leaq 0xb8(%rsp), %rdi
jmp 0x7c82f
movq %rax, %r14
leaq 0xd8(%rsp), %rdi
jmp 0x7c82f
movq %rax, %r14
leaq 0x88(%rsp), %rdi
callq 0x295a0
jmp 0x7c875
jmp 0x7c863
jmp 0x7c863
jmp 0x7c863
jmp 0x7c863
movq %rax, %r14
movq %r15, %rdi
jmp 0x7c854
jmp 0x7c863
jmp 0x7c863
jmp 0x7c868
movq %rax, %r14
leaq 0x58(%rsp), %rdi
callq 0x5c44e
jmp 0x7c86b
jmp 0x7c863
jmp 0x7c868
jmp 0x7c863
jmp 0x7c863
movq %rax, %r14
jmp 0x7c875
movq %rax, %r14
leaq 0x20(%rsp), %rdi
callq 0x5c44e
movq 0x48(%rsp), %rdi
callq 0x8b35a
movq %r14, %rdi
callq 0x292f0
nop