ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rhoptimize.c
(Generate patch)

Comparing ray/src/hd/rhoptimize.c (file contents):
Revision 3.1 by gwlarson, Wed Nov 4 16:37:19 1998 UTC vs.
Revision 3.14 by schorsch, Mon Jul 21 22:30:18 2003 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1998 Silicon Graphics, Inc. */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ SGI";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   * Optimize holodeck for quick access.
6   *
7   *      11/4/98         Greg Ward Larson
8   */
9  
10 + #include <signal.h>
11 + #include <string.h>
12 +
13 + #include "rtprocess.h" /* getpid() */
14   #include "holo.h"
15  
16   #ifndef BKBSIZE
17 < #define BKBSIZE         64              /* beam clump size (kilobytes) */
17 > #define BKBSIZE         256             /* beam clump size (kilobytes) */
18   #endif
19  
19
20   char    *progname;
21 + char    tempfile[128];
22 + int     dupchecking = 0;
23  
24   extern long     rhinitcopy();
25  
# Line 26 | Line 28 | main(argc, argv)
28   int     argc;
29   char    *argv[];
30   {
29        char    nambuf[128];
31          char    *inpname, *outname;
32          int     hdfd[2];
33          long    nextipos, lastopos, thisopos;
34  
35          progname = argv[0];
36 <        if (argc < 2 | argc > 3) {
37 <                fprintf(stderr, "Usage: %s input.hdk [output.hdk]\n", progname);
36 >        argv++; argc--;                 /* duplicate checking flag? */
37 >        if (argc > 1 && !strcmp(argv[0], "-u")) {
38 >                dupchecking++;
39 >                argv++; argc--;
40 >        }
41 >        if (argc < 1 | argc > 2) {
42 >                fprintf(stderr, "Usage: %s [-u] input.hdk [output.hdk]\n",
43 >                                progname);
44                  exit(1);
45          }
46 <        inpname = argv[1];
47 <        if (argc == 3)                  /* use given output file */
48 <                outname = argv[2];
49 <        else {                          /* else create temporary file */
50 <                strcpy(nambuf, inpname);
51 <                if ((outname = strrchr(nambuf, '/')) != NULL)
46 >        inpname = argv[0];              /* get input file */
47 >        argv++; argc--;
48 >        if (argc == 1)                  /* use given output file */
49 >                outname = argv[0];
50 >        else {                          /* else use temporary file */
51 >                if (access(inpname, R_OK|W_OK) < 0) {   /* check permissions */
52 >                        sprintf(errmsg, "cannot access \"%s\"", inpname);
53 >                        error(SYSTEM, errmsg);
54 >                }
55 >                strcpy(tempfile, inpname);
56 >                if ((outname = strrchr(tempfile, '/')) != NULL)
57                          outname++;
58                  else
59 <                        outname = nambuf;
59 >                        outname = tempfile;
60                  sprintf(outname, "rho%d.hdk", getpid());
61 <                outname = nambuf;
61 >                outname = tempfile;
62          }
63                                          /* copy holodeck file header */
64          nextipos = rhinitcopy(hdfd, inpname, outname);
65          lastopos = 0L;                  /* copy sections one by one */
66          while (nextipos != 0L) {
67                                          /* set input position; get next */
68 <                lseek(hdfd[0], nextipos, 0);
68 >                lseek(hdfd[0], (off_t)nextipos, 0);
69                  read(hdfd[0], (char *)&nextipos, sizeof(nextipos));
70                                          /* get output position; set last */
71 <                thisopos = lseek(hdfd[1], 0L, 2);
71 >                thisopos = lseek(hdfd[1], (off_t)0, 2);
72                  if (lastopos > 0L) {
73 <                        lseek(hdfd[1], lastopos, 0);
73 >                        lseek(hdfd[1], (off_t)lastopos, 0);
74                          write(hdfd[1], (char *)&thisopos, sizeof(thisopos));
75 <                        lseek(hdfd[1], 0L, 2);
75 >                        lseek(hdfd[1], (off_t)0, 2);
76                  }
77                  lastopos = thisopos;
78                  thisopos = 0L;          /* write place holder */
# Line 71 | Line 83 | char   *argv[];
83                                          /* clean up */
84          close(hdfd[0]);
85          close(hdfd[1]);
86 <        if (argc == 2 && rename(outname, inpname) < 0) {
86 >        if (outname == tempfile && rename(outname, inpname) < 0) {
87                  sprintf(errmsg, "cannot rename \"%s\" to \"%s\"",
88                                  outname, inpname);
89                  error(SYSTEM, errmsg);
# Line 92 | Line 104 | char   *infn, *outfn;
104                  sprintf(errmsg, "cannot open \"%s\" for reading", infn);
105                  error(SYSTEM, errmsg);
106          }
107 +        if (access(outfn, F_OK) == 0) {
108 +                sprintf(errmsg, "output file \"%s\" already exists!", outfn);
109 +                error(USER, errmsg);
110 +        }
111          if ((outfp = fopen(outfn, "w+")) == NULL) {
112                  sprintf(errmsg, "cannot open \"%s\" for writing", outfn);
113                  error(SYSTEM, errmsg);
114          }
115 +                                        /* set up signal handling */
116 +        if (signal(SIGINT, quit) == SIG_IGN) signal(SIGINT, SIG_IGN);
117 +        if (signal(SIGHUP, quit) == SIG_IGN) signal(SIGHUP, SIG_IGN);
118 +        if (signal(SIGTERM, quit) == SIG_IGN) signal(SIGTERM, SIG_IGN);
119 + #ifdef SIGXCPU
120 +        if (signal(SIGXCPU, quit) == SIG_IGN) signal(SIGXCPU, SIG_IGN);
121 +        if (signal(SIGXFSZ, quit) == SIG_IGN) signal(SIGXFSZ, SIG_IGN);
122 + #endif
123                                          /* copy and verify header */
124 <        if (checkheader(infp, HOLOFMT, outfp) < 0 ||
101 <                        getw(infp) != HOLOMAGIC)
124 >        if (checkheader(infp, HOLOFMT, outfp) < 0 || getw(infp) != HOLOMAGIC)
125                  error(USER, "input not in holodeck format");
126          fputformat(HOLOFMT, outfp);
127          fputc('\n', outfp);
# Line 111 | Line 134 | char   *infn, *outfn;
134          fclose(infp);
135          if (fclose(outfp) == EOF)
136                  error(SYSTEM, "file flushing error in rhinitcopy");
137 <                                        /* we flush everything manually */
138 <        hdcachesize = 0;
137 >                                        /* check cache size */
138 >        if (BKBSIZE*1024*1.5 > hdcachesize)
139 >                hdcachesize = BKBSIZE*1024*1.5;
140                                          /* return input position */
141          return(ifpos);
142   }
143  
144  
145 < gcshifti(gc, ia, di, hp)        /* shift cell row or column */
146 < register GCOORD *gc;
147 < int     ia, di;
148 < register HOLO   *hp;
145 > int
146 > nuniq(rva, n)                   /* sort unique rays to front of beam list */
147 > register RAYVAL *rva;
148 > int     n;
149   {
150 <        int     nw;
150 >        register int    i, j;
151 >        RAYVAL  rtmp;
152  
153 <        if (di > 0) {
154 <                if (++gc->i[ia] >= hp->grid[((gc->w>>1)+1+ia)%3]) {
155 <                        nw = ((gc->w&~1) + (ia<<1) + 3) % 6;
156 <                        gc->i[ia] = gc->i[1-ia];
157 <                        gc->i[1-ia] = gc->w&1 ? hp->grid[((nw>>1)+2-ia)%3]-1 : 0;
158 <                        gc->w = nw;
159 <                }
160 <        } else if (di < 0) {
161 <                if (--gc->i[ia] < 0) {
162 <                        nw = ((gc->w&~1) + (ia<<1) + 2) % 6;
163 <                        gc->i[ia] = gc->i[1-ia];
164 <                        gc->i[1-ia] = gc->w&1 ? hp->grid[((nw>>1)+2-ia)%3]-1 : 0;
165 <                        gc->w = nw;
166 <                }
142 <        }
153 >        for (j = 0; j < n; j++)
154 >                for (i = j+1; i < n; i++)
155 >                        if ( rva[i].d == rva[j].d &&
156 >                                        rva[i].r[0][0]==rva[j].r[0][0] &&
157 >                                        rva[i].r[0][1]==rva[j].r[0][1] &&
158 >                                        rva[i].r[1][0]==rva[j].r[1][0] &&
159 >                                        rva[i].r[1][1]==rva[j].r[1][1] ) {
160 >                                n--;            /* swap duplicate with end */
161 >                                rtmp = *(rva+n);
162 >                                *(rva+n) = *(rva+i);
163 >                                *(rva+i) = rtmp;
164 >                                i--;            /* recheck one we swapped */
165 >                        }
166 >        return(n);
167   }
168  
169  
170 < mkneighgrid(ng, hp, gc)         /* compute neighborhood for grid cell */
171 < GCOORD  ng[3*3];
172 < HOLO    *hp;
173 < GCOORD  *gc;
170 > static BEAMI    *beamdir;
171 >
172 > static int
173 > bpcmp(b1p, b2p)                 /* compare beam positions on disk */
174 > int     *b1p, *b2p;
175   {
176 <        GCOORD  gci0;
152 <        int     i, j;
176 >        register off_t  pdif = beamdir[*b1p].fo - beamdir[*b2p].fo;
177  
178 <        for (i = 3; i--; ) {
179 <                copystruct(&gci0, gc);
156 <                gcshifti(&gci0, 0, i-1, hp);
157 <                for (j = 3; j--; ) {
158 <                        copystruct(ng+(3*i+j), &gci0);
159 <                        gcshifti(ng+(3*i+j), 1, j-1, hp);
160 <                }
161 <        }
178 >        if (pdif < 0L) return(-1);
179 >        return(pdif > 0L);
180   }
181  
182 + static HOLO     *hout;
183  
184 < int     bneighlist[9*9-1];
185 < int     bneighrem;
167 <
168 < #define nextneigh()     (bneighrem<=0 ? 0 : bneighlist[--bneighrem])
169 <
170 < int
171 < firstneigh(hp, b)               /* initialize neighbor list and return first */
184 > static int
185 > xferclump(hp, bq, nb)           /* transfer the given clump to hout and free */
186   HOLO    *hp;
187 < int     b;
187 > int     *bq, nb;
188   {
189 <        GCOORD  wg0[9], wg1[9], bgc[2];
190 <        int     i, j;
189 >        register int    i;
190 >        register BEAM   *bp;
191 >        int     n;
192  
193 <        hdbcoord(bgc, hp, b);
194 <        mkneighgrid(wg0, hp, bgc);
195 <        mkneighgrid(wg1, hp, bgc+1);
196 <        bneighrem = 0;
197 <        for (i = 9; i--; )
198 <                for (j = 9; j--; ) {
199 <                        if (i == 4 & j == 4)
200 <                                continue;
201 <                        copystruct(bgc, wg0+i);
202 <                        copystruct(bgc+1, wg1+j);
203 <                        bneighlist[bneighrem++] = hdbindex(hp, bgc);
204 <                }
205 <        return(nextneigh());
193 >        beamdir = hp->bi;               /* sort based on file position */
194 >        qsort((void *)bq, nb, sizeof(*bq), bpcmp);
195 >                                        /* transfer and free each beam */
196 >        for (i = 0; i < nb; i++) {
197 >                bp = hdgetbeam(hp, bq[i]);
198 >                DCHECK(bp==NULL, CONSISTENCY, "empty beam in xferclump");
199 >                n = dupchecking ? nuniq(hdbray(bp),bp->nrm) : bp->nrm;
200 >                memcpy((void *)hdnewrays(hout,bq[i],n),(void *)hdbray(bp),
201 >                                n*sizeof(RAYVAL));
202 >                hdfreebeam(hp, bq[i]);
203 >        }
204 >        hdfreebeam(hout, 0);            /* write & free clump */
205 >        return(0);
206   }
207  
193
208   copysect(ifd, ofd)              /* copy holodeck section from ifd to ofd */
209   int     ifd, ofd;
210   {
211 < #define beamdone(b)     (!hinp->bi[b].nrd || bnrays(hout,b))
198 <        static short    primes[] = {9431,6803,4177,2659,1609,887,587,251,47,1};
199 <        register HOLO   *hinp, *hout;
200 <        register BEAM   *bp;
201 <        int     *bqueue;
202 <        int     bqlen;
203 <        int4    bqtotal;
204 <        int     bc, bci, bqc, bnc, myprime;
205 <        register int    i;
211 >        HOLO    *hinp;
212                                          /* load input section directory */
213          hinp = hdinit(ifd, NULL);
214                                          /* create output section directory */
215          hout = hdinit(ofd, (HDGRID *)hinp);
216 <                                        /* allocate beam queue */
217 <        if ((bqueue = (int *)malloc(nbeams(hinp)*sizeof(int))) == NULL)
218 <                error(SYSTEM, "out of memory in copysect");
213 <                                        /* pick a good prime step size */
214 <        for (i = 0; primes[i]<<5 >= nbeams(hinp); i++)
215 <                ;
216 <        while ((myprime = primes[i++]) > 1)
217 <                if (nbeams(hinp) % myprime)
218 <                        break;
219 <                                        /* add each input beam and neighbors */
220 <        for (bc = bci = nbeams(hinp); bc > 0; bc--,
221 <                        bci += bci>myprime ? -myprime : nbeams(hinp)-myprime) {
222 <                if (beamdone(bci))
223 <                        continue;
224 <                bqueue[0] = bci;                /* initialize queue */
225 <                bqlen = 1;
226 <                bqtotal = bnrays(hinp, bci);
227 <                                                /* run through growing queue */
228 <                for (bqc = 0; bqc < bqlen; bqc++) {
229 <                                                /* transfer the beam */
230 <                        bp = hdgetbeam(hinp, bqueue[bqc]);
231 <                        bcopy((char *)hdbray(bp),
232 <                                (char *)hdnewrays(hout,bqueue[bqc],bp->nrm),
233 <                                        bp->nrm*sizeof(RAYVAL));
234 <                        hdfreebeam(hinp, bqueue[bqc]);
235 <                                                /* check queue size */
236 <                        if (bqtotal >= BKBSIZE*1024/sizeof(RAYVAL))
237 <                                continue;
238 <                                                /* add neighbors to queue */
239 <                        for (bnc = firstneigh(hinp,bqueue[bqc]); bnc > 0;
240 <                                        bnc = nextneigh()) {
241 <                                if (beamdone(bnc))      /* see if valid */
242 <                                        continue;
243 <                                for (i = bqlen; i--; )
244 <                                        if (bqueue[i] == bnc) break;
245 <                                if (i >= 0)
246 <                                        continue;
247 <                                bqueue[bqlen++] = bnc;  /* add it */
248 <                                bqtotal += bnrays(hinp, bnc);
249 <                                if (bqtotal >= BKBSIZE*1024/sizeof(RAYVAL))
250 <                                        break;          /* queue full */
251 <                        }
252 <                }
253 <                hdfreebeam(hout, 0);            /* flush output block */
254 <        }
255 <                                        /* we're done -- clean up */
256 <        free((char *)bqueue);
216 >                                        /* clump the beams */
217 >        clumpbeams(hinp, 0, BKBSIZE*1024, xferclump);
218 >                                        /* clean up */
219          hddone(hinp);
220          hddone(hout);
259 #undef beamdone
221   }
222  
223  
224 + void
225   eputs(s)                        /* put error message to stderr */
226   register char  *s;
227   {
# Line 279 | Line 241 | register char  *s;
241   }
242  
243  
244 + void
245   quit(code)                      /* exit the program gracefully */
246   int     code;
247   {
248 <        hdsync(NULL, 1);        /* write out any buffered data */
248 >        if (tempfile[0])
249 >                unlink(tempfile);
250          exit(code);
251   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines