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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines