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"); }
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); }