Ejemplo n.º 1
0
void check_route(enum e_route_type route_type, int num_switch,
		t_ivec ** clb_opins_used_locally) {

	/* This routine checks that a routing:  (1) Describes a properly         *
	 * connected path for each net, (2) this path connects all the           *
	 * pins spanned by that net, and (3) that no routing resources are       *
	 * oversubscribed (the occupancy of everything is recomputed from        *
	 * scratch).                                                             */

	int inet, ipin, max_pins, inode, prev_node;
	boolean valid, connects;
	boolean * connected_to_route; /* [0 .. num_rr_nodes-1] */
	struct s_trace *tptr;
	boolean * pin_done;

	vpr_printf(TIO_MESSAGE_INFO, "\n");
	vpr_printf(TIO_MESSAGE_INFO, "Checking to ensure routing is legal...\n");

	/* Recompute the occupancy from scratch and check for overuse of routing *
	 * resources.  This was already checked in order to determine that this  *
	 * is a successful routing, but I want to double check it here.          */

	recompute_occupancy_from_scratch(clb_opins_used_locally);
	valid = feasible_routing();
	if (valid == FALSE) {
		vpr_printf(TIO_MESSAGE_ERROR, "Error in check_route -- routing resources are overused.\n");
		exit(1);
	}

	check_locally_used_clb_opins(clb_opins_used_locally, route_type);

	connected_to_route = (boolean *) my_calloc(num_rr_nodes, sizeof(boolean));

	max_pins = 0;
	for (inet = 0; inet < num_nets; inet++)
		max_pins = std::max(max_pins, (clb_net[inet].num_sinks + 1));

	pin_done = (boolean *) my_malloc(max_pins * sizeof(boolean));

	/* Now check that all nets are indeed connected. */

	for (inet = 0; inet < num_nets; inet++) {

		if (clb_net[inet].is_global || clb_net[inet].num_sinks == 0) /* Skip global nets. */
			continue;

		for (ipin = 0; ipin < (clb_net[inet].num_sinks + 1); ipin++)
			pin_done[ipin] = FALSE;

		/* Check the SOURCE of the net. */

		tptr = trace_head[inet];
		if (tptr == NULL) {
			vpr_printf(TIO_MESSAGE_ERROR, "in check_route: net %d has no routing.\n", inet);
			exit(1);
		}

		inode = tptr->index;
		check_node_and_range(inode, route_type);
		check_switch(tptr, num_switch);
		connected_to_route[inode] = TRUE; /* Mark as in path. */

		check_source(inode, inet);
		pin_done[0] = TRUE;

		prev_node = inode;
		tptr = tptr->next;

		/* Check the rest of the net */

		while (tptr != NULL) {
			inode = tptr->index;
			check_node_and_range(inode, route_type);
			check_switch(tptr, num_switch);

			if (rr_node[prev_node].type == SINK) {
				if (connected_to_route[inode] == FALSE) {
					vpr_printf(TIO_MESSAGE_ERROR, "in check_route: node %d does not link into existing routing for net %d.\n", inode, inet);
					exit(1);
				}
			}

			else {
				connects = check_adjacent(prev_node, inode);
				if (!connects) {
					vpr_printf(TIO_MESSAGE_ERROR, "in check_route: found non-adjacent segments in traceback while checking net %d.\n", inet);
					exit(1);
				}

				if (connected_to_route[inode] && rr_node[inode].type != SINK) {

					/* Note:  Can get multiple connections to the same logically-equivalent     *
					 * SINK in some logic blocks.                                               */

					vpr_printf(TIO_MESSAGE_ERROR, "in check_route: net %d routing is not a tree.\n", inet);
					exit(1);
				}

				connected_to_route[inode] = TRUE; /* Mark as in path. */

				if (rr_node[inode].type == SINK)
					check_sink(inode, inet, pin_done);

			} /* End of prev_node type != SINK */
			prev_node = inode;
			tptr = tptr->next;
		} /* End while */

		if (rr_node[prev_node].type != SINK) {
			vpr_printf(TIO_MESSAGE_ERROR, "in check_route: net %d does not end with a SINK.\n", inet);
			exit(1);
		}

		for (ipin = 0; ipin < (clb_net[inet].num_sinks + 1); ipin++) {
			if (pin_done[ipin] == FALSE) {
				vpr_printf(TIO_MESSAGE_ERROR, "in check_route: net %d does not connect to pin %d.\n", inet, ipin);
				exit(1);
			}
		}

		reset_flags(inet, connected_to_route);

	} /* End for each net */

	free(pin_done);
	free(connected_to_route);
	vpr_printf(TIO_MESSAGE_INFO, "Completed routing consistency check successfully.\n");
	vpr_printf(TIO_MESSAGE_INFO, "\n");
}
Ejemplo n.º 2
0
int phrase_pos_match (ft_doc_index *doc_idx, ft_phrase_info *phrase_info, ft_word_info *words_info, int size_words_info)
{
	int index_to_comp_next_st[10] = {0};
	int *index_to_comp_next;
	int i, j, k, i_plus_1, last_i;

	// Before declaring various variables, given below the rationale behind their names. First, following are the various 
	// data structures to consider while performing the phrase match -
	// 1 - phrase info node, which contains an array. Value of element i of this array determines the index of the 
	// words_info array. At this index is the word_info object containing information about the i'th word of phrase
	// inside the document.
	// 2 - words_info, array of word_info type objects. Each element of this array contains information about some word
	// in the contains condition string. This information includes an array of positions, a selectivity value for that 
	// word, and the normalized frequency of the word. Note that not every word corresponding to nodes in this array 
	// need to appear in the phrase. But every word in phrase must appear in this array somewhere.
	// For two consecutive words in a phrase (k'th and k+1'th) -
	// info_index_i = index in word_info array for k'th word.
	// i = index of position array currently being used for k'th word present inside the word_info object 
	//		words_info[info_index_i].
	// limit_i = length of position array of words_info[info_index_i]. i will start from 0 and will go upto limit_i - 1.
	// pos_i = value at i'th location of position array of words_info[info_index_i]. This value represents the actual 
	//			position of i'th presence of k'th word in the document.
	// The same pattern goes for j which represents k+1'th word.
	int pos_i, pos_i_plus_1, pos_j, limit_i, limit_j, info_index_i, info_index_j;
	int result = TMAN_MATCH;
	int phrase_found = FALSE;

	// There must be atleast 2 words in the phrase.
	ASSERT (phrase_info->num_words >= 2);

	if (phrase_info->num_words > 10)
	{
		index_to_comp_next = (int *) tman_malloc (phrase_info->num_words * sizeof(int));
		memset (index_to_comp_next, 0, phrase_info->num_words * sizeof(int));
	}
	else
	{
		index_to_comp_next = index_to_comp_next_st;
	}
	
	last_i = -1;
	do
	{
		k = 0;
		// Get the last position compared for the first word.
		i = index_to_comp_next[k];

		// This statement helps detect the case when the position for first word did not change, which will result
		// in an infinite loop.
		ASSERT (i != last_i);
		last_i = i;
		// Get index for first word in phrase in the word info array.
		info_index_i = get_index_from_phrase_info (phrase_info, k);
		ASSERT (info_index_i < size_words_info);

		// Continue with phrase match only if the word exists.
		if (words_info[info_index_i].word_pos == NULL)
		{
			result = TMAN_NOMATCH;
			goto cleanup;
		}
		
		// The upper limit on index i is the size of word position arrays in the document.
		limit_i = va_get_size (words_info[info_index_i].word_pos);
	
		if (i == limit_i)
		{
			result = TMAN_NOMATCH;
			goto cleanup;
		}

		// The position of i'th occurance of the word inside the document.
		pos_i = (int) va_get_element (words_info[info_index_i].word_pos, i);
		k++;

		for (;k < phrase_info->num_words; k++)
		{
			phrase_found = FALSE;

			// Get the last positions compared for k'th word.
			j = index_to_comp_next[k];
			
			// Get index for word k in the word info array. This is required, since a word in phrase may appear
			// anywhere in the word info array.
			info_index_j = get_index_from_phrase_info (phrase_info, k);

			// In any case, this index should be less than the word info array itself.
			ASSERT (info_index_j < size_words_info);

			// Continue with phrase match only if the word exists.
			if (words_info[info_index_j].word_pos == NULL)
			{
				result = TMAN_NOMATCH;
				goto cleanup;
			}
			
			// The upper limit on index j is the size of word position arrays in the document.
			limit_j = va_get_size (words_info[info_index_j].word_pos);	

			// If the k'th word has been exhausted, phrase match fails. 
			if (j == limit_j) 
			{
				result = TMAN_NOMATCH;
				goto cleanup;
			}

			// Get the next position of k'th word of phrase in the document.
			pos_j = (int) va_get_element (words_info[info_index_j].word_pos, j);
		
			// Increment j till pos_j < pos_i.
			while (pos_i >= pos_j)
			{
				j++;
				// If j reaches its limit before pos_i becomes smaller than pos_j, phrase match failed, since the 
				// word k must appear after k-1 somewhere for phrase to match.
				if (j == limit_j) 
				{
					result = TMAN_NOMATCH;
					goto cleanup;
				}
				info_index_j = get_index_from_phrase_info (phrase_info, k);
				pos_j = (int) va_get_element (words_info[info_index_j].word_pos, j);
			}
		
			// If pos_j is also greater than pos_(i+1), the phrase match is impossible with i'th occurance of previous
			// word.
			i_plus_1 = i + 1;
			if (i_plus_1 == limit_i)
			{
				// Previous word has no more occurances after the i'th one. Let the phrase match continue among pos_i and
				// pos_j. Increment indices for comparing the next time.
				index_to_comp_next[k-1] = i + 1;
				index_to_comp_next[k] = j + 1;
			}
			else
			{
				pos_i_plus_1 = (int) va_get_element (words_info[info_index_i].word_pos, i_plus_1);
				if (pos_i_plus_1 >= pos_j)
				{
					// Let the phrase match continue among pos_i and pos_j here, since pos_i < pos_j <= pos_(i+1).
					// Increment indices for comparing the next time.
					index_to_comp_next[k-1] = i + 1;
					index_to_comp_next[k] = j + 1;
				}
				else
				{
					// There are more occurances of previous word before an occurance of this word. Change the index to 
					// compare next for the previous word, abort the phrase match among pos_i and pos_j, and restart the 
					// whole process of phrase matching again (from the outer do while loop).
					i_plus_1++;
					while (i_plus_1 < limit_i)
					{
						pos_i_plus_1 = (int) va_get_element (words_info[info_index_i].word_pos, i_plus_1);
						if (pos_i_plus_1 >= pos_j)
						{
							break;
						}
						i_plus_1++;
					}
					// Next time, the comparison for previous word should start at i, and for this one should start at j.
					i = i_plus_1 - 1;
					index_to_comp_next[k-1] = i;
					index_to_comp_next[k] = j;
					break;
				}
			}

			if (check_adjacent (doc_idx, pos_i, pos_j))
			{
				phrase_found = TRUE;
				i = j;
				limit_i = limit_j;
				pos_i = pos_j;
				info_index_i = info_index_j;

			}
			else 
			{
				// restart the whole process of phrase matching again (from the outer do while loop).
				phrase_found = FALSE;
				break;
			}
		}

		// It can only happen if we found an instance of phrase in the document.
		if (phrase_found == TRUE)
		{
			result = TMAN_MATCH;
			break;
		}
		// Go again in the loop to find the next instance of phrase.
	} while (TRUE);

cleanup:
	if (phrase_info->num_words > 10)
	{
		tman_free (index_to_comp_next);
	}

	// In case the phrase match did not succeed, we zero out the normal frequencies of the words that appear in the phrase.
	// That way, they will not be included in the scoring.
	if (result == TMAN_NOMATCH)
	{
		for (k = 0; k < phrase_info->num_words; k++)
		{
			info_index_i = get_index_from_phrase_info (phrase_info, k);
			words_info[info_index_i].norm_freq = 0.0;
		}
	}

	return (result);
}