Exemple #1
0
/**
 * This function tries to resolve the conditions of the graph #n.
 * It returns 1 if at least one condition was resolved.
 */
int resolve_conditions_for_one_graph(int n,ConditionList* conditions,
                                     Fst2State* states,int* initial_states,U_FILE*ferr) {
int modification=0;
int matches_E=DOES_NOT_KNOW_IF_E_IS_MATCHED;
if (conditions[n]==NULL) {
   error("NULL internal error in resolve_conditions_for_one_graph for graph %d\n",n);
   if (ferr != NULL)
     u_fprintf(ferr,"NULL internal error in resolve_conditions_for_one_graph for graph %d\n",n);
   return modification;
}
conditions[n]=resolve_condition_list(conditions[n],states,initial_states,&modification,&matches_E,ferr);
if (matches_E==E_IS_MATCHED) {
   /* If at least one condition was verified */
   set_bit_mask(&(states[initial_states[n]]->control),UNCONDITIONAL_E_MATCH);
   /* We can free the conditions */
   free_ConditionList(conditions[n]);
   conditions[n]=NULL;
   return 1;
}
if (conditions[n]==NULL) {
   /* If the graph has no more condition, then we mark it as unable to match <E> */
   set_bit_mask(&(states[initial_states[n]]->control),DOES_NOT_MATCH_E);
   free_ConditionList(conditions[n]);
   conditions[n]=NULL;
   return 1;
}
return modification;
}
Exemple #2
0
/**
 * Explores the transitions that outgo from the given state.
 * Returns 1 if a recursion is found; 0 otherwise.
 */
int explore_state(int state_number,struct list_int* l,Fst2* fst2,int* graphs_matching_E,U_FILE*ferr) {
Fst2State s=fst2->states[state_number];
int ret=0;
if (s==NULL) return 0;
if (is_bit_mask_set(s->control,TMP_LOOP_MARK|VISITED_MARK)) {
   /* If this state has already been processed */
   return 0;
}
set_bit_mask(&(s->control),TMP_LOOP_MARK|VISITED_MARK);
Transition* list=s->transitions;
while (list!=NULL) {
   if (list->tag_number<0) {
      /* If we have a subgraph call */
      if (look_for_recursion(-(list->tag_number),l,fst2,graphs_matching_E,ferr)) {
         /* If there is a recursion */
         return 1;
      }
      if (graphs_matching_E[-list->tag_number] && explore_state(list->state_number,l,fst2,graphs_matching_E,ferr)) {
         /* If the graph matches <E> */
         return 1;
      }
   } else if (fst2->tags[list->tag_number]->control==1) {
      /* If we have a transition that can match <E> */
      if (explore_state(list->state_number,l,fst2,graphs_matching_E,ferr)) {
         return 1;
      }
   }
   list=list->next;
}
unset_bit_mask(&(s->control),TMP_LOOP_MARK);
return ret;
}
Exemple #3
0
/**
 * Returns 1 if the given state has already been visited; 0 otherwise.
 */
int look_for_E_loop_in_state(int state_number,Fst2* fst2,int* graphs_matching_E) {
Transition* l;
Fst2State e=fst2->states[state_number];
if (is_bit_mask_set(e->control,TMP_LOOP_MARK)) {
   /* If we have already visited this state */
   unset_bit_mask(&(e->control),TMP_LOOP_MARK);
   return 1;
}
set_bit_mask(&(e->control),TMP_LOOP_MARK);
l=e->transitions;
while (l!=NULL) {
   if (l->tag_number<0) {
      /* If we have a graph call */
      if (graphs_matching_E[-l->tag_number]) {
         /* And if we can cross it because it matches <E> */
         if (look_for_E_loop_in_state(l->state_number,fst2,graphs_matching_E)) {
            /* And if we have reached the current state via an <E> loop */
            unset_bit_mask(&(e->control),TMP_LOOP_MARK);
            return 1;
         }
      }
   }
   else if (fst2->tags[l->tag_number]->control==1) {
      /* If we have a tag that can match <E> */
      if (look_for_E_loop_in_state(l->state_number,fst2,graphs_matching_E)) {
         /* And if we have reached the current state via an <E> loop */
         unset_bit_mask(&(e->control),TMP_LOOP_MARK);
         return 1;
      }
   }
  l=l->next;
}
unset_bit_mask(&(e->control),TMP_LOOP_MARK);
return 0;
}
Exemple #4
0
/**
 * This function looks for each graph if it can resolve a condition.
 * 
 * It returns a non zero value if some conditions have been resolved, 
 * even just one; 0 otherwise.
 */
int resolve_conditions(ConditionList* conditions,int n_graphs,
                       Fst2State* states,int* initial_states,U_FILE*ferr) {
int modification=0;
for (int i=1;i<n_graphs+1;i++) {
   if (!is_bit_mask_set(states[initial_states[i]]->control,
                        UNCONDITIONAL_E_MATCH|DOES_NOT_MATCH_E)) {
      /* If we don't already know the status of the current graph */
      if (!is_bit_mask_set(states[initial_states[i]]->control,CONDITIONAL_E_MATCH)) {
         /* If there is no conditionnal match, then we say that it does
          * not match <E> */
         set_bit_mask(&(states[initial_states[i]]->control),DOES_NOT_MATCH_E);
         modification++;
      } else {
         /* Otherwise, we try to solve the conditions of the graph */
         modification=modification+resolve_conditions_for_one_graph(i,conditions,states,initial_states,ferr);
      }
   }
}
return modification;
}
Exemple #5
0
/**
 * Returns a control byte that represents the characteristics of the given token.
 */
unsigned char get_control_byte(const unichar* token,const Alphabet* alph,struct string_hash* err,TokenizationPolicy tokenization_policy) {
    int i;
    int tmp;
    unsigned char c=0;
    if (token==NULL || token[0]=='\0') {
        fatal_error("NULL or empty token in get_control_byte\n");
    }
    /* We consider that a token starting with a letter is a word */
    if (is_letter(token[0],alph)) {
        set_bit_mask(&c,MOT_TOKEN_BIT_MASK);
        /* If a token is a word, we check if it is in the 'err' word list
         * in order to answer the question <!DIC>. We perform this test in order
         * to avoid taking "priori" as an unknown word if the compound "a priori"
         * is in the text. */
        if (err!=NULL && get_value_index(token,err,DONT_INSERT)!=-1) {
            set_bit_mask(&c,NOT_DIC_TOKEN_BIT_MASK);
        }
        if (is_upper(token[0],alph)) {
            set_bit_mask(&c,PRE_TOKEN_BIT_MASK);
            i=0;
            tmp=0;
            while (token[i]!='\0') {
                if (is_lower(token[i],alph)) {
                    tmp=1;
                    break;
                }
                i++;
            }
            if (!tmp) {
                set_bit_mask(&c,MAJ_TOKEN_BIT_MASK);
            }
            return c;
        }
        i=0;
        tmp=0;
        while (token[i]!='\0') {
            if (is_upper(token[i],alph)) {
                tmp=1;
                break;
            }
            i++;
        }
        if (!tmp) {
            set_bit_mask(&c,MIN_TOKEN_BIT_MASK);
        }
        return c;
    }
    /* If the token doesn't start with a letter, we start with
     * checking if it is a tag like {today,.ADV} */
    if (token[0]=='{' && u_strcmp(token,"{S}") && u_strcmp(token,"{STOP}")) {
        /* Anyway, such a tag is classed as verifying <MOT> and <DIC> */
        set_bit_mask(&c,MOT_TOKEN_BIT_MASK|DIC_TOKEN_BIT_MASK|TDIC_TOKEN_BIT_MASK);
        struct dela_entry* temp=tokenize_tag_token(token);
        if (is_upper(temp->inflected[0],alph)) {
            set_bit_mask(&c,PRE_TOKEN_BIT_MASK);
            i=0;
            tmp=0;
            while (temp->inflected[i]!='\0') {
                if (is_letter(temp->inflected[i],alph) && is_lower(temp->inflected[i],alph)) {
                    tmp=1;
                    break;
                }
                i++;
            }
            if (!tmp) {
                set_bit_mask(&c,MAJ_TOKEN_BIT_MASK);
            }
        }
        else {
            i=0;
            tmp=0;
            while (temp->inflected[i]!='\0') {
                if (is_letter(temp->inflected[i],alph) && is_upper(temp->inflected[i],alph)) {
                    tmp=1;
                    break;
                }
                i++;
            }
            if (!tmp) {
                set_bit_mask(&c,MIN_TOKEN_BIT_MASK);
            }
        }
        if (!is_a_simple_word(temp->inflected,tokenization_policy,alph)) {
            /* If the tag is a compound word, we say that it verifies the <CDIC> pattern */
            set_bit_mask(&c,CDIC_TOKEN_BIT_MASK);
        }
        free_dela_entry(temp);
    }
    return c;
}
Exemple #6
0
/**
 * This function analyses the inputs of all the tags of the given .fst2 in
 * order to determine their kind. 'tokens' contains all the text tokens.
 * After the execution of the function, 'number_of_patterns' will contain
 * the number of patterns found in the grammar, and 'is_DIC'/'is_CDIC'/'is_SDIC'/'is_TDIC'
 * will contain 1 if the tag 'DIC'/'CDIC'/'SDIC'/'TDIC' has been found. See
 * the comment below about the special case for '<!DIC>'.
 */
void process_tags(int *number_of_patterns,
                  struct string_hash* semantic_codes,
                  int *is_DIC,int *is_CDIC,
                  int *is_SDIC,struct locate_parameters* parameters,
                  Abstract_allocator prv_alloc) {
(*number_of_patterns)=0;
(*is_DIC)=0;
(*is_CDIC)=0;
(*is_SDIC)=0;
Fst2* fst2=parameters->fst2;
struct string_hash* tokens=parameters->tokens;
Fst2Tag* tag=fst2->tags;
/* We get the number of the SPACE token */
unichar t[2];
t[0]=' ';
t[1]='\0';
parameters->SPACE=get_value_index(t,tokens,DONT_INSERT);
/* Then, we test all the tags */
for (int i=0;i<fst2->number_of_tags;i++) {
   if (tag[i]->type!=UNDEFINED_TAG) {
      /* We don't need to process again things like variables and contexts
       * that have already been processed at the time of loading the fst2 */
      continue;
   }
   int length=u_strlen(tag[i]->input);
   if (!u_strcmp(tag[i]->input,"#")) {
      /* If we have a #, we must check if it is the meta one that
       * forbids space or the "#" token */
      if (is_bit_mask_set(tag[i]->control,RESPECT_CASE_TAG_BIT_MASK)) {
         /* If the case respect bit is set to 1, then we have the "#" token */
         tag[i]->type=PATTERN_TAG;
         tag[i]->pattern=build_token_pattern(tag[i]->input,prv_alloc);
      }
      else {
         /* If we have the meta # */
         tag[i]->type=META_TAG;
         tag[i]->meta=META_SHARP;
      }
   }
   else if (!u_strcmp(tag[i]->input,"<E>")) {
      /* If we have a transition tagged by the empty word epsilon */
      tag[i]->type=META_TAG;
      tag[i]->meta=META_EPSILON;
   }
   else {
      int token_number=get_value_index(tag[i]->input,tokens,DONT_INSERT);
      if (token_number!=-1) {
         /* If the input is an existing token */
         if (token_number==parameters->SPACE) {
            /* If it is a space */
            tag[i]->type=META_TAG;
            tag[i]->meta=META_SPACE;
         } else {
            /* If it is a normal token */
            tag[i]->type=PATTERN_TAG;
            tag[i]->pattern=build_token_pattern(tag[i]->input,prv_alloc);
         }
      }
      else {
         /* This input is not an existing token. Two cases can happen:
          * 1) metas like <!MOT> or patterns like <V:K>
          * 2) a word that is not in the text tokens */
         if (tag[i]->input[0]!='<' || tag[i]->input[length-1]!='>') {
            /* If we are in case 2, it may not be an error. For instance,
             * if the tag contains "foo" and if it is a tag that allows
             * case variations, we could match "FOO" if this token is in the
             * text. */
            tag[i]->type=PATTERN_TAG;
            tag[i]->pattern=build_token_pattern(tag[i]->input,prv_alloc);
         } else {
            /* If we have something of the form <...>, we must test first if it is
             * or not a negative tag like <!XXX> */
            int negative_tag=(tag[i]->input[1]=='!')?1:0;
            if (negative_tag) {
               set_bit_mask(&(tag[i]->control),NEGATION_TAG_BIT_MASK);
            }
            /* Then, we must test if we have or not a meta. To do that, we
             * extract the content without < > and ! if any.*/
            unichar* content=u_strdup(&(tag[i]->input[1+negative_tag]),length-2-negative_tag,prv_alloc);
            /* And we test all the possible metas */
            if (!u_strcmp(content,"MOT")) {
               tag[i]->type=META_TAG;
               tag[i]->meta=META_MOT;
            }
            else if (!u_strcmp(content,"DIC")) {
               tag[i]->type=META_TAG;
               tag[i]->meta=META_DIC;
               if (!negative_tag) {
                  /* We mark that the DIC tag has been found, but only
                   * if it is not the negative one (<!DIC>). We do this
                   * because things matched by <DIC> will be taken from
                   * the 'dlf' and 'dlc' files, whereas things matched by <!DIC>
                   * will be taken from the 'err' file. Such a trick is necessary
                   * if we don't want 'priori' to be taken as an unknown word since
                   * it is  part of the compound word 'a priori' */
                  (*is_DIC)=1;
               }
            }
            else if (!u_strcmp(content,"CDIC")) {
               tag[i]->type=META_TAG;
               tag[i]->meta=META_CDIC;
               (*is_CDIC)=1;
            }
            else if (!u_strcmp(content,"SDIC")) {
               tag[i]->type=META_TAG;
               tag[i]->meta=META_SDIC;
               (*is_SDIC)=1;
            }
            else if (!u_strcmp(content,"TDIC")) {
               tag[i]->type=META_TAG;
               tag[i]->meta=META_TDIC;
            }
            else if (!u_strcmp(content,"MAJ")) {
               tag[i]->type=META_TAG;
               tag[i]->meta=META_MAJ;
            }
            else if (!u_strcmp(content,"MIN")) {
               tag[i]->type=META_TAG;
               tag[i]->meta=META_MIN;
            }
            else if (!u_strcmp(content,"PRE")) {
               tag[i]->type=META_TAG;
               tag[i]->meta=META_PRE;
            }
            else if (!u_strcmp(content,"NB")) {
               tag[i]->type=META_TAG;
               tag[i]->meta=META_NB;
               if (negative_tag) {
                  error("Negative mark will be ignored in <!NB>\n");
               }
            }
            else if (!u_strcmp(content,"TOKEN")) {
               tag[i]->type=META_TAG;
               tag[i]->meta=META_TOKEN;
            }
            else {
               /* If we arrive here, we have not a meta but a pattern like
                * <be>, <be.V>, <V:K>, ... */
               tag[i]->type=PATTERN_TAG;
               tag[i]->pattern=build_pattern(content,semantic_codes,parameters->tilde_negation_operator,prv_alloc);
               if (tag[i]->pattern->type==CODE_PATTERN ||
                   tag[i]->pattern->type==LEMMA_AND_CODE_PATTERN ||
                   tag[i]->pattern->type==FULL_PATTERN || 
                   tag[i]->pattern->type==INFLECTED_AND_LEMMA_PATTERN) {
                  /* If the pattern we obtain contains grammatical/semantic
                   * codes, then we put it in the pattern tree and we note its number. */
                  tag[i]->pattern_number=add_pattern(number_of_patterns,tag[i]->pattern,parameters->pattern_tree_root,prv_alloc);
                  if (tag[i]->pattern->type==CODE_PATTERN) {
                     /* If we have a code pattern, then the tag will just need to contain
                      * the pattern number, BUT, WE DO NOT FREE THE PATTERN,
                      * since this pattern still could be used in morphological mode */
                     tag[i]->type=PATTERN_NUMBER_TAG;
                  }
               }
            }
            /* We don't forget to free the content */
            free_cb(content,prv_alloc);
         }
      }
   }
}
}
Exemple #7
0
static PetscErrorCode set_pairwise(gs_id *gs)
{
   PetscInt i, j;
  PetscInt p_mask_size;
  PetscInt *p_mask, *sh_proc_mask, *tmp_proc_mask;
  PetscInt *ngh_buf, *buf2;
  PetscInt offset;
  PetscInt *msg_list, *msg_size, **msg_nodes, nprs;
  PetscInt *pairwise_elm_list, len_pair_list=0;
  PetscInt *iptr, t1, i_start, nel, *elms;
  PetscInt ct;
  PetscErrorCode ierr;

  PetscFunctionBegin;
  /* to make life easier */
  nel  = gs->nel;
  elms = gs->elms;
  ngh_buf = gs->ngh_buf;
  sh_proc_mask  = gs->pw_nghs;

  /* need a few temp masks */
  p_mask_size   = len_bit_mask(num_nodes);
  p_mask        = (PetscInt*) malloc(p_mask_size);
  tmp_proc_mask = (PetscInt*) malloc(p_mask_size);

  /* set mask to my my_id's bit mask */
  ierr = set_bit_mask(p_mask,p_mask_size,my_id);CHKERRQ(ierr);

  p_mask_size /= sizeof(PetscInt);
          
  len_pair_list=gs->len_pw_list;
  gs->pw_elm_list=pairwise_elm_list=(PetscInt*)malloc((len_pair_list+1)*sizeof(PetscInt));

  /* how many processors (nghs) do we have to exchange with? */
  nprs=gs->num_pairs=ct_bits((char *)sh_proc_mask,p_mask_size*sizeof(PetscInt));


  /* allocate space for gs_gop() info */
  gs->pair_list = msg_list = (PetscInt *)  malloc(sizeof(PetscInt)*nprs);
  gs->msg_sizes = msg_size  = (PetscInt *)  malloc(sizeof(PetscInt)*nprs);
  gs->node_list = msg_nodes = (PetscInt **) malloc(sizeof(PetscInt*)*(nprs+1));

  /* init msg_size list */
  ierr = ivec_zero(msg_size,nprs);CHKERRQ(ierr);

  /* expand from bit mask list to int list */
  ierr = bm_to_proc((char *)sh_proc_mask,p_mask_size*sizeof(PetscInt),msg_list);CHKERRQ(ierr);
  
  /* keep list of elements being handled pairwise */
  for (i=j=0;i<nel;i++)
    {
      if (elms[i] & TOP_BIT)
        {elms[i] ^= TOP_BIT; pairwise_elm_list[j++] = i;}
    }
  pairwise_elm_list[j] = -1;

  gs->msg_ids_out = (MPI_Request *)  malloc(sizeof(MPI_Request)*(nprs+1));
  gs->msg_ids_out[nprs] = MPI_REQUEST_NULL;
  gs->msg_ids_in = (MPI_Request *)  malloc(sizeof(MPI_Request)*(nprs+1));
  gs->msg_ids_in[nprs] = MPI_REQUEST_NULL;
  gs->pw_vals = (PetscScalar *) malloc(sizeof(PetscScalar)*len_pair_list*vec_sz);

  /* find who goes to each processor */
  for (i_start=i=0;i<nprs;i++)
    {
      /* processor i's mask */
      ierr = set_bit_mask(p_mask,p_mask_size*sizeof(PetscInt),msg_list[i]);CHKERRQ(ierr);

      /* det # going to processor i */
      for (ct=j=0;j<len_pair_list;j++)
        {
          buf2 = ngh_buf+(pairwise_elm_list[j]*p_mask_size);
          ierr = ivec_and3(tmp_proc_mask,p_mask,buf2,p_mask_size);CHKERRQ(ierr);
          if (ct_bits((char *)tmp_proc_mask,p_mask_size*sizeof(PetscInt)))
            {ct++;}
        }
      msg_size[i] = ct;
      i_start = PetscMax(i_start,ct);

      /*space to hold nodes in message to first neighbor */
      msg_nodes[i] = iptr = (PetscInt*) malloc(sizeof(PetscInt)*(ct+1));

      for (j=0;j<len_pair_list;j++)
        {
          buf2 = ngh_buf+(pairwise_elm_list[j]*p_mask_size);
          ierr = ivec_and3(tmp_proc_mask,p_mask,buf2,p_mask_size);CHKERRQ(ierr);
          if (ct_bits((char *)tmp_proc_mask,p_mask_size*sizeof(PetscInt)))
            {*iptr++ = j;}
        }
      *iptr = -1;
    }
  msg_nodes[nprs] = NULL;

  j=gs->loc_node_pairs=i_start;
  t1 = GL_MAX;
  ierr = giop(&i_start,&offset,1,&t1);CHKERRQ(ierr);
  gs->max_node_pairs = i_start;

  i_start=j;
  t1 = GL_MIN;
  ierr = giop(&i_start,&offset,1,&t1);CHKERRQ(ierr);
  gs->min_node_pairs = i_start;

  i_start=j;
  t1 = GL_ADD;
  ierr = giop(&i_start,&offset,1,&t1);CHKERRQ(ierr);
  gs->avg_node_pairs = i_start/num_nodes + 1;

  i_start=nprs;
  t1 = GL_MAX;
  giop(&i_start,&offset,1,&t1);
  gs->max_pairs = i_start;


  /* remap pairwise in tail of gsi_via_bit_mask() */
  gs->msg_total = ivec_sum(gs->msg_sizes,nprs);
  gs->out = (PetscScalar *) malloc(sizeof(PetscScalar)*gs->msg_total*vec_sz);
  gs->in  = (PetscScalar *) malloc(sizeof(PetscScalar)*gs->msg_total*vec_sz);

  /* reset malloc pool */
  free((void*)p_mask);
  free((void*)tmp_proc_mask);
  PetscFunctionReturn(0);
}    
Exemple #8
0
static PetscErrorCode get_ngh_buf(gs_id *gs)
{
   PetscInt i, j, npw=0, ntree_map=0;
  PetscInt p_mask_size, ngh_buf_size, buf_size;
  PetscInt *p_mask, *sh_proc_mask, *pw_sh_proc_mask;
  PetscInt *ngh_buf, *buf1, *buf2;
  PetscInt offset, per_load, num_loads, or_ct, start, end;
  PetscInt *ptr1, *ptr2, i_start, negl, nel, *elms;
  PetscInt oper=GL_B_OR;
  PetscInt *ptr3, *t_mask, level, ct1, ct2;
  PetscErrorCode ierr;

  PetscFunctionBegin;
  /* to make life easier */
  nel   = gs->nel;
  elms  = gs->elms;
  level = gs->level;
  
  /* det #bytes needed for processor bit masks and init w/mask cor. to my_id */
  p_mask = (PetscInt*) malloc(p_mask_size=len_bit_mask(num_nodes));
  ierr = set_bit_mask(p_mask,p_mask_size,my_id);CHKERRQ(ierr);

  /* allocate space for masks and info bufs */
  gs->nghs = sh_proc_mask = (PetscInt*) malloc(p_mask_size);
  gs->pw_nghs = pw_sh_proc_mask = (PetscInt*) malloc(p_mask_size);
  gs->ngh_buf_sz = ngh_buf_size = p_mask_size*nel;
  t_mask = (PetscInt*) malloc(p_mask_size);
  gs->ngh_buf = ngh_buf = (PetscInt*) malloc(ngh_buf_size);

  /* comm buffer size ... memory usage bounded by ~2*msg_buf */
  /* had thought I could exploit rendezvous threshold */

  /* default is one pass */
  per_load = negl  = gs->negl;
  gs->num_loads = num_loads = 1;
  i=p_mask_size*negl;

  /* possible overflow on buffer size */
  /* overflow hack                    */
  if (i<0) {i=INT_MAX;}

  buf_size = PetscMin(msg_buf,i);

  /* can we do it? */
  if (p_mask_size>buf_size) SETERRQ2(PETSC_ERR_PLIB,"get_ngh_buf() :: buf<pms :: %d>%d\n",p_mask_size,buf_size);

  /* get giop buf space ... make *only* one malloc */
  buf1 = (PetscInt*) malloc(buf_size<<1);

  /* more than one gior exchange needed? */
  if (buf_size!=i)
    {
      per_load = buf_size/p_mask_size;
      buf_size = per_load*p_mask_size;
      gs->num_loads = num_loads = negl/per_load + (negl%per_load>0);
    }


  /* convert buf sizes from #bytes to #ints - 32 bit only! */
  p_mask_size/=sizeof(PetscInt); ngh_buf_size/=sizeof(PetscInt); buf_size/=sizeof(PetscInt);
  
  /* find giop work space */
  buf2 = buf1+buf_size;

  /* hold #ints needed for processor masks */
  gs->mask_sz=p_mask_size;

  /* init buffers */ 
  ierr = ivec_zero(sh_proc_mask,p_mask_size);CHKERRQ(ierr);
  ierr = ivec_zero(pw_sh_proc_mask,p_mask_size);CHKERRQ(ierr);
  ierr = ivec_zero(ngh_buf,ngh_buf_size);CHKERRQ(ierr);

  /* HACK reset tree info */
  tree_buf=NULL;
  tree_buf_sz=ntree=0;

  /* ok do it */
  for (ptr1=ngh_buf,ptr2=elms,end=gs->gl_min,or_ct=i=0; or_ct<num_loads; or_ct++)
    {
      /* identity for bitwise or is 000...000 */
      ivec_zero(buf1,buf_size);

      /* load msg buffer */
      for (start=end,end+=per_load,i_start=i; (offset=*ptr2)<end; i++, ptr2++)
        {
          offset = (offset-start)*p_mask_size;
          ivec_copy(buf1+offset,p_mask,p_mask_size);
        }

      /* GLOBAL: pass buffer */
      ierr = giop(buf1,buf2,buf_size,&oper);CHKERRQ(ierr);


      /* unload buffer into ngh_buf */
      ptr2=(elms+i_start);
      for(ptr3=buf1,j=start; j<end; ptr3+=p_mask_size,j++)
        {
          /* I own it ... may have to pairwise it */
          if (j==*ptr2)
            {
              /* do i share it w/anyone? */
              ct1 = ct_bits((char *)ptr3,p_mask_size*sizeof(PetscInt));
              /* guess not */
              if (ct1<2)
                {ptr2++; ptr1+=p_mask_size; continue;}

              /* i do ... so keep info and turn off my bit */
              ivec_copy(ptr1,ptr3,p_mask_size);
              ierr = ivec_xor(ptr1,p_mask,p_mask_size);CHKERRQ(ierr);
              ierr = ivec_or(sh_proc_mask,ptr1,p_mask_size);CHKERRQ(ierr);
              
              /* is it to be done pairwise? */
              if (--ct1<=level)
                {
                  npw++;
                  
                  /* turn on high bit to indicate pw need to process */
                  *ptr2++ |= TOP_BIT; 
                  ierr = ivec_or(pw_sh_proc_mask,ptr1,p_mask_size);CHKERRQ(ierr);
                  ptr1+=p_mask_size; 
                  continue;
                }

              /* get set for next and note that I have a tree contribution */
              /* could save exact elm index for tree here -> save a search */
              ptr2++; ptr1+=p_mask_size; ntree_map++;
            }
          /* i don't but still might be involved in tree */
          else
            {

              /* shared by how many? */
              ct1 = ct_bits((char *)ptr3,p_mask_size*sizeof(PetscInt));

              /* none! */
              if (ct1<2) continue;

              /* is it going to be done pairwise? but not by me of course!*/
              if (--ct1<=level) continue;
            }
          /* LATER we're going to have to process it NOW */
          /* nope ... tree it */
          ierr = place_in_tree(j);CHKERRQ(ierr);
        }
    }

  free((void*)t_mask);
  free((void*)buf1);

  gs->len_pw_list=npw;
  gs->num_nghs = ct_bits((char *)sh_proc_mask,p_mask_size*sizeof(PetscInt));

  /* expand from bit mask list to int list and save ngh list */
  gs->nghs = (PetscInt*) malloc(gs->num_nghs * sizeof(PetscInt));
  bm_to_proc((char *)sh_proc_mask,p_mask_size*sizeof(PetscInt),gs->nghs);

  gs->num_pw_nghs = ct_bits((char *)pw_sh_proc_mask,p_mask_size*sizeof(PetscInt));

  oper = GL_MAX;
  ct1 = gs->num_nghs;
  ierr = giop(&ct1,&ct2,1,&oper);CHKERRQ(ierr);
  gs->max_nghs = ct1;

  gs->tree_map_sz  = ntree_map;
  gs->max_left_over=ntree;

  free((void*)p_mask);
  free((void*)sh_proc_mask);
  PetscFunctionReturn(0);
}
Exemple #9
0
/**
 * Returns 1 if we can match <E> from the current state, with or without
 * conditions; 0 otherwise.
 */
int graph_matches_E(int initial_state,int current_state,const Fst2State* states,Fst2Tag* tags,
                      int current_graph,unichar** graph_names,
                      ConditionList conditions_for_states[],
                      ConditionList *graph_conditions) {
Transition* l;
Fst2State s;
int ret_value=0;
int ret;
*graph_conditions=NULL;
s=states[current_state];
if (is_final_state(s)) {
   /* If we are arrived in a final state, then the graph matches <E> */
   set_bit_mask(&(s->control),UNCONDITIONAL_E_MATCH);
   return 1;
}
if (is_bit_mask_set(s->control,TMP_LOOP_MARK)) {
   /* If we have a loop, we do nothing, because they will be
    * dealt with later. */
   return 0;
}
if (is_bit_mask_set(s->control,VISITED_MARK)) {
   /* If we are in state that has already been visited */
   if (is_bit_mask_set(s->control,UNCONDITIONAL_E_MATCH)) {
      /* If this state can match <E> without conditions, then we have finished */
      return 1;
   }
   if (is_bit_mask_set(s->control,CONDITIONAL_E_MATCH)) {
      /* If this state can match <E> with conditions, then we have finished, but
       * we copy the necessary conditions in 'graph_conditions'. */
      *graph_conditions=clone_ConditionList(conditions_for_states[current_state-initial_state]);
      return 1;
   }
   /* If the state has been visited and if it does not match <E>, then we return OK */
   return 0;
}
set_bit_mask(&(s->control),VISITED_MARK);
set_bit_mask(&(s->control),TMP_LOOP_MARK);
l=s->transitions;
/* We look all the outgoing transitions */
while (l!=NULL) {
   if (l->tag_number<0) {
      /* If we have a subgraph, we test if it matches <E> */
      *graph_conditions=NULL;
      ret=graph_matches_E(initial_state,l->state_number,states,tags,current_graph,graph_names,conditions_for_states,graph_conditions);
      if (ret==1) {
         /* If the subgraph matches <E>, we say that the current state matches
          * <E>, modulo the conditions to be verified */
         set_bit_mask(&(s->control),CONDITIONAL_E_MATCH);
         /* We insert the new condition in first position... */
         insert_graph_in_conditions(-(l->tag_number),graph_conditions);
         /* ...and we merge the new conditions with the existing ones for this state */
         merge_condition_lists(&conditions_for_states[current_state-initial_state],*graph_conditions);
         *graph_conditions=NULL;
      }
      ret_value=ret_value|ret;
   }
   else if (tags[l->tag_number]->control&1) {
      /* If we have an <E> transition, we explore the rest of the graph from it */
      *graph_conditions=NULL;
      ret=graph_matches_E(initial_state,l->state_number,states,tags,current_graph,graph_names,conditions_for_states,graph_conditions);
      if (ret==1) {
         /* If we can match <E> from the <E>-transition's destination state, then
          * we can match it from the current state. */
         if (*graph_conditions==NULL) {
            /* If there is no condition */
            set_bit_mask(&(s->control),UNCONDITIONAL_E_MATCH);
         }
         else {
            /* Otherwise, we add the condition to the existing ones */
            set_bit_mask(&(s->control),CONDITIONAL_E_MATCH);
            merge_condition_lists(&conditions_for_states[current_state-initial_state],*graph_conditions);
            *graph_conditions=NULL;
         }
      }
      ret_value=ret_value|ret;
   }
   l=l->next;
}
unset_bit_mask(&(s->control),TMP_LOOP_MARK);
*graph_conditions=clone_ConditionList(conditions_for_states[current_state-initial_state]);
return ret_value;
}