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.3 by gwlarson, Fri Nov 6 16:54:23 1998 UTC vs.
Revision 3.17 by greg, Wed Oct 22 02:06:34 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  
13 #include "holo.h"
14
10   #include <signal.h>
11 + #include <string.h>
12  
13 + #include "platform.h"
14 + #include "rtprocess.h" /* getpid() */
15 + #include "holo.h"
16 +
17   #ifndef BKBSIZE
18   #define BKBSIZE         256             /* beam clump size (kilobytes) */
19   #endif
20  
21 #define flgop(p,i,op)           ((p)[(i)>>5] op (1L<<((i)&0x1f)))
22 #define isset(p,i)              flgop(p,i,&)
23 #define setfl(p,i)              flgop(p,i,|=)
24 #define clrfl(p,i)              flgop(p,i,&=~)
25
21   char    *progname;
22   char    tempfile[128];
23 + int     dupchecking = 0;
24  
29 extern char     *rindex();
30 extern int      quit();
25   extern long     rhinitcopy();
26  
27  
# Line 40 | Line 34 | char   *argv[];
34          long    nextipos, lastopos, thisopos;
35  
36          progname = argv[0];
37 <        if (argc < 2 | argc > 3) {
38 <                fprintf(stderr, "Usage: %s input.hdk [output.hdk]\n", progname);
37 >        argv++; argc--;                 /* duplicate checking flag? */
38 >        if (argc > 1 && !strcmp(argv[0], "-u")) {
39 >                dupchecking++;
40 >                argv++; argc--;
41 >        }
42 >        if ((argc < 1) | (argc > 2)) {
43 >                fprintf(stderr, "Usage: %s [-u] input.hdk [output.hdk]\n",
44 >                                progname);
45                  exit(1);
46          }
47 <        inpname = argv[1];
48 <        if (argc == 3)                  /* use given output file */
49 <                outname = argv[2];
47 >        inpname = argv[0];              /* get input file */
48 >        argv++; argc--;
49 >        if (argc == 1)                  /* use given output file */
50 >                outname = argv[0];
51          else {                          /* else use temporary file */
52                  if (access(inpname, R_OK|W_OK) < 0) {   /* check permissions */
53                          sprintf(errmsg, "cannot access \"%s\"", inpname);
54                          error(SYSTEM, errmsg);
55                  }
56                  strcpy(tempfile, inpname);
57 <                if ((outname = rindex(tempfile, '/')) != NULL)
57 >                if ((outname = strrchr(tempfile, '/')) != NULL)
58                          outname++;
59                  else
60                          outname = tempfile;
# Line 65 | Line 66 | char   *argv[];
66          lastopos = 0L;                  /* copy sections one by one */
67          while (nextipos != 0L) {
68                                          /* set input position; get next */
69 <                lseek(hdfd[0], nextipos, 0);
69 >                lseek(hdfd[0], (off_t)nextipos, SEEK_SET);
70                  read(hdfd[0], (char *)&nextipos, sizeof(nextipos));
71                                          /* get output position; set last */
72 <                thisopos = lseek(hdfd[1], 0L, 2);
72 >                thisopos = lseek(hdfd[1], (off_t)0, SEEK_END);
73                  if (lastopos > 0L) {
74 <                        lseek(hdfd[1], lastopos, 0);
74 >                        lseek(hdfd[1], (off_t)lastopos, SEEK_SET);
75                          write(hdfd[1], (char *)&thisopos, sizeof(thisopos));
76 <                        lseek(hdfd[1], 0L, 2);
76 >                        lseek(hdfd[1], (off_t)0, SEEK_END);
77                  }
78                  lastopos = thisopos;
79                  thisopos = 0L;          /* write place holder */
# Line 104 | Line 105 | char   *infn, *outfn;
105                  sprintf(errmsg, "cannot open \"%s\" for reading", infn);
106                  error(SYSTEM, errmsg);
107          }
108 +        if (access(outfn, F_OK) == 0) {
109 +                sprintf(errmsg, "output file \"%s\" already exists!", outfn);
110 +                error(USER, errmsg);
111 +        }
112          if ((outfp = fopen(outfn, "w+")) == NULL) {
113                  sprintf(errmsg, "cannot open \"%s\" for writing", outfn);
114                  error(SYSTEM, errmsg);
# Line 130 | Line 135 | char   *infn, *outfn;
135          fclose(infp);
136          if (fclose(outfp) == EOF)
137                  error(SYSTEM, "file flushing error in rhinitcopy");
138 <                                        /* flush everything manually hence */
139 <        hdcachesize = 0;
138 >                                        /* check cache size */
139 >        if (BKBSIZE*1024*1.5 > hdcachesize)
140 >                hdcachesize = BKBSIZE*1024*1.5;
141                                          /* return input position */
142          return(ifpos);
143   }
144  
145  
146 < gcshifti(gc, ia, di, hp)        /* shift cell row or column */
147 < register GCOORD *gc;
148 < int     ia, di;
149 < register HOLO   *hp;
146 > int
147 > nuniq(rva, n)                   /* sort unique rays to front of beam list */
148 > register RAYVAL *rva;
149 > int     n;
150   {
145        int     nw;
146
147        if (di > 0) {
148                if (++gc->i[ia] >= hp->grid[((gc->w>>1)+1+ia)%3]) {
149                        nw = ((gc->w&~1) + (ia<<1) + 3) % 6;
150                        gc->i[ia] = gc->i[1-ia];
151                        gc->i[1-ia] = gc->w&1 ? hp->grid[((nw>>1)+2-ia)%3]-1 : 0;
152                        gc->w = nw;
153                }
154        } else if (di < 0) {
155                if (--gc->i[ia] < 0) {
156                        nw = ((gc->w&~1) + (ia<<1) + 2) % 6;
157                        gc->i[ia] = gc->i[1-ia];
158                        gc->i[1-ia] = gc->w&1 ? hp->grid[((nw>>1)+2-ia)%3]-1 : 0;
159                        gc->w = nw;
160                }
161        }
162 }
163
164
165 mkneighgrid(ng, hp, gc)         /* compute neighborhood for grid cell */
166 GCOORD  ng[3*3];
167 HOLO    *hp;
168 GCOORD  *gc;
169 {
170        GCOORD  gci0;
151          register int    i, j;
152 +        RAYVAL  rtmp;
153  
154 <        for (i = 3; i--; ) {
155 <                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), gci0.w==gc->w, j-1, hp);
160 <                }
161 <        }
154 >        for (j = 0; j < n; j++)
155 >                for (i = j+1; i < n; i++)
156 >                        if ( rva[i].d == rva[j].d &&
157 >                                        rva[i].r[0][0]==rva[j].r[0][0] &&
158 >                                        rva[i].r[0][1]==rva[j].r[0][1] &&
159 >                                        rva[i].r[1][0]==rva[j].r[1][0] &&
160 >                                        rva[i].r[1][1]==rva[j].r[1][1] ) {
161 >                                n--;            /* swap duplicate with end */
162 >                                rtmp = *(rva+n);
163 >                                *(rva+n) = *(rva+i);
164 >                                *(rva+i) = rtmp;
165 >                                i--;            /* recheck one we swapped */
166 >                        }
167 >        return(n);
168   }
169  
170  
171 < int     bneighlist[9*9-1];
185 < int     bneighrem;
171 > static BEAMI    *beamdir;
172  
173 < #define nextneigh()     (bneighrem<=0 ? 0 : bneighlist[--bneighrem])
174 <
175 < int
190 < firstneigh(hp, b)               /* initialize neighbor list and return first */
191 < HOLO    *hp;
192 < int     b;
173 > static int
174 > bpcmp(b1p, b2p)                 /* compare beam positions on disk */
175 > int     *b1p, *b2p;
176   {
177 <        GCOORD  wg0[9], wg1[9], bgc[2];
195 <        int     i, j;
177 >        register off_t  pdif = beamdir[*b1p].fo - beamdir[*b2p].fo;
178  
179 <        hdbcoord(bgc, hp, b);
180 <        mkneighgrid(wg0, hp, bgc);
199 <        mkneighgrid(wg1, hp, bgc+1);
200 <        bneighrem = 0;
201 <        for (i = 9; i--; )
202 <                for (j = 9; j--; ) {
203 <                        if (i == 4 & j == 4)    /* don't copy starting beam */
204 <                                continue;
205 <                        if (wg0[i].w == wg1[j].w)
206 <                                continue;
207 <                        copystruct(bgc, wg0+i);
208 <                        copystruct(bgc+1, wg1+j);
209 <                        bneighlist[bneighrem++] = hdbindex(hp, bgc);
210 < #ifdef DEBUG
211 <                        if (bneighlist[bneighrem-1] <= 0)
212 <                                error(CONSISTENCY, "bad beam in firstneigh");
213 < #endif
214 <                }
215 <        return(nextneigh());
179 >        if (pdif < 0L) return(-1);
180 >        return(pdif > 0L);
181   }
182  
183 + static HOLO     *hout;
184  
185 < BEAMI   *beamdir;
186 <
187 < int
188 < bpcmp(b1p, b2p)                 /* compare beam positions on disk */
223 < int     *b1p, *b2p;
185 > static int
186 > xferclump(hp, bq, nb)           /* transfer the given clump to hout and free */
187 > HOLO    *hp;
188 > int     *bq, nb;
189   {
190 <        register long   pdif = beamdir[*b1p].fo - beamdir[*b2p].fo;
190 >        register int    i;
191 >        register BEAM   *bp;
192 >        int     n;
193  
194 <        if (pdif > 0L) return(1);
195 <        if (pdif < 0L) return(-1);
194 >        beamdir = hp->bi;               /* sort based on file position */
195 >        qsort((void *)bq, nb, sizeof(*bq), bpcmp);
196 >                                        /* transfer and free each beam */
197 >        for (i = 0; i < nb; i++) {
198 >                bp = hdgetbeam(hp, bq[i]);
199 >                DCHECK(bp==NULL, CONSISTENCY, "empty beam in xferclump");
200 >                n = dupchecking ? nuniq(hdbray(bp),bp->nrm) : bp->nrm;
201 >                memcpy((void *)hdnewrays(hout,bq[i],n),(void *)hdbray(bp),
202 >                                n*sizeof(RAYVAL));
203 >                hdfreebeam(hp, bq[i]);
204 >        }
205 >        hdfreebeam(hout, 0);            /* write & free clump */
206          return(0);
207   }
208  
232
209   copysect(ifd, ofd)              /* copy holodeck section from ifd to ofd */
210   int     ifd, ofd;
211   {
212 <        static short    primes[] = {9431,6803,4177,2659,1609,887,587,251,47,1};
237 <        register HOLO   *hinp;
238 <        HOLO    *hout;
239 <        register BEAM   *bp;
240 <        unsigned int4   *bflags;
241 <        int     *bqueue;
242 <        int     bqlen;
243 <        int4    bqtotal;
244 <        int     bc, bci, bqc, myprime;
245 <        register int    i;
212 >        HOLO    *hinp;
213                                          /* load input section directory */
214          hinp = hdinit(ifd, NULL);
215                                          /* create output section directory */
216          hout = hdinit(ofd, (HDGRID *)hinp);
217 <                                        /* allocate beam queue */
218 <        bqueue = (int *)malloc(nbeams(hinp)*sizeof(int));
219 <        bflags = (unsigned int4 *)calloc((nbeams(hinp)>>5)+1,
253 <                        sizeof(unsigned int4));
254 <        if (bqueue == NULL | bflags == NULL)
255 <                error(SYSTEM, "out of memory in copysect");
256 <                                        /* mark empty beams as done */
257 <        for (i = nbeams(hinp); i > 0; i--)
258 <                if (!hinp->bi[i].nrd)
259 <                        setfl(bflags, i);
260 <                                        /* pick a good prime step size */
261 <        for (i = 0; primes[i]<<5 >= nbeams(hinp); i++)
262 <                ;
263 <        while ((myprime = primes[i++]) > 1)
264 <                if (nbeams(hinp) % myprime)
265 <                        break;
266 <                                        /* add each input beam and neighbors */
267 <        for (bc = bci = nbeams(hinp); bc > 0; bc--,
268 <                        bci += bci>myprime ? -myprime : nbeams(hinp)-myprime) {
269 <                if (isset(bflags, bci))
270 <                        continue;
271 <                bqueue[0] = bci;                /* initialize queue */
272 <                bqlen = 1;
273 <                bqtotal = hinp->bi[bci].nrd;
274 <                setfl(bflags, bci);
275 <                                                /* run through growing queue */
276 <                for (bqc = 0; bqc < bqlen; bqc++) {
277 <                                                /* add neighbors until full */
278 <                        for (i = firstneigh(hinp,bqueue[bqc]); i > 0;
279 <                                        i = nextneigh()) {
280 <                                if (isset(bflags, i))   /* done already? */
281 <                                        continue;
282 <                                bqueue[bqlen++] = i;    /* add it */
283 <                                bqtotal += hinp->bi[i].nrd;
284 <                                setfl(bflags, i);
285 <                                if (bqtotal >= BKBSIZE*1024/sizeof(RAYVAL))
286 <                                        break;          /* queue full */
287 <                        }
288 <                        if (i > 0)
289 <                                break;
290 <                }
291 <                beamdir = hinp->bi;             /* sort queue */
292 <                qsort((char *)bqueue, bqlen, sizeof(*bqueue), bpcmp);
293 <                                                /* transfer each beam */
294 <                for (i = 0; i < bqlen; i++) {
295 <                        bp = hdgetbeam(hinp, bqueue[i]);
296 <                        bcopy((char *)hdbray(bp),
297 <                                (char *)hdnewrays(hout,bqueue[i],bp->nrm),
298 <                                        bp->nrm*sizeof(RAYVAL));
299 <                        hdfreebeam(hinp, bqueue[i]);
300 <                }
301 <                hdfreebeam(hout, 0);            /* flush output block */
302 < #ifdef DEBUG
303 <                hdsync(hout, 0);
304 < #endif
305 <        }
306 <                                        /* we're done -- clean up */
307 <        free((char *)bqueue);
308 <        free((char *)bflags);
217 >                                        /* clump the beams */
218 >        clumpbeams(hinp, 0, BKBSIZE*1024, xferclump);
219 >                                        /* clean up */
220          hddone(hinp);
221          hddone(hout);
222   }
223  
224  
225 + void
226   eputs(s)                        /* put error message to stderr */
227   register char  *s;
228   {
# Line 330 | Line 242 | register char  *s;
242   }
243  
244  
245 + void
246   quit(code)                      /* exit the program gracefully */
247   int     code;
248   {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines