bool executive::ReconvergenceBarrier::eval_Bra(executive::CTAContext &context, 
	const ir::PTXInstruction &instr, 
	const boost::dynamic_bitset<> & branch, 
	const boost::dynamic_bitset<> & fallthrough) {
	
	bool isDivergent = false;
	
	if (instr.uni) {
		// unfiorm
		if (branch.count()) {
			// all threads branch
			context.PC = instr.branchTargetInstruction;
		}
		else {
			// all threads fall through
			context.PC ++;
		}
	}
	else {
		// divergence - complicated
		CTAContext branchContext(context), fallthroughContext(context);

		branchContext.active = branch;
		branchContext.PC = instr.branchTargetInstruction;

		fallthroughContext.active = fallthrough;
		fallthroughContext.PC++;

		runtimeStack.pop_back();
		
		if (branchContext.active.any()) {
			runtimeStack.push_back(branchContext);
		}
		
		if (fallthroughContext.active.any()) {
			runtimeStack.push_back(fallthroughContext);		
		}
		
		isDivergent = true;
	}
	
	return isDivergent;
}
示例#2
0
/// \brief Check if the split is informative
///
/// \param p The split
bool informative(const boost::dynamic_bitset<>& p) {
  int N = p.size();
  int C = p.count();
  return (C >= 2) and ((N-C) >= 2);
}
示例#3
0
std::size_t range_calculate_size(boost::dynamic_bitset<I,A> const& c) {
  return c.count();
}
bool executive::ReconvergenceIPDOM::eval_Bra(executive::CTAContext &context, 
	const ir::PTXInstruction &instr, 
	const boost::dynamic_bitset<> & branch, 
	const boost::dynamic_bitset<> & fallthrough) {

	bool isDivergent = false;
	if (instr.uni) {

		// unfiorm
		if (branch.count()) {
			// all threads branch
			context.PC = instr.branchTargetInstruction;
		}
		else {
			// all threads fall through
			context.PC ++;
		}
	}
	else {
		// divergence - complicated
		CTAContext branchContext(context), fallthroughContext(context),
			reconvergeContext(context);

		int pc = context.PC + 1;

		branchContext.active = branch;
		branchContext.PC = instr.branchTargetInstruction;

		fallthroughContext.active = fallthrough;
		fallthroughContext.PC = pc;
		
		reconvergeContext.PC = instr.reconvergeInstruction + 1;
		int reconverge = pcStack.back();
		Token token = tokenStack.back();
		
		runtimeStack.pop_back();
		pcStack.pop_back();
		tokenStack.pop_back();

		bool reconvergeContextAlreadyExists = false;

		// only look for existing contexts in the current stack frame
		if(token != Call) {
			auto ti = tokenStack.rbegin();
			for(auto si = runtimeStack.rbegin(); 
				si != runtimeStack.rend(); ++si, ++ti) {
				assert(ti != tokenStack.rend());
			
				if(si->PC == reconvergeContext.PC) {
					reconvergeContextAlreadyExists = true;
					break;
				}
			
				if(*ti != Branch) {
					continue;
				}
			}
		}
		
		if(!reconvergeContextAlreadyExists) {
			report(" (" << pc << ") Pushing reconvergence context at "
				<< reconvergeContext.PC << " (type " << toString(token) << ")");
			runtimeStack.push_back(reconvergeContext);
			pcStack.push_back(reconverge);
			tokenStack.push_back(token);
		}
		
		if (branchContext.active.any()) {
			report(" (" << pc << ") Pushing branch context at "
				<< branchContext.PC << ", reconverge at "
				<< instr.reconvergeInstruction
				<< " (type " << toString(Branch) << ")");
			runtimeStack.push_back(branchContext);
			pcStack.push_back(instr.reconvergeInstruction);
			tokenStack.push_back(Branch);
		}
		
		if (fallthroughContext.active.any()) {
			report(" (" << pc << ") Pushing fallthrough context at "
				<< fallthroughContext.PC << ", reconverge at "
				<< instr.reconvergeInstruction
				<< " (type " << toString(Branch) << ")");
			runtimeStack.push_back(fallthroughContext);		
			pcStack.push_back(instr.reconvergeInstruction);
			tokenStack.push_back(Branch);
		}
	}

	return isDivergent;
}