Пример #1
0
EXTRADECLS
#endif

/*****************************************************************************
*                                                                            *
*  This is a program which illustrates the use of nauty.                     *
*  Commands are read from stdin, and may be separated by white space,        *
*  commas or not separated.  Output is written to stdout.                    *
*  For a short description, see the nauty User's Guide.                      *
*                                                                            *
*****************************************************************************/

main()
{
        int m,n,newm,newn;
        boolean gvalid,ovalid,cvalid,pvalid,minus,prompt,doquot;
        int i,worksize,numcells,refcode,umask,qinvar;
        int oldorg;
        char *s1,*s2,*invarprocname;
        int c,d;
        register long li;
        set *gp;
        double timebefore,timeafter;
        char filename[100];
        graph *savedg;
        nvector *savedlab;
        int sgn,sgactn,sgorg;
        int cgactn,gactn;

        curfile = 0;
        fileptr[curfile] = stdin;
        prompt = DOPROMPT(INFILE);
        outfile = stdout;
        n = m = 1;

#ifdef  INITSEED
        INITSEED;
#endif

        umask = 0;
        pvalid = FALSE;
        gvalid = FALSE;
        ovalid = FALSE;
        cvalid = FALSE;
        minus = FALSE;
        worksize = 2*MAXM*WORKSIZE;
        labelorg = oldorg = 0;
        cgactn = sgactn = gactn = 0;

#ifdef  DYNALLOC
        workspace = (setword*) ALLOCS(WORKSIZE,2*MAXM*sizeof(setword));
        ptn = (nvector*) ALLOCS(MAXN,sizeof(nvector));
        orbits = (nvector*) ALLOCS(MAXN,sizeof(nvector));
        perm = (permutation*) ALLOCS(MAXN,sizeof(permutation));

        if (workspace == NILSET || ptn == (nvector*)NULL ||
                orbits == (nvector*)NULL || perm == (permutation*)NULL)
        {
            fprintf(ERRFILE,"ALLOCS failed; reduce MAXN.\n\n");
            EXIT;
        }
#endif

#ifdef  INITIALIZE
        INITIALIZE;
#endif

        allocg(&g,&lab,&gactn,n);
        if (gactn == 0)
        {
            fprintf(ERRFILE,"ALLOCS failed for g: this shouldn't happen.\n\n");
            EXIT;
        }

        invarprocname = "none";
        if (prompt)
        {
            fprintf(PROMPTFILE,"Dreadnaut version %s.\n",DREADVERSION);
            fprintf(PROMPTFILE,"> ");
        }

     /* Calling dummy routines in nautinv.c, nauty.c and nautil.c causes
        those segments to get loaded in various Macintosh variants.  This
        causes an apparent, but illusory, improvement in the time required
        for the first call to nauty().   */

        nautinv_null();
        nautil_null();
        nauty_null();

        while (curfile >= 0)
            if ((c = getc(INFILE)) == EOF || c == '\004')
            {
                fclose(INFILE);
                --curfile;
                if (curfile >= 0)
                    prompt = DOPROMPT(INFILE);
            }
            else switch (c)
            {
            case '\n':  /* possibly issue prompt */
                if (prompt)
                    fprintf(PROMPTFILE,"> ");
                minus = FALSE;
                break;

            case ' ':   /* do nothing */
            case '\t':
#ifndef  NLMAP
            case '\r':
#endif
            case '\f':
                break;

            case '-':   /* remember this for next time */
                minus = TRUE;
                break;

            case '+':   /* forget - */
            case ',':
            case ';':
                minus = FALSE;
                break;

            case '<':   /* new input file */
                minus = FALSE;
                if (curfile == MAXIFILES - 1)
                    fprintf(ERRFILE,"exceeded maximum input nesting of %d\n\n",
                            MAXIFILES);
                if (!readstring(INFILE,filename))
                {
                    fprintf(ERRFILE,
                            "missing file name on '>' command : ignored\n\n");
                    break;
                }
                if ((fileptr[curfile+1] = fopen(filename,"r")) == NULL)
                {
                    for (s1 = filename; *s1 != '\0'; ++s1) {}
                    for (s2 = def_ext; (*s1 = *s2) != '\0'; ++s1, ++s2) {}
                    fileptr[curfile+1] = fopen(filename,"r");
                }
                if (fileptr[curfile+1] != NULL)
                {
                    ++curfile;
                    prompt = DOPROMPT(INFILE);
                    if (prompt)
                        fprintf(PROMPTFILE,"> ");
                }
                else
                    fprintf(ERRFILE,"can't open input file\n\n");
                break;

            case '>':   /* new output file */
                if ((d = getc(INFILE)) != '>')
                    ungetc((char)d,INFILE);
                if (minus)
                {
                    minus = FALSE;
                    if (outfile != stdout)
                    {
                        fclose(outfile);
                        outfile = stdout;
                    }
                }
                else
                {
                    if (!readstring(INFILE,filename))
                    {
                        fprintf(ERRFILE,
                            "improper file name, reverting to stdout\n\n");
                        outfile = stdout;
                        break;
                    }
                    OPENOUT(outfile,filename,d=='>');
                    if (outfile == NULL)
                    {
                        fprintf(ERRFILE,
                            "can't open output file, reverting to stdout\n\n");
                        outfile = stdout;
                    }
                }
                break;

            case '!':   /* ignore rest of line */
                do
                    c = getc(INFILE);
                while (c != '\n' && c != EOF);
                if (c == '\n')
                    ungetc('\n',INFILE);
                break;

            case 'n':   /* read n value */
                minus = FALSE;
                i = getint(INFILE);
                if (i <= 0 || i > MAXN)
                    fprintf(ERRFILE,
                         " n can't be less than 1 or more than %d\n\n",MAXN);
                else
                {
                    gvalid = FALSE;
                    ovalid = FALSE;
                    cvalid = FALSE;
                    pvalid = FALSE;
                    n = i;
                    m = (n + WORDSIZE - 1) / WORDSIZE;
                    allocg(&g,&lab,&gactn,n);
                    if (gactn == 0)
                    {
                        fprintf(ERRFILE,"can't allocate space for graph\n");
                        n = m = 1;
                        break;
                    }
                }
                break;

            case 'g':   /* read graph */
                minus = FALSE;
                readgraph(INFILE,g,options.digraph,prompt,FALSE,
                          options.linelength,m,n);
                gvalid = TRUE;
                cvalid = FALSE;
                ovalid = FALSE;
                break;

            case 'e':   /* edit graph */
                minus = FALSE;
                readgraph(INFILE,g,options.digraph,prompt,gvalid,
                          options.linelength,m,n);
                gvalid = TRUE;
                cvalid = FALSE;
                ovalid = FALSE;
                break;

            case 'r':   /* relabel graph and current partition */
                minus = FALSE;
                if (gvalid)
                {
                    allocg(&canong,(nvector**)NULL,&cgactn,n);
                    if (cgactn == 0)
                    {
                        fprintf(ERRFILE,
                                "can't allocate work space for 'r'\n\n");
                        break;
                    }
                    readperm(INFILE,perm,prompt,n);
                    relabel(g,(pvalid ? lab : (nvector*)NULL),perm,canong,m,n);
                    cvalid = FALSE;
                    ovalid = FALSE;
                }
                else
                    fprintf(ERRFILE,"g is not defined\n\n");
                break;

            case '_':   /* complement graph */
                minus = FALSE;
                if (gvalid)
                {
                    complement(g,m,n);
                    cvalid = FALSE;
                    ovalid = FALSE;
                }
                else
                    fprintf(ERRFILE,"g is not defined\n\n");
                break;

            case '@':   /* copy canong into savedg */
                minus = FALSE;
                if (cvalid)
                {
                    allocg(&savedg,&savedlab,&sgactn,n);
                    if (sgactn == 0)
                    {
                        fprintf(ERRFILE,"can`t allocate space for h'\n\n");
                        break;
                    }
                    sgn = n;
                    for (li = (long)n * (long)m; --li >= 0;)
                        savedg[li] = canong[li];
                    for (i = n; --i >= 0;)
                        savedlab[i] = lab[i];
                    sgorg = labelorg;
                }
                else
                    fprintf(ERRFILE,"h is not defined\n\n");
                break;

            case '#':   /* compare canong to savedg */
                if ((d = getc(INFILE)) != '#')
                    ungetc((char)d,INFILE);

                if (cvalid)
                {
                    if (sgactn > 0)
                    {
                        if (sgn != n)
                            fprintf(OUTFILE,
                                  "h and h' have different sizes.\n");
                        else
                        {
                            for (li = (long)n * (long)m; --li >= 0;)
                                if (savedg[li] != canong[li])
                                    break;
                            if (li >= 0)
                                fprintf(OUTFILE,
                                   "h and h' are different.\n");
                            else
                            {
                                fprintf(OUTFILE,
                                   "h and h' are identical.\n");
                                if (d == '#')
                                    putmapping(OUTFILE,savedlab,sgorg,
                                           lab,labelorg,options.linelength,n);
                            }
                        }
                    }
                    else
                        fprintf(ERRFILE,"h' is not defined\n\n");
                }
                else
                    fprintf(ERRFILE,"h is not defined\n\n");
                break;

            case 'j':   /* relabel graph randomly */
                minus = FALSE;
                if (gvalid)
                {
                    allocg(&canong,(nvector**)NULL,&cgactn,n);
                    if (cgactn == 0)
                    {
                        fprintf(ERRFILE,
                                "can't allocate work space for 'j'\n\n");
                        break;
                    }
                    ranperm(perm,n);
                    relabel(g,(pvalid ? lab : (nvector*)NULL),perm,canong,m,n);
                    cvalid = FALSE;
                    ovalid = FALSE;
                }
                else
                    fprintf(ERRFILE,"g is not defined\n\n");
                break;

            case 'v':   /* write vertex degrees */
                minus = FALSE;
                if (gvalid)
                    putdegs(OUTFILE,g,options.linelength,m,n);
                else
                    fprintf(ERRFILE,"g is not defined\n\n");
                break;

            case '%':   /* do Mathon doubling operation */
                minus = FALSE;
                if (gvalid)
                {
                    if (2L * ((long)n + 1L) > MAXN)
                    {
                        fprintf(ERRFILE,"n can't be more than %d\n\n",MAXN);
                        break;
                    }
                    newn = 2 * (n + 1);
                    newm = (newn + WORDSIZE - 1) / WORDSIZE;
                    allocg(&canong,(nvector**)NULL,&cgactn,n);
                    if (cgactn == 0)
                    {
                        fprintf(ERRFILE,
                                "can't allocate work space for '%'\n\n");
                        break;
                    }

                    for (li = (long)n * (long)m; --li >= 0;)
                        canong[li] = g[li];

                    allocg(&g,&lab,&gactn,newn);
                    if (gactn == 0)
                    {
                        fprintf(ERRFILE,"can't allocate space for graph \n\n");
                        break;
                    }
                    mathon(canong,m,n,g,newm,newn);
                    m = newm;
                    n = newn;
                    cvalid = FALSE;
                    ovalid = FALSE;
                    pvalid = FALSE;
                }
                else
                    fprintf(ERRFILE,"g is not defined\n\n");
                break;

            case 's':   /* generate random graph */
                minus = FALSE;
                i = getint(INFILE);
                if (i <= 0)
                    i = 2;
                rangraph(g,options.digraph,i,m,n);
                gvalid = TRUE;
                cvalid = FALSE;
                ovalid = FALSE;
                break;

            case 'q':   /* quit */
                EXIT;
                break;

            case '"':   /* copy comment to output */
                minus = FALSE;
                copycomment(INFILE,OUTFILE,'"');
                break;

            case 'I':   /* do refinement and invariants procedure */
                if (!pvalid)
                    unitptn(lab,ptn,&numcells,n);
                cellstarts(ptn,0,active,m,n);
#ifdef  CPUTIME
                timebefore = CPUTIME;
#endif
                doref(g,lab,ptn,0,&numcells,&qinvar,perm,active,&refcode,
                      refine,options.invarproc,
                      0,0,options.invararg,options.digraph,m,n);
#ifdef  CPUTIME
                timeafter = CPUTIME;
#endif
                fprintf(OUTFILE," %d cell%s; code = %x",
                        SS(numcells,"","s"),refcode);
                if (options.invarproc != NILFUNCTION)
                    fprintf(OUTFILE," (%s %s)",invarprocname,
                        (qinvar == 2 ? "worked" : "failed"));
#ifdef  CPUTIME
                fprintf(OUTFILE,"; cpu time = %.2f seconds\n",
                        timeafter-timebefore);
#else
                fprintf(OUTFILE,"\n");
#endif
                if (numcells > 1)
                    pvalid = TRUE;
                break;

            case 'i':   /* do refinement */
                if (!pvalid)
                    unitptn(lab,ptn,&numcells,n);
                cellstarts(ptn,0,active,m,n);
                if (m == 1)
                    refine1(g,lab,ptn,0,&numcells,perm,active,&refcode,m,n);
                else
                    refine(g,lab,ptn,0,&numcells,perm,active,&refcode,m,n);
                fprintf(OUTFILE," %d cell%s; code = %x\n",
                        SS(numcells,"","s"),refcode);
                if (numcells > 1)
                    pvalid = TRUE;
                break;

            case 'x':   /* execute nauty */
                minus = FALSE;
                ovalid = FALSE;
                cvalid = FALSE;
                if (!gvalid)
                {
                    fprintf(ERRFILE,"g is not defined\n\n");
                    break;
                }
                if (pvalid)
                {
                    fprintf(OUTFILE,"[fixing partition]\n");
                    options.defaultptn = FALSE;
                }
                else
                    options.defaultptn = TRUE;
                options.outfile = outfile;

                if (options.getcanon)
                {
                    allocg(&canong,(nvector**)NULL,&cgactn,n);
                    if (cgactn == 0)
                    {
                        fprintf(ERRFILE,"can't allocate space for h\n\n");
                        break;
                    }
                }

                firstpath = TRUE;
#ifdef  CPUTIME
                timebefore = CPUTIME;
#endif
                nauty(g,lab,ptn,NILSET,orbits,&options,&stats,workspace,
                      worksize,m,n,canong);
#ifdef  CPUTIME
                timeafter = CPUTIME;
#endif
                if (stats.errstatus != 0)
                    fprintf(ERRFILE,
                      "nauty returned error status %d [this can't happen]\n\n",
                       stats.errstatus);
                else
                {
                    if (options.getcanon)
                        cvalid = TRUE;
                    ovalid = TRUE;
                    fprintf(OUTFILE,"%d orbit%s",SS(stats.numorbits,"","s"));
                    if (stats.grpsize2 == 0)
                        fprintf(OUTFILE,"; grpsize=%.0f",stats.grpsize1+0.1);
                    else
                    {
                        while (stats.grpsize1 >= 10.0)
                        {
                            stats.grpsize1 /= 10.0;
                            ++stats.grpsize2;
                        }
                        fprintf(OUTFILE,"; grpsize=%12.10fe%d",
                                   stats.grpsize1,stats.grpsize2);
                    }
                    fprintf(OUTFILE,"; %d gen%s",
                            SS(stats.numgenerators,"","s"));
                    fprintf(OUTFILE,"; %ld node%s",SS(stats.numnodes,"","s"));
                    if (stats.numbadleaves)
                        fprintf(OUTFILE," (%ld bad lea%s)",
                                SS(stats.numbadleaves,"f","ves"));
                    fprintf(OUTFILE,"; maxlev=%d\n", stats.maxlevel);
                    fprintf(OUTFILE,"tctotal=%ld",stats.tctotal);
                    if (options.getcanon)
                        fprintf(OUTFILE,"; canupdates=%ld",stats.canupdates);
#ifdef  CPUTIME
                    fprintf(OUTFILE,"; cpu time = %.2f seconds\n",
                            timeafter-timebefore);
#else
                    fprintf(OUTFILE,"\n");
#endif
                    if (options.invarproc != NILFUNCTION &&
                                           options.maxinvarlevel != 0)
                    {
                        fprintf(OUTFILE,"invarproc \"%s\" succeeded %ld/%ld",
                            invarprocname,stats.invsuccesses,stats.invapplics);
                        if (stats.invarsuclevel > 0)
                            fprintf(OUTFILE," beginning at level %d.\n",
                                    stats.invarsuclevel);
                        else
                            fprintf(OUTFILE,".\n");
                    }
                }
                break;

            case 'f':   /* read initial partition */
                if (minus)
                {
                    pvalid = FALSE;
                    minus = FALSE;
                }
                else
                {
                    readptn(INFILE,lab,ptn,&numcells,prompt,n);
                    pvalid = TRUE;
                }
                break;

            case 't':   /* type graph */
                minus = FALSE;
                if (!gvalid)
                    fprintf(ERRFILE,"g is not defined\n\n");
                else
                    putgraph(OUTFILE,g,options.linelength,m,n);
                break;

            case 'T':   /* type graph preceded by n, $ and g commands */
                minus = FALSE;
                if (!gvalid)
                    fprintf(ERRFILE,"g is not defined\n\n");
                else
                {
                    fprintf(OUTFILE,"n=%d $=%d g\n",n,labelorg);
                    putgraph(OUTFILE,g,options.linelength,m,n);
                    fprintf(OUTFILE,"$$\n");
                }
                break;

            case 'u':   /* call user procs */
                if (minus)
                {
                    umask = 0;
                    minus = FALSE;
                }
                else
                {
                    umask = getint(INFILE);
                    if (umask < 0)
                        umask = ~0;
                }
                if (umask & U_NODE)
                    options.usernodeproc = NODEPROC;
                else
                    options.usernodeproc = NILFUNCTION;
                if (umask & U_AUTOM)
                    options.userautomproc = AUTOMPROC;
                else
                    options.userautomproc = NILFUNCTION;
                if (umask & U_LEVEL)
                    options.userlevelproc = LEVELPROC;
                else
                    options.userlevelproc = NILFUNCTION;
                if (umask & U_TCELL)
                    options.usertcellproc = TCELLPROC;
                else
                    options.usertcellproc = NILFUNCTION;
                if (umask & U_REF)
                    options.userrefproc = REFPROC;
                else
                    options.userrefproc = NILFUNCTION;
                break;

            case 'o':   /* type orbits */
                minus = FALSE;
                if (ovalid)
                    putorbits(OUTFILE,orbits,options.linelength,n);
                else
                    fprintf(ERRFILE,"orbits are not defined\n\n");
                break;

            case 'b':   /* type canonlab and canong */
                minus = FALSE;
                if (cvalid)
                    putcanon(OUTFILE,lab,canong,options.linelength,m,n);
                else
                    fprintf(ERRFILE,"h is not defined\n\n");
                break;

            case 'z':   /* type hashcode for canong */
                minus = FALSE;
                if (cvalid)
                    fprintf(OUTFILE,"[%8lx %8lx]\n",
                                    hash(canong,(long)m * (long)n,13),
                                    hash(canong,(long)m * (long)n,7));
                else
                    fprintf(ERRFILE,"h is not defined\n\n");
                break;

            case 'c':   /* set getcanon option */
                options.getcanon = !minus;
                minus = FALSE;
                break;

            case 'w':   /* read size of workspace */
                minus = FALSE;
                worksize = getint(INFILE);
                if (worksize > 2*MAXM*WORKSIZE)
                {
                    fprintf(ERRFILE,
                       "too big - setting worksize = %d\n\n", 2*MAXM*WORKSIZE);
                    worksize = 2*MAXM*WORKSIZE;
                }
                break;

            case 'l':   /* read linelength for output */
                options.linelength = getint(INFILE);
                minus = FALSE;
                break;

            case 'y':   /* set tc_level field of options */
                options.tc_level = getint(INFILE);
                minus = FALSE;
                break;

            case 'k':   /* set invarlev fields of options */
                options.mininvarlevel = getint(INFILE);
                options.maxinvarlevel = getint(INFILE);
                minus = FALSE;
                break;

            case 'K':   /* set invararg field of options */
                options.invararg = getint(INFILE);
                minus = FALSE;
                break;

            case '*':   /* set invarproc field of options */
                minus = FALSE;
                d = getint(INFILE);
                if (d >= -1 && d <= NUMINVARS-2)
                {
                    options.invarproc = invarproc[d+1].entrypoint;
                    invarprocname = invarproc[d+1].name;
                }
                else
                    fprintf(ERRFILE,"no such vertex-invariant\n\n");
                break;

            case 'a':   /* set writeautoms option */
                options.writeautoms = !minus;
                minus = FALSE;
                break;

            case 'm':   /* set writemarkers option */
                options.writemarkers = !minus;
                minus = FALSE;
                break;

            case 'p':   /* set cartesian option */
                options.cartesian = !minus;
                minus = FALSE;
                break;

            case 'd':   /* set digraph option */
                if (options.digraph && minus)
                    gvalid = FALSE;
                options.digraph = !minus;
                minus = FALSE;
                break;

            case '$':   /* set label origin */
                if ((d = getc(INFILE)) == '$')
                    labelorg = oldorg;
                else
                {
                    ungetc((char)d,INFILE);
                    oldorg = labelorg;
                    i = getint(INFILE);
                    if (i < 0)
                        fprintf(ERRFILE,"labelorg must be >= 0\n\n");
                    else
                        labelorg = i;
                }
                break;

            case '?':   /* type options, etc. */
                minus = FALSE;
                fprintf(OUTFILE,"m=%d n=%d labelorg=%d",m,n,labelorg);
                if (!gvalid)
                    fprintf(OUTFILE," g=undef");
                else
                {
                    li = 0;
                    for (i = 0, gp = g; i < n; ++i, gp += m)
                        li += setsize(gp,m);
                    if (options.digraph)
                        fprintf(OUTFILE," arcs=%ld",li);
                    else
                        fprintf(OUTFILE," edges=%ld",li/2);
                }
                fprintf(OUTFILE," options=(%cc%ca%cm%cp%cd",
                            PM(options.getcanon),PM(options.writeautoms),
                            PM(options.writemarkers),PM(options.cartesian),
                            PM(options.digraph));
                if (umask & 31)
                    fprintf(OUTFILE," u=%d",umask&31);
                if (options.tc_level > 0)
                    fprintf(OUTFILE," y=%d",options.tc_level);
                if (options.mininvarlevel != 0 || options.maxinvarlevel != 0)
                    fprintf(OUTFILE," k=(%d,%d)",
                                  options.mininvarlevel,options.maxinvarlevel);
                if (options.invararg > 0)
                    fprintf(OUTFILE," K=%d",options.invararg);
                fprintf(OUTFILE,")\n");
                fprintf(OUTFILE,"linelen=%d worksize=%d input_depth=%d",
                                options.linelength,worksize,curfile);
                if (options.invarproc != NILFUNCTION)
                    fprintf(OUTFILE," invarproc=%s",invarprocname);
                if (pvalid)
                    fprintf(OUTFILE,"; %d cell%s",SS(numcells,"","s"));
                else
                    fprintf(OUTFILE,"; 1 cell");
                fprintf(OUTFILE,"\n");
                if (OUTFILE != PROMPTFILE)
                    fprintf(PROMPTFILE,"m=%d n=%d depth=%d labelorg=%d\n",
                            m,n,curfile,labelorg);
                break;

            case '&':   /* list the partition and possibly the quotient */
                if ((d = getc(INFILE)) == '&')
                    doquot = TRUE;
                else
                {
                    ungetc((char)d,INFILE);
                    doquot = FALSE;
                }
                minus = FALSE;
                if (pvalid)
                    putptn(OUTFILE,lab,ptn,0,options.linelength,n);
                else
                    fprintf(OUTFILE,"unit partition\n");
                if (doquot)
                {
                    if (!pvalid)
                        unitptn(lab,ptn,&numcells,n);
                    putquotient(OUTFILE,g,lab,ptn,0,options.linelength,m,n);
                }
                break;

            case 'h':   /* type help information */
                minus = FALSE;
                help(PROMPTFILE);
                break;

            default:    /* illegal command */
                fprintf(ERRFILE,"'%c' is illegal - type 'h' for help\n\n",c);
                flushline(INFILE);
                if (prompt)
                    fprintf(PROMPTFILE,"> ");
                break;

            }  /* end of switch */
}
Пример #2
0
void CallCandidate::relabelTypeVars(BindingEnv & env) {
  if (method_ == NULL) {
    DASSERT(spCandidate_ == NULL);
    return;
  }

  // The precondition for all type assignments is that this candidate not be culled.
  if (callExpr_ != NULL && callExpr_->candidates().size() > 1) {
    primaryProvision_ = new CandidateNotCulledProvision(this);
  }

  conditionCount_ = 0;
  if (method_->isTemplate() || method_->isTemplateMember() || method_->isPartialInstantiation()) {
    // Normalize the return type and parameter types, replacing all type variables
    // with type assignments which will eventually contain the inferred type for that
    // variable.
    QualifiedTypeVarMap assignments;
    for (Defn * def = method_; def != NULL && !def->isSingular(); def = def->parentDefn()) {
      Template * ts = def->templateSignature();
      if (ts != NULL) {
        isTemplate_ = true;
        if (typeParams_ == NULL) {
          typeParams_ = ts->typeParams();
        }
        size_t numParams = ts->typeParams()->size();
        // For each template parameter, create a TypeAssignment instance.
        for (size_t i = 0; i < numParams; ++i) {
          const TypeVariable * var = ts->patternVar(i);
          if (assignments.count(var) == 0) {
            TypeAssignment * ta = env.assign(var, this);
            ta->setPrimaryProvision(primaryProvision_);
            assignments[var] = ta;
            conditionCount_ += var->upperBounds().size() + var->lowerBounds().size();
          }
        }
      }
    }

    // Establish the upper and lower bounds of the assignments.
    env.setAssignmentBounds(assignments);

    // If there are any explicit type arguments, then we want to relabel the template
    // parameters themselves so that we can unify the type arguments with them.
    RelabelTransform relabel(assignments);

    Template * ts = method_->templateSignature();
    if (typeParams_ == NULL) {
      // typeParams_ should have been set above *unless* method_ is a template instance with
      // no unbound params.
      typeParams_ = ts->typeParams();
    }
    if (typeParams_ != NULL) {
      typeParams_ = cast<TupleType>(relabel(typeParams_).unqualified());
    }

    if (spCandidate_ != NULL) {
      if (spCandidate_->def() != method_) {
        spCandidate_->relabelTypeVars(relabel);
      } else {
        DASSERT(typeParams_ != NULL);
        spCandidate_->setParams(typeParams_);
      }
    }

    // Substitute all occurrences of pattern vars in the result type
    // the corresponding pattern value.
    resultType_ = relabel(resultType_);
    AnalyzerBase::analyzeType(resultType_, Task_PrepTypeComparison);

    // Same with function parameter types.
    for (QualifiedTypeList::iterator pt = paramTypes_.begin(); pt != paramTypes_.end(); ++pt) {
      QualifiedType paramType = relabel.transform(*pt);
      if (AnalyzerBase::analyzeType(paramType, Task_PrepTypeComparison)) {
        *pt = paramType;
      }
    }
  }
}
Пример #3
0
__global__
static void update_equiv(cuda::Param<T> equiv_map, const cudaTextureObject_t tex)
{
    // Basic coordinates
    const int base_x = (blockIdx.x * blockDim.x * n_per_thread) + threadIdx.x;
    const int base_y = (blockIdx.y * blockDim.y * n_per_thread) + threadIdx.y;

    const int width  = equiv_map.dims[0];
    const int height = equiv_map.dims[1];

    bool tid_changed = false;

    // Per element write flags and label, initially 0
    char write[n_per_thread * n_per_thread];
    T    best_label[n_per_thread * n_per_thread];

    #pragma unroll
    for (int i = 0; i < n_per_thread * n_per_thread; ++i) {
        write[i]      = (char)0;
        best_label[i] = (T)0;
    }

    // Cached tile of the equivalency map
    __shared__ T s_tile[n_per_thread*block_dim][(n_per_thread*block_dim)];

    #pragma unroll
    for (int xb = 0; xb < n_per_thread; ++xb) {
        #pragma unroll
        for (int yb = 0; yb < n_per_thread; ++yb) {

            // Indexing variables
            const int x = base_x + (xb * blockDim.x);
            const int y = base_y + (yb * blockDim.y);
            const int tx = threadIdx.x + (xb * blockDim.x);
            const int ty = threadIdx.y + (yb * blockDim.y);
            const int tid_i = xb * n_per_thread + yb;
            const int n = y * width + x;

            // Get the label for this pixel if we're  in bounds
            const T orig_label = (x < width && y < height) ?
                fetch<T>(n, equiv_map, tex) : (T)0;
            s_tile[ty][tx] = orig_label;

            // Find the lowest label of the nearest valid pixel
            // So far, all we know is that this pixel is valid.
            best_label[tid_i] = orig_label;

            if (orig_label != (T)0) {
                const int south_y = min(y, height-2) + 1;
                const int north_y = max(y, 1) - 1;
                const int east_x = min(x, width-2) + 1;
                const int west_x = max(x, 1) - 1;

                // Check bottom
                best_label[tid_i] = relabel(best_label[tid_i],
                        fetch((south_y) * width + x, equiv_map, tex));

                // Check right neighbor
                best_label[tid_i] = relabel(best_label[tid_i],
                        fetch(y * width + east_x, equiv_map, tex));

                // Check left neighbor
                best_label[tid_i] = relabel(best_label[tid_i],
                        fetch(y * width + west_x, equiv_map, tex));

                // Check top neighbor
                best_label[tid_i] = relabel(best_label[tid_i],
                        fetch((north_y) * width + x, equiv_map, tex));

                if (full_conn) {
                    // Check NW corner
                    best_label[tid_i] = relabel(best_label[tid_i],
                            fetch((north_y) * width + west_x, equiv_map, tex));

                    // Check NE corner
                    best_label[tid_i] = relabel(best_label[tid_i],
                            fetch((north_y) * width + east_x, equiv_map, tex));

                    // Check SW corner
                    best_label[tid_i] = relabel(best_label[tid_i],
                        fetch((south_y) * width + west_x, equiv_map, tex));

                    // Check SE corner
                    best_label[tid_i] = relabel(best_label[tid_i],
                            fetch((south_y) * width + east_x, equiv_map, tex));
                } // if connectivity == 8
            } // if orig_label != 0

            // Process the equivalency list.
            T last_label = orig_label;
            T new_label  = best_label[tid_i];

            while (best_label[tid_i] != (T)0 && new_label < last_label) {
                last_label = new_label;
                new_label = fetch(new_label - (T)1, equiv_map, tex);
            }

            if (orig_label != new_label) {
                tid_changed = true;
                s_tile[ty][tx] = new_label;
                write[tid_i] = (char)1;
            }
            best_label[tid_i] = new_label;
        }
    }

    bool continue_iter = __syncthreads_or((int)tid_changed);

    // Iterate until no pixel in the tile changes
    while (continue_iter) {

        // Reset whether or not this thread's pixels have changed.
        tid_changed = false;

        #pragma unroll
        for (int xb = 0; xb < n_per_thread; ++xb) {
            #pragma unroll
            for (int yb = 0; yb < n_per_thread; ++yb) {

                // Indexing
                const int tx = threadIdx.x + (xb * blockDim.x);
                const int ty = threadIdx.y + (yb * blockDim.y);
                const int tid_i = xb * n_per_thread + yb;

                T last_label = best_label[tid_i];

                if (best_label[tid_i] != 0) {

                    const int north_y   = max(ty, 1) -1;
                    const int south_y   = min(ty, n_per_thread*block_dim - 2) +1;
                    const int east_x    = min(tx, n_per_thread*block_dim - 2) +1;
                    const int west_x    = max(tx, 1) -1;

                    // Check bottom
                    best_label[tid_i] = relabel(best_label[tid_i],
                                                s_tile[south_y][tx]);

                    // Check right neighbor
                    best_label[tid_i] = relabel(best_label[tid_i],
                                                s_tile[ty][east_x]);

                    // Check left neighbor
                    best_label[tid_i] = relabel(best_label[tid_i],
                                                s_tile[ty][west_x]);

                    // Check top neighbor
                    best_label[tid_i] = relabel(best_label[tid_i],
                                                s_tile[north_y][tx]);

                    if (full_conn) {
                        // Check NW corner
                        best_label[tid_i] = relabel(best_label[tid_i],
                                                    s_tile[north_y][west_x]);

                        // Check NE corner
                        best_label[tid_i] = relabel(best_label[tid_i],
                                                    s_tile[north_y][east_x]);

                        // Check SW corner
                        best_label[tid_i] = relabel(best_label[tid_i],
                                                    s_tile[south_y][west_x]);

                        // Check SE corner
                        best_label[tid_i] = relabel(best_label[tid_i],
                                                    s_tile[south_y][east_x]);
                    } // if connectivity == 8

                    // This thread's value changed during this iteration if the
                    // best label is not the same as the last label.
                    const bool changed = best_label[tid_i] != last_label;
                    write[tid_i] = write[tid_i] || changed;
                    tid_changed  =  tid_changed || changed;
                }
            }
        }
        // Done looking at neighbors for this iteration
        continue_iter = __syncthreads_or((int)tid_changed);

        // If we have to continue iterating, update the tile of the
        // equiv map in shared memory
        if (continue_iter) {
            #pragma unroll
            for (int xb = 0; xb < n_per_thread; ++xb) {
                #pragma unroll
                for (int yb = 0; yb < n_per_thread; ++yb) {
                    const int tx = threadIdx.x + (xb * blockDim.x);
                    const int ty = threadIdx.y + (yb * blockDim.y);
                    const int tid_i = xb * n_per_thread + yb;
                    // Update tile in shared memory
                    s_tile[ty][tx] = best_label[tid_i];
                }
            }
            __syncthreads();
        }
    } // while (continue_iter)

    // Write out equiv_map
    #pragma unroll
    for (int xb = 0; xb < n_per_thread; ++xb) {
        #pragma unroll
        for (int yb = 0; yb < n_per_thread; ++yb) {
            const int x = base_x + (xb * blockDim.x);
            const int y = base_y + (yb * blockDim.y);
            const int n = y * width + x;
            const int tid_i = xb * n_per_thread + yb;
            if (x < width && y < height && write[tid_i]) {
                equiv_map.ptr[n]  = best_label[tid_i];
                continue_flag = 1;
            }
        }
    }
}
Пример #4
0
// . set m_reply/m_replySize to the reply
void Msg20::gotReply ( UdpSlot *slot ) {
	// we got the reply
	m_gotReply = true;
	// no longer in progress, we got a reply
	m_inProgress = false;
	// sanity check
	if ( m_r ) { g_process.shutdownAbort(true); }

	// free our serialized request buffer to save mem
	if ( m_request ) {
		mfree ( m_request , m_requestSize  , "Msg20rb2" );
		m_request = NULL;
	}

	// save error so Msg40 can look at it
	if ( g_errno ) { 
		m_errno = g_errno;
		log( LOG_WARN, "query: msg20: got reply for docid %" PRId64" : %s", m_requestDocId,mstrerror(g_errno));
		return; 
	}
	// . get the best reply we got
	// . we are responsible for freeing this reply
	bool freeit;
	// . freeit is true if mcast will free it
	// . we should always own it since we call deserialize and has ptrs
	//   into it
	char *rp = NULL;
	if ( slot ) {
		rp             = slot->m_readBuf;
		m_replySize    = slot->m_readBufSize;
		m_replyMaxSize = slot->m_readBufMaxSize;
		freeit = false;
	}
	else {
		rp =m_mcast.getBestReply(&m_replySize,&m_replyMaxSize,&freeit);
	}

	relabel( rp , m_replyMaxSize, "Msg20-mcastGBR" );

	// sanity check. make sure multicast is not going to free the
	// slot's m_readBuf... we need to own it.
	if ( freeit ) {
		log(LOG_LOGIC,"query: msg20: gotReply: Bad engineer.");
		g_process.shutdownAbort(true);
	}

	// see if too small for a getSummary request
	if ( m_replySize < (int32_t)sizeof(Msg20Reply) ) { 
		log("query: Summary reply is too small.");
		//g_process.shutdownAbort(true);
		m_errno = g_errno = EREPLYTOOSMALL; return; }

	// cast it
	m_r = (Msg20Reply *)rp;

	// we own it now
	m_ownReply = true;

	// deserialize it, sets g_errno on error??? not yet TODO!
	m_r->deserialize();
}
void Msg22::gotReply ( ) {
	// save g_errno
	m_errno = g_errno;
	// shortcut
	Msg22Request *r = m_r;
	// back
	m_outstanding = false;
	r->m_inUse    = 0;

	// bail on error, multicast will free the reply buffer if it should
	if ( g_errno ) {
		if ( r->m_url[0] )
			log("db: Had error getting title record for %s : %s.",
			    r->m_url,mstrerror(g_errno));
		else
			log("db: Had error getting title record for docId of "
			    "%lli: %s.",r->m_docId,mstrerror(g_errno));
		// free reply buf right away
		m_mcast.reset();
		m_callback ( m_state );
		return;
	}

	// breathe
	QUICKPOLL ( r->m_niceness );

	// get the reply
	long  replySize = -1 ;
	long  maxSize   ;
	bool  freeIt    ;
	char *reply     = m_mcast.getBestReply (&replySize, &maxSize, &freeIt);
	relabel( reply, maxSize, "Msg22-mcastGBR" );

	// breathe
	QUICKPOLL ( r->m_niceness );

	// a NULL reply happens when not found at one host and the other host
	// is dead... we need to fix Multicast to return a g_errno for this
	if ( ! reply ) {
		// set g_errno for callback
		m_errno = g_errno = EBADENGINEER;
		log("db: Had problem getting title record. Reply is empty.");
		m_callback ( m_state );
		return;
	}		

	// if replySize is only 8 bytes that means a not found
	if ( replySize == 8 ) {
		// we did not find it
		m_found = false;
		// get docid provided
		long long d = *(long long *)reply;
		// this is -1 or 0 if none available
		m_availDocId = d;
		// nuke the reply
		mfree ( reply , maxSize , "Msg22");
		// store error code
		m_errno = ENOTFOUND;
		// debug msg
		//if ( m_availDocId != m_probableDocId && m_url )
		//	log(LOG_DEBUG,"build: Avail docid %lli != probable "
		//	     "of %lli for %s.", 
		//	     m_availDocId, m_probableDocId , m_urlPtr );
		// this is having problems in Msg23::gotTitleRec()
		m_callback ( m_state );
		return;
	}

	// sanity check. must either be an empty reply indicating nothing
	// available or an 8 byte reply above!
	if ( m_r->m_getAvailDocIdOnly ) { char *xx=NULL;*xx=0; }

	// otherwise, it was found
	m_found = true;

	// if just checking tfndb, do not set this, reply will be empty!
	if ( ! r->m_justCheckTfndb ) { // && ! r->m_getAvailDocIdOnly ) {
		*m_titleRecPtrPtr  = reply;
		*m_titleRecSizePtr = replySize;
	}
	// if they don't want the title rec, nuke it!
	else {
		// nuke the reply
		mfree ( reply , maxSize , "Msg22");
	}

	// all done
	m_callback ( m_state );
}
Пример #6
0
int command_loop(solutionp root) {
  char command[MAX_BUF];
  char *token;
  int start,end,i;
  printf("Enter Command : ");
  fgets(command,MAX_BUF,stdin);
  switch(command[0]) {
  case 'l':
    printf("  BR    PT  TY LAB  NEW\n");
    token = strtok(&command[1]," \n");
    if(token != NULL) {
      /*If there are further arguements use them*/
      expandtoken(token,&start,&end);
      for(i=start;i<=end;i++){
    print(root, i);
      }
      token = strtok(NULL," ");
      while(token != NULL) {
    expandtoken(token,&start,&end);
    for(i=start;i<=end;i++){
      print(root, i);
    }
    token = strtok(NULL," ");
      }
    } else {
      /*Otherwise print them all*/
      print(root,-1);
    }
    break;
  case 'd':
    token = strtok(&command[1]," \n");
    if(token != NULL) {
      /*If there are further arguements use them*/
      expandtoken(token,&start,&end);
      for(i=start;i<=end;i++){
    delete_(root, i);
      }
      token = strtok(NULL," ");
      while(token != NULL) {
    expandtoken(token,&start,&end);
    for(i=start;i<=end;i++){
      delete_(root, i);
    }
    token = strtok(NULL," ");
      }
    } else {
      /*Otherwise delete them all*/
      delete_(root,-1);
    }
    break;
  case 'r':
    token = strtok(&command[1]," \n");
    if(token != NULL) {
      /*If there are further arguements use them*/
      expandtoken(token,&start,&end);
      for(i=start;i<=end;i++){
    relabel(root, i);
      }
      token = strtok(NULL," ");
      while(token != NULL) {
    expandtoken(token,&start,&end);
    for(i=start;i<=end;i++){
      relabel(root, i);
    }
    token = strtok(NULL," ");
      }
    } else {
      /*Otherwise relabel them all*/
      relabel(root,-1);
    }
    break;
  case 'w':
    write8(root);
    write7(root);
    printf("Writing files...\n");
    return 0;
    break;
  case 'q':
    return 0;
    break;
  case 'h':
    help();
    break;
  default:
    printf("Invalid Command.  Type 'h' for help.\n");
  }
  return 1;
}
bool Msg3a::gotAllSplitReplies ( ) {

    // if any of the split requests had an error, give up and set m_errno
    // but don't set if for non critical errors like query truncation
    if ( m_errno ) {
        g_errno = m_errno;
        return true;
    }

    // also reset the finalbuf and the oldNumTopDocIds
    if ( m_finalBuf ) {
        mfree ( m_finalBuf, m_finalBufSize, "Msg3aF" );
        m_finalBuf     = NULL;
        m_finalBufSize = 0;
    }

    // update our estimated total hits
    m_numTotalEstimatedHits = 0;

    for ( long i = 0; i < m_numHosts ; i++ ) {
        // get that host that gave us the reply
        //Host *h = g_hostdb.getHost(i);
        // . get the reply from multicast
        // . multicast should have destroyed all slots, but saved reply
        // . we are responsible for freeing the reply
        // . we need to call this even if g_errno or m_errno is
        //   set so we can free the replies in Msg3a::reset()
        // . if we don't call getBestReply() on it multicast should
        //   free it, because Multicast::m_ownReadBuf is still true
        Multicast *m = &m_mcast[i];
        bool freeit = false;
        long  replySize = 0;
        long  replyMaxSize;
        char *rbuf;
        Msg39Reply *mr;
        // . only get it if the reply not already full
        // . if reply already processed, skip
        // . perhaps it had no more docids to give us or all termlists
        //   were exhausted on its disk and this is a re-call
        // . we have to re-process it for count m_numTotalEstHits, etc.
        rbuf = m->getBestReply ( &replySize    ,
                                 &replyMaxSize ,
                                 &freeit       ,
                                 true          ); //stealIt?
        // cast it
        mr = (Msg39Reply *)rbuf;
        // in case of mem leak, re-label from "mcast" to this so we
        // can determine where it came from, "Msg3a-GBR"
        relabel( rbuf, replyMaxSize , "Msg3a-GBR" );
        // . we must be able to free it... we must own it
        // . this is true if we should free it, but we should not have
        //   to free it since it is owned by the slot?
        if ( freeit ) {
            log(LOG_LOGIC,"query: msg3a: Steal failed.");
            char *xx = NULL;
            *xx=0;
        }
        // bad reply?
        if ( ! mr ) {
            log(LOG_LOGIC,"query: msg3a: Bad NULL reply.");
            m_reply       [i] = NULL;
            m_replyMaxSize[i] = 0;
            // it might have been timd out, just ignore it!!
            continue;
            // if size is 0 it can be Msg39 giving us an error!
            g_errno = EBADREPLYSIZE;
            m_errno = EBADREPLYSIZE;
            // all reply buffers should be freed on reset()
            return true;
        }
        // how did this happen?
        if ( replySize < 29 && ! mr->m_errno ) {
            // if size is 0 it can be Msg39 giving us an error!
            g_errno = EBADREPLYSIZE;
            m_errno = EBADREPLYSIZE;
            log(LOG_LOGIC,"query: msg3a: Bad reply size of %li.",
                replySize);
            // all reply buffers should be freed on reset()
            return true;
        }

        // can this be non-null? we shouldn't be overwriting one
        // without freeing it...
        if ( m_reply[i] )
            // note the mem leak now
            log("query: mem leaking a 0x39 reply");

        // cast it and set it
        m_reply       [i] = mr;
        m_replyMaxSize[i] = replyMaxSize;
        // deserialize it (just sets the ptr_ and size_ member vars)
        //mr->deserialize ( );
        deserializeMsg ( sizeof(Msg39Reply) ,
                         &mr->size_docIds,
                         &mr->size_clusterRecs,
                         &mr->ptr_docIds,
                         mr->m_buf );

        // sanity check
        if ( mr->m_nqt != m_q->getNumTerms() ) {
            g_errno = EBADREPLY;
            m_errno = EBADREPLY;
            log("query: msg3a: Split reply qterms=%li != %li.",
                (long)mr->m_nqt,(long)m_q->getNumTerms() );
            return true;
        }
        // return if split had an error, but not for a non-critical
        // error like query truncation
        if ( mr->m_errno && mr->m_errno != EQUERYTRUNCATED ) {
            g_errno = mr->m_errno;
            m_errno = mr->m_errno;
            log("query: msg3a: Split had error: %s",
                mstrerror(g_errno));
            return true;
        }
        // skip down here if reply was already set
        //skip:
        // add of the total hits from each split, this is how many
        // total results the lastest split is estimated to be able to
        // return
        // . THIS should now be exact since we read all termlists
        //   of posdb...
        m_numTotalEstimatedHits += mr->m_estimatedHits;

        // debug log stuff
        if ( ! m_debug ) continue;
        // cast these for printing out
        long long *docIds    = (long long *)mr->ptr_docIds;
        score_t   *scores    = (score_t   *)mr->ptr_scores;
        // print out every docid in this split reply
        for ( long j = 0; j < mr->m_numDocIds ; j++ ) {
            // print out score_t
            logf( LOG_DEBUG,
                  "query: msg3a: [%lu] %03li) "
                  "split=%li docId=%012llu domHash=0x%02lx "
                  "score=%lu"                     ,
                  (unsigned long)this                      ,
                  j                                        ,
                  i                                        ,
                  docIds [j] ,
                  (long)g_titledb.getDomHash8FromDocId(docIds[j]),
                  (long)scores[j] );
        }
    }

    // this seems to always return true!
    mergeLists ( );

    if ( ! m_r->m_useSeoResultsCache ) return true;

    // now cache the reply
    SafeBuf cr;
    long dataSize = 4 + 4 + 4 + m_numDocIds * (8+4+4);
    long need = sizeof(key_t) + 4 + dataSize;
    bool status = cr.reserve ( need );
    // sanity
    if ( ( m_ckey.n0 & 0x01 ) == 0x00 ) {
        char *xx=NULL;
        *xx=0;
    }
    // ignore errors
    g_errno = 0;
    // return on error with g_errno cleared if cache add failed
    if ( ! status ) return true;
    // add to buf otherwise
    cr.safeMemcpy ( &m_ckey , sizeof(key_t) );
    cr.safeMemcpy ( &dataSize , 4 );
    long now = getTimeGlobal();
    cr.pushLong ( now );
    cr.pushLong ( m_numDocIds );
    cr.pushLong ( m_numTotalEstimatedHits );//Results );
    long max = m_numDocIds;
    // then the docids
    for ( long i = 0 ; i < max ; i++ )
        cr.pushLongLong(m_docIds[i] );
    for ( long i = 0 ; i < max ; i++ )
        cr.pushFloat(m_scores[i]);
    for ( long i = 0 ; i < max ; i++ )
        cr.pushLong(getSiteHash26(i));
    // sanity
    if ( cr.length() != need ) {
        char *xx=NULL;
        *xx=0;
    }
    // make these
    key_t startKey;
    key_t endKey;
    startKey = m_ckey;
    // clear delbit
    startKey.n0 &= 0xfffffffffffffffeLL;
    // end key is us
    endKey = m_ckey;
    // that is the single record
    m_seoCacheList.set ( cr.getBufStart() ,
                         cr.length(),
                         cr.getBufStart(), // alloc
                         cr.getCapacity(), // alloc size
                         (char *)&startKey,
                         (char *)&endKey,
                         -1, // fixeddatasize
                         true, // owndata?
                         false,// use half keys?
                         sizeof(key_t) );
    // do not allow cr to free it, msg1 will
    cr.detachBuf();
    // note it
    //log("seopipe: storing ckey=%s q=%s"
    //    ,KEYSTR(&m_ckey,12)
    //    ,m_r->ptr_query
    //    );
    //log("msg1: sending niceness=%li",(long)m_r->m_niceness);
    // this will often block, but who cares!? it just sends a request off
    if ( ! m_msg1.addList ( &m_seoCacheList ,
                            RDB_SERPDB,//RDB_CACHEDB,
                            m_r->ptr_coll,
                            this, // state
                            gotSerpdbReplyWrapper, // callback
                            false, // forcelocal?
                            m_r->m_niceness ) ) {
        //log("blocked");
        return false;
    }

    // we can safely delete m_msg17... just return true
    return true;
}
Пример #8
0
int dinic()
{
    int f=0;
    while (relabel()) f+=augment(S,oo);
    return f;
}
Пример #9
0
// inteface to various superpixel helpers
void mexFunction( int nl, mxArray *pl[], int nr, const mxArray *pr[] ) {
  int f; char action[1024]; f=mxGetString(pr[0],action,1024); nr--; pr++;
  uint *S = (uint*) mxGetData(pr[0]);
  uint h = (uint) mxGetM(pr[0]);
  uint w = (uint) mxGetN(pr[0]);

  if(f) { mexErrMsgTxt("Failed to get action.");

  } else if(!strcmp(action,"sticky")) {
    // S = sticky( S, I, E, prm )
    float *I = (float*) mxGetData(pr[1]);
    float *E = (float*) mxGetData(pr[2]);
    double *prm = (double*) mxGetData(pr[3]);
    pl[0] = mxCreateNumericMatrix(h,w,mxUINT32_CLASS,mxREAL);
    uint* T = (uint*) mxGetData(pl[0]); memcpy(T,S,h*w*sizeof(uint));
    sticky(T,h,w,I,E,prm); relabel(T,h,w);

  } else if(!strcmp(action,"boundaries")) {
    // S = boundaries( S, E, add, nThreads )
    float *E = (float*) mxGetData(pr[1]);
    bool add = mxGetScalar(pr[2])>0;
    uint nThreads = (uint) mxGetScalar(pr[3]);
    pl[0] = mxCreateNumericMatrix(h,w,mxUINT32_CLASS,mxREAL);
    uint* T = (uint*) mxGetData(pl[0]); memcpy(T,S,h*w*sizeof(uint));
    boundaries(T,h,w,E,add,nThreads);

  } else if(!strcmp(action,"merge")) {
    // S = merge( S, E, thr );
    float *E = (float*) mxGetData(pr[1]);
    float thr = (float) mxGetScalar(pr[2]);
    pl[0] = mxCreateNumericMatrix(h,w,mxUINT32_CLASS,mxREAL);
    uint* T = (uint*) mxGetData(pl[0]); memcpy(T,S,h*w*sizeof(uint));
    merge(T,h,w,E,thr);

  } else if(!strcmp(action,"visualize")) {
    // V = visualize( S, I, hasBnds )
    float *I = (float*) mxGetData(pr[1]);
    bool hasBnds = mxGetScalar(pr[2])>0;
    const int dims[3] = {h,w,3};
    pl[0] = mxCreateNumericArray(3,dims,mxSINGLE_CLASS,mxREAL);
    float* V = (float*) mxGetData(pl[0]);
    visualize(V,S,h,w,I,hasBnds);

  } else if(!strcmp(action,"affinities")) {
    // A = affinities( S, E, segs, nThreads )
    float *E  = (float*) mxGetData(pr[1]);
    uint8 *segs  = (uint8*) mxGetData(pr[2]);
    uint nThreads = (uint) mxGetScalar(pr[3]);
    if( mxGetNumberOfDimensions(pr[2])!=5 ) mexErrMsgTxt("invalid input");
    uint *dims = (uint*) mxGetDimensions(pr[2]);
    uint m=0; for( uint x=0; x<w*h; x++ ) m=S[x]>m ? S[x] : m;
    pl[0] = mxCreateNumericMatrix(m,m,mxSINGLE_CLASS,mxREAL);
    float *A = (float*) mxGetData(pl[0]);
    affinities(A,S,h,w,E,segs,dims,nThreads);

  } else if(!strcmp(action,"edges")) {
    // E = edges(S,A);
    float* A = (float*) mxGetData(pr[1]);
    pl[0] = mxCreateNumericMatrix(h,w,mxSINGLE_CLASS,mxREAL);
    float *E = (float*) mxGetData(pl[0]);
    edges(E,S,h,w,A);

  } else mexErrMsgTxt("Invalid action.");
}
Пример #10
0
// . set m_reply/m_replySize to the reply
void Msg20::gotReply ( UdpSlot *slot ) {
	// we got the reply
	m_gotReply = true;
	// no longer in progress, we got a reply
	m_inProgress = false;
	// sanity check
	if ( m_r ) { char *xx = NULL; *xx = 0; }

	// free our serialized request buffer to save mem
	if ( m_request && m_request   != m_requestBuf ) {
		mfree ( m_request , m_requestSize  , "Msg20rb2" );
		m_request = NULL;
	}

	// save error so Msg40 can look at it
	if ( g_errno ) { 
		m_errno = g_errno; 
		if ( g_errno != EMISSINGQUERYTERMS )
			log("query: msg20: got reply for docid %"INT64" : %s",
			    m_requestDocId,mstrerror(g_errno));
		return; 
	}
	// . get the best reply we got
	// . we are responsible for freeing this reply
	bool freeit;
	// . freeit is true if mcast will free it
	// . we should always own it since we call deserialize and has ptrs
	//   into it
	char *rp = NULL;
	if ( slot ) {
		rp             = slot->m_readBuf;
		m_replySize    = slot->m_readBufSize;
		m_replyMaxSize = slot->m_readBufMaxSize;
		freeit = false;
	}
	else
		rp =m_mcast.getBestReply(&m_replySize,&m_replyMaxSize,&freeit);


	//if( rp != m_replyBuf )
	relabel( rp , m_replyMaxSize, "Msg20-mcastGBR" );

	// sanity check. make sure multicast is not going to free the
	// slot's m_readBuf... we need to own it.
	if ( freeit ) {
		log(LOG_LOGIC,"query: msg20: gotReply: Bad engineer.");
		char *xx = NULL; *xx = 0;
		return;
	}
	// see if too small for a getSummary request
	if ( m_replySize < (int32_t)sizeof(Msg20Reply) ) { 
		log("query: Summary reply is too small.");
		//char *xx = NULL; *xx = 0;
		m_errno = g_errno = EREPLYTOOSMALL; return; }

	// cast it
	m_r = (Msg20Reply *)rp;

	m_r->m_parentOwner = (void *)this;
	m_r->m_constructorId = 2;

	// reset this since constructor never called
	m_r->m_tmp = 0;
	// we own it now
	m_ownReply = true;
	// deserialize it, sets g_errno on error??? not yet TODO!
	m_r->deserialize();

	// log("msg20: got msg20=0x%"PTRFMT" msg20reply=0x%"PTRFMT" slot=0x%"PTRFMT" s_tmp=%i"
	//     ,(PTRTYPE)this
	//     ,(PTRTYPE)m_r
	//     ,(PTRTYPE)slot
	//     ,s_tmp);
}
Пример #11
0
void cTplCoxRoyAlgo<cCRNode>::EndMaxFlowStd(int aX0,int aY0,int aX1,int aY1)
{
        mX0Loc = aX0;
        mY0Loc = aY0;
        mX1Loc = aX1;
        mY1Loc = aY1;

       SetFlagEdges(mX0Loc,mY0Loc,mX1Loc,mY1Loc,false);


	// Init();
	/** flood the first nodes **/
	for(int anY=mY0Loc ; anY<mY1Loc ; anY++)
        {
	    for(int anX=mX0Loc ; anX<mX1Loc ; anX++) 
            {
                 cCRNode *  aCol = ColumnOfP(anX,anY);
		 int  aZ0 = ZMin(anX,anY);
		 int  aZ1 = ZMax(anX,anY);
		 for (int aZ = aZ0; (aZ<aZ1) && (aCol[aZ].SourceConnected()) ; aZ++)
                 {

                     aCol[aZ].SetExcess(largef);
		     mCRH.LinkQInsert(cRoyPt(anX,anY,aZ),aCol[aZ].Height());
                 }
	    }
        }
	ResizeDetected=false;

        // End Init()



	int Level=mCRH.MaxKey();
        int Count =0;

	// printf("Starting at Key=%d\n",Level);

	/** generic preflow-push **/
	for(;;) 
        {
		/** This is the schedule for relabelling **/
		/** it can be changed for more/less relabel steps **/
		if( ((Count+1)%(2*sz/2)==0 && mSinkFlow!=0) || ResizeDetected ) 
		  {
			relabel();
			Level=mCRH.MaxKey();
			ResizeDetected=false;
		}

		/** update level to a non empty key **/
        mCRH.Set2NonEmptyKey(Level);

		/* if reached bottom, reset to top */
		if( Level<0 ) Level=mCRH.MaxKey(); /* highest level */

		/* if Level still <0 -> list MUST be empty! */
		if( Level<0 ) break; /* no more nodes! */

		/** get overflowing node with largest level **/
		cRoyPt aPU = mCRH.LinkQRemove(Level);

//		if( Count%100000==0 ) 
//		{
//        	mCRH.ShowLink();
			// printf("%6dk... SinkFlow=%8d  \n",Count/1000,mSinkFlow);
//		}

		Discharge(aPU);

		Count++;
	}

	// printf("SinkFlow=%d\n",mSinkFlow);
}
int distance_label(graph_matrix residue, int beg, int end)
{
	//d[i]指代节点i到汇点的距离标号
	//d_num[i]指代距离标号为i的节点数量,用于间隙优化,也称gap heuristic优化
	//d和d_num是实现距离标号技术的核心体现,注意d_num代表的意义
	//path[i]指代增广路径上节点i的父节点下标号,用于记录增广路径
	int d[MAX], d_num[MAX], path[MAX];
	memset(path, -1, MAX * sizeof(int));
	//将各节点的d值初始化为流网络中各节点的拓扑距离
	construct_d(residue, beg, end, d, d_num);
	int max_flow(0), u(beg);
	//算法结束条件是源点beg的距离标号d值小于节点数量g_cnt
	while(d[beg] < residue.g_cnt){
		//从残留网络residue中找出节点u的容许边
		//返回节点u的这条容许边的邻节点p
		int p = find_allow_edge(u, residue, d);
		if(p >= 0){
			//若存在这样的邻节点p,从0到g_cnt-1
			//在path中记录节点p的父节点为u
			path[p] = u;
			//从节点u走到当前节点p
			u = p;
			if(u == end){
				//当走到汇点end,可以使用这条增广路径上的残留网络volum
				int volum = INF;
				//在该增广路径上找出剩余容量volum
				for(u = end; u != beg; u = path[u])
					volum = min(volum, residue.g_m[path[u]][u]);
				//更新残留网络
				for(u = end; u != beg; u = path[u]){
					residue.g_m[path[u]][u] -= volum;
					residue.g_m[u][path[u]] += volum;
				}
				//经过此遍历u又倒着回到beg
				//下一轮循环时u仍从源点出发,搜索下一条增广路径
				max_flow += volum;
			}
		}
		else{
			//若不存在这样的容许边则find_allow_edge返回-1
			//对u节点尝试重标记操作,在重标记之前先进行间隙优化
			-- d_num[d[u]];
			if(d_num[d[u]] == 0)
				//距离标号算法存在退化现象
				//对节点u进行重标记之后,与u距离标号相等的节点数量为0
				//即再没有距离标号为d[u]这样的节点,判定算法直接结束
				//这是著名的gap heuristic优化,也成为间隙优化,它的思路是:
				//如果一次重标号操作后,出现断层,即节点d值没有d[v]=d[u]+1的情况
				//可以证明残留网络中再无增广路径,判定算法结束
				return(max_flow);

			//对u节点进行重标号,返回重标号后u节点的d值
			//本文中间隙优化与重标记操作的顺序与
			//引用的文档“最大流ISAP(距离标号最短增广路算法)模”中的顺序不同
			//因为在实际测试中我发现这里的顺序按照
			//另一篇文档“网络最大流算法算法拓展(最大流算法拓展,百度文库)”中的更好
			//调整顺序之后重标记中不会出现d_tmp==INF的意外情况
			int v = relabel(u, residue, d);
			//距离标号为v的节点数量加1
			++ d_num[v];
			//与节点u的距离标号相等的节点数量减1
			d[u] = v;
			if(u != beg)
				//将节点u退回其父节点重走
				//这是当前弧优化
				//为了使每次寻找增广路径的时间均摊为O(V),对每个节点保留当前弧
				//初始时当前弧是第一条容许边,每次查找容许边都从当前弧开始查找
				//找到一条容许边后则把该容许边设置为当前弧
				//当未找到容许边时退回上一节点
				u = path[u];
		}
	}
	return(max_flow);
}
Пример #13
0
		PrimaryBlock::PrimaryBlock()
		 : _procflags(0), _timestamp(0), _sequencenumber(0), _lifetime(3600), _fragmentoffset(0), _appdatalength(0)
		{
			relabel();
		}
Пример #14
0
bool discharge(const GNode& src, Galois::UserContext<GNode>& ctx) {
  //Node& node = app.graph.getData(src, Galois::MethodFlag::CHECK_CONFLICT);
  Node& node = app.graph.getData(src, Galois::MethodFlag::NONE);
  //int prevHeight = node.height;
  bool relabeled = false;

  if (node.excess == 0 || node.height >= (int) app.graph.size()) {
    return false;
  }

  while (true) {
    //Galois::MethodFlag flag = relabeled ? Galois::MethodFlag::NONE : Galois::MethodFlag::CHECK_CONFLICT;
    Galois::MethodFlag flag = Galois::MethodFlag::NONE;
    bool finished = false;
    int current = node.current;
    Graph::edge_iterator
      ii = app.graph.edge_begin(src, flag),
      ee = app.graph.edge_end(src, flag);
    std::advance(ii, node.current);
    for (; ii != ee; ++ii, ++current) {
      GNode dst = app.graph.getEdgeDst(ii);
      int cap = app.graph.getEdgeData(ii);
      if (cap == 0)// || current < node.current) 
        continue;

      Node& dnode = app.graph.getData(dst, Galois::MethodFlag::NONE);
      if (node.height - 1 != dnode.height) 
        continue;

      // Push flow
      int amount = std::min(static_cast<int>(node.excess), cap);
      reduceCapacity(ii, src, dst, amount);

      // Only add once
      if (dst != app.sink && dst != app.source && dnode.excess == 0) 
        ctx.push(dst);
      
      node.excess -= amount;
      dnode.excess += amount;
      
      if (node.excess == 0) {
        finished = true;
        node.current = current;
        break;
      }
    }

    if (finished)
      break;

    relabel(src);
    relabeled = true;

    if (node.height == (int) app.graph.size())
      break;

    //prevHeight = node.height;
  }

  return relabeled;
}