Пример #1
0
bool LayoutOperations::prepareSwappingCoordinatesFailedAlignment(CorblivarCore const& corb, int& tuple1) {
	std::vector<unsigned> failed_reqs_tuple_index;

	// determine failed alignments w/ flexible alignment handling; only such flexible
	// requests allow to swap their coordinates / partial requests
	for (unsigned r = 0; r < corb.getAlignments().size(); r++) {

		if (!corb.getAlignments()[r].fulfilled && corb.getAlignments()[r].handling == CorblivarAlignmentReq::Handling::FLEXIBLE) {
			failed_reqs_tuple_index.push_back(r);
		}
	}

	// randomly pick any failed alignment; onl
	if (!failed_reqs_tuple_index.empty()) {

		tuple1 = failed_reqs_tuple_index[Math::randI(0, failed_reqs_tuple_index.size())];

		if (CorblivarAlignmentReq::DBG_HANDLE_FAILED) {
			std::cout << "DBG_ALIGNMENT> " << corb.getAlignments()[tuple1].tupleString() << " failed so far;" << std::endl;
			std::cout << "DBG_ALIGNMENT> swapping flexible partial alignments (swapping x- and y-alignment)" << std::endl;
		}

		return true;
	}

	return false;
}
Пример #2
0
bool LayoutOperations::performOpSwapAlignmentCoordinates(bool const& revert, CorblivarCore& corb, int& tuple1) const {

	if (!revert) {

		// sanity check for assigned and valid tuple
		if (tuple1 == -1 || tuple1 >= static_cast<int>(corb.getAlignments().size())) {
			return false;
		}

		if (LayoutOperations::DBG) {
			std::cout << "DBG_LAYOUT> LayoutOperations::OP_SWAP_ALIGNMENT_COORDINATES; revert: " << revert <<
				"; tuple: " << tuple1 << std::endl;
		}

		corb.swapAlignmentCoordinates(tuple1);
	}
	else {
		if (LayoutOperations::DBG) {
			std::cout << "DBG_LAYOUT> LayoutOperations::OP_SWAP_ALIGNMENT_COORDINATES; revert: " << revert <<
				"; tuple: " << this->last_op_tuple1 << std::endl;
		}

		corb.swapAlignmentCoordinates(this->last_op_tuple1);
	}

	return true;
}
Пример #3
0
bool LayoutOperations::prepareBlockSwappingFailedAlignment(CorblivarCore const& corb, int& die1, int& tuple1, int& die2, int& tuple2) {
	CorblivarAlignmentReq const* failed_req = nullptr;
	std::vector<CorblivarAlignmentReq const*> failed_reqs;
	Block const* b1;
	Block const* b1_partner;
	Block const* b1_neighbour = nullptr;
	Rect bb;

	// determine failed alignments
	for (unsigned r = 0; r < corb.getAlignments().size(); r++) {

		if (!corb.getAlignments()[r].fulfilled) {
			failed_reqs.push_back(&corb.getAlignments()[r]);
		}
	}

	// randomly pick any failed alignment
	if (!failed_reqs.empty()) {

		failed_req = failed_reqs[Math::randI(0, failed_reqs.size())];

		// randomly decide for one block to move around / to swap with other
		// blocks; avoid the dummy reference block if required
		if (
			// randomly select s_i if it's not the RBOD
			(failed_req->s_i->numerical_id != RBOD::NUMERICAL_ID && Math::randB()) ||
			// also consider s_i if s_j is the RBOD
			failed_req->s_j->numerical_id == RBOD::NUMERICAL_ID
		   ) {
			// sanity check for both s_i and s_j being RBOD
			if (failed_req->s_i->numerical_id == RBOD::NUMERICAL_ID) {
				return false;
			}

			// s_i is the block to be changed
			b1 = failed_req->s_i;
			// memorize the opposite block s_j
			b1_partner = failed_req->s_j;
		}
		else {
			// s_j is the block to be changed
			b1 = failed_req->s_j;
			// memorize the opposite block s_i
			b1_partner = failed_req->s_i;
		}

		// determine die and tuple variables; tuple2 is to be determined below
		//
		die1 = b1->layer;
		tuple1 = corb.getDie(die1).getTuple(b1);
		// for RBOD being the partner, we assume the same die as for the block to
		// be changed
		if (b1_partner->numerical_id == RBOD::NUMERICAL_ID) {
			die2 = die1;
		}
		else {
			die2 = b1_partner->layer;
		}

		if (CorblivarAlignmentReq::DBG_HANDLE_FAILED) {
			std::cout << "DBG_ALIGNMENT> s_i: " << failed_req->s_i->id << std::endl;
			std::cout << "DBG_ALIGNMENT> s_j: " << failed_req->s_j->id << std::endl;
			std::cout << "DBG_ALIGNMENT> b1: " << b1->id << std::endl;
			std::cout << "DBG_ALIGNMENT> b1_partner: " << b1_partner->id << std::endl;
			std::cout << "DBG_ALIGNMENT> die1: " << die1 << std::endl;
			std::cout << "DBG_ALIGNMENT> tuple1: " << tuple1 << std::endl;
			std::cout << "DBG_ALIGNMENT> die2: " << die2 << std::endl;
			std::cout << "DBG_ALIGNMENT> tuple1: to be determined" << std::endl;
		}

		// dedicatedly defined vertical bus; failed vertical alignment across
		// different dies
		if (failed_req->vertical_bus()) {

			// select block to swap with b1 such that blocks to be aligned (b1
			// and its partner) are initially at least intersecting blocks;
			// that means, we need to swap with a block that is intersecting
			// with b1's partner block
			//
			// if b1 and its partner block are in one die, b1 needs to be
			// swapped with a block on another layer which is intersecting
			// b1's partner block; randomly select another layer
			//
			if (die1 == die2) {

				// such vertical alignment  is only possible for > 1
				// layers; sanity check
				if (this->parameters.layers == 1) {
					return false;
				}

				while (die1 == die2) {
					die2 = Math::randI(0, this->parameters.layers);
				}
			}
			// if b1 and its partner block are in different dies, b1 can be
			// swapped with a block intersecting b1's partner block on the
			// current die of b1
			else {
				die2 = die1;
			}

			// the block to swap w/ is stepwise searched according to this bb;
			// init it with the bb of b1's partner block
			bb = b1_partner->bb;

			while (true) {

				for (Block const* b2 : corb.getDie(die2).getBlocks()) {

					// candidate block; overlaps with b1's partner
					// block
					if (Rect::rectsIntersect(bb, b2->bb) &&
						// avoid swapping with b1 itself
						b1->numerical_id != b2->numerical_id &&
						// also check that blocks are not partner blocks
						// of the alignment request; otherwise,
						// consecutively circular swap might occur which
						// are not resolving the failing alignment
						!failed_req->partner_blocks(b1, b2)
					   ) {

						b1_neighbour = b2;

						break;
					}
				}

				// no intersecting block was found, increase the search
				// radius by doubling the considered bb
				if (b1_neighbour == nullptr) {

					bb.ll.x -= bb.w / 2.0;
					bb.ur.x += bb.w / 2.0;
					bb.ll.y -= bb.h / 2.0;
					bb.ur.y += bb.h / 2.0;
				}
				else {
					break;
				}
			}

		}

		// other failed alignment ranges or non-zero-offset fixed alignment
		//
		// determine relevant neighbour block to perform swap operation, i.e.,
		// nearest neighbour w.r.t. failure type
		else {

			// also consider to randomly change die2 as well; this is required
			// for alignments which cannot be fulfilled within one die and
			// does not harm for alignments which could be fulfilled within
			// one die (they can then also be fulfilled across dies); note
			// that an explicit check for all the different options of
			// alignments not possible within one die are not performed here
			// but rather a die change is considered randomly
			//
			// note that changing dies is only possible for > 1 layers
			if (Math::randB() && this->parameters.layers > 1) {

				while (die1 == die2) {
					die2 = Math::randI(0, this->parameters.layers);
				}
			}

			// consider different neighbours for different alignment failures
			switch (b1->alignment) {

				// determine nearest right block
				case Block::AlignmentStatus::FAIL_HOR_TOO_LEFT:
		
					for (Block const* b2 : corb.getDie(die2).getBlocks()) {

						if (Rect::rectA_leftOf_rectB(b1->bb, b2->bb, true) &&
							// also check that blocks are not partner blocks
							// of the alignment request; otherwise,
							// consecutively circular swap might occur which
							// are not resolving the failing alignment
							!failed_req->partner_blocks(b1, b2)
						   ) {

							if (b1_neighbour == nullptr || b2->bb.ll.x < b1_neighbour->bb.ll.x) {
								b1_neighbour = b2;
							}
						}
					}

					break;

				// determine nearest left block
				case Block::AlignmentStatus::FAIL_HOR_TOO_RIGHT:
		
					for (Block const* b2 : corb.getDie(die2).getBlocks()) {

						if (Rect::rectA_leftOf_rectB(b2->bb, b1->bb, true) &&
							// also check that blocks are not partner blocks
							// of the alignment request; otherwise,
							// consecutively circular swap might occur which
							// are not resolving the failing alignment
							!failed_req->partner_blocks(b1, b2)
						   ) {

							if (b1_neighbour == nullptr || b2->bb.ur.x > b1_neighbour->bb.ur.x) {
								b1_neighbour = b2;
							}
						}
					}

					break;

				// determine nearest block above
				case Block::AlignmentStatus::FAIL_VERT_TOO_LOW:
		
					for (Block const* b2 : corb.getDie(die2).getBlocks()) {

						if (Rect::rectA_below_rectB(b1->bb, b2->bb, true) &&
							// also check that blocks are not partner blocks
							// of the alignment request; otherwise,
							// consecutively circular swap might occur which
							// are not resolving the failing alignment
							!failed_req->partner_blocks(b1, b2)
						   ) {

							if (b1_neighbour == nullptr || b2->bb.ll.y < b1_neighbour->bb.ll.y) {
								b1_neighbour = b2;
							}
						}
					}

					break;

				// determine nearest block below
				case Block::AlignmentStatus::FAIL_VERT_TOO_HIGH:
		
					for (Block const* b2 : corb.getDie(die2).getBlocks()) {

						if (Rect::rectA_below_rectB(b2->bb, b1->bb, true) &&
							// also check that blocks are not partner blocks
							// of the alignment request; otherwise,
							// consecutively circular swap might occur which
							// are not resolving the failing alignment
							!failed_req->partner_blocks(b1, b2)
						   ) {

							if (b1_neighbour == nullptr || b2->bb.ur.y > b1_neighbour->bb.ur.y) {
								b1_neighbour = b2;
							}
						}
					}

					break;

				// dummy case, to catch other (here not occurring)
				// alignment status
				default:
					break;
			}
		}

		// determine related tuple of neighbour block; == -1 in case the tuple
		// cannot be find; sanity check for undefined neighbour
		if (b1_neighbour != nullptr) {

			tuple2 = corb.getDie(die2).getTuple(b1_neighbour);

			if (CorblivarAlignmentReq::DBG_HANDLE_FAILED) {
				std::cout << "DBG_ALIGNMENT> " << failed_req->tupleString() << " failed so far;" << std::endl;
				std::cout << "DBG_ALIGNMENT>  failed alignment status (" << b1->id << "): " << b1->alignment << std::endl;
				std::cout << "DBG_ALIGNMENT> considering swapping block " << b1->id << " on layer " << b1->layer;
				std::cout << " with block " << b1_neighbour->id << " on layer " << b1_neighbour->layer << std::endl;
			}

			return true;
		}
		else {
			tuple2 = -1;

			if (CorblivarAlignmentReq::DBG_HANDLE_FAILED) {
				std::cout << "DBG_ALIGNMENT> " << failed_req->tupleString() << " failed so far;" << std::endl;
				std::cout << "DBG_ALIGNMENT>  failed alignment status (" << b1->id << "): " << b1->alignment << std::endl;
				std::cout << "DBG_ALIGNMENT> no appropriate block to swap with found" << std::endl;
			}

			return false;
		}
	}

	// no failing request was found
	else {
		return false;
	}
}