Changeset 21166 for trunk/psphot/src/psphotGuessModels.c
- Timestamp:
- Jan 24, 2009, 10:54:29 AM (17 years ago)
- File:
-
- 1 edited
-
trunk/psphot/src/psphotGuessModels.c (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psphot/src/psphotGuessModels.c
r20453 r21166 1 1 # include "psphotInternal.h" 2 2 3 bool psphotChooseCellSizes (int *Cx, int *Cy, pmReadout *readout, int nThreads); 4 psphotGuessModelForRegionArgs *psphotGuessModelForRegionArgsAlloc(); 5 bool psphotGuessModelForRegion (psphotGuessModelForRegionArgs *args); 3 // XXX : the threading here is not great. this may be due to blocks between elements, but 4 // the selection of the objects in a cell is not optimal. To fix: 5 // 1) define the boundaries of the cells up front 6 // 2) loop over the sources once and associate them with their cell 7 // 3) define the threaded function to work with sources for a given cell 6 8 7 9 // A guess for when the moments aren't available … … 20 22 } 21 23 22 # define NFILL 423 24 24 // construct an initial PSF model for each object 25 25 bool psphotGuessModels (pmConfig *config, pmReadout *readout, psArray *sources, pmPSF *psf) { … … 33 33 assert (recipe); 34 34 35 // int nThreads = psMetadataLookupS32(&status, config->arguments, "NTHREADS"); // Number of threads 36 // if (!status) { 37 // nThreads = 0; 38 // } 39 int nThreads = 0; 35 // determine the number of allowed threads 36 int nThreads = psMetadataLookupS32(&status, config->arguments, "NTHREADS"); // Number of threads 37 if (!status) { 38 nThreads = 0; 39 } 40 // nThreads = 0; // XXX until testing is complete, do not thread this function 40 41 41 42 // bit-masks to test for good/bad pixels … … 53 54 psphotInitRadiusPSF (recipe, psf->type); 54 55 55 // the strategy here is to divide the image into 2x2 blocks of cells and cycle through 56 // the four discontiguous sets of cells, threading all within a set and blocking between 57 // sets 58 59 // we divide the image region into 2*2 blocks of size Nx*Ny, the image will have 60 // Cx*Cy blocks so that (2Nx)Cx = numCols, (2Ny)Cy = numRows. We want to choose Cx and 61 // Cy so that (2Nx)Cx * (2Ny)Cy = 4 * NFILL * nThreads -- each of the four sets of cells 62 // has enough cells to allow NFILL cells for each thread (to better distribute heavy and 63 // light load cells 64 65 // choose Cx, Cy: 56 // choose Cx, Cy (see psphotThreadTools.c for overview of the concepts) 66 57 int Cx = 1, Cy = 1; 67 58 psphotChooseCellSizes (&Cx, &Cy, readout, nThreads); 68 59 69 // the array runs from readout->image->col0 to readout->image->col0 + readout->image->numCols 70 int Xo = readout->image->col0; 71 int Yo = readout->image->row0; 72 int Nx = readout->image->numCols / (2*Cx); 73 int Ny = readout->image->numRows / (2*Cy); 74 75 // we can thread all of the cells within a set, but need to block between sets 76 for (int jy = 0; jy < 2; jy++) { 77 for (int jx = 0; jx < 2; jx++) { 78 79 // generate jobs for all of the Cx*Cy cells in this set 80 for (int ix = 0; ix < Cx; ix++) { 81 for (int iy = 0; iy < Cy; iy++) { 82 83 int x0 = (2*ix + jx)*Nx + Xo; 84 int x1 = x0 + Nx; 85 86 int y0 = (2*iy + jy)*Ny + Yo; 87 int y1 = y0 + Ny; 88 89 if (readout->image->numCols + Xo - x1 < Nx) { 90 x1 = readout->image->numCols + Xo; 91 } 92 if (readout->image->numRows + Yo - y1 < Ny) { 93 y1 = readout->image->numRows + Yo; 94 } 95 96 // fprintf (stderr, "launch %d,%d - %d,%d\n", x0, y0, x1, y1); 97 98 psRegion *cellRegion = psRegionAlloc (x0, x1, y0, y1); 99 *cellRegion = psRegionForImage (readout->image, *cellRegion); 100 // if we got the math above right, this should be a NOP 101 102 psphotGuessModelForRegionArgs *args = psphotGuessModelForRegionArgsAlloc(); 103 args->readout = psMemIncrRefCounter(readout); 104 args->sources = psMemIncrRefCounter(sources); 105 args->psf = psMemIncrRefCounter(psf); 106 args->region = psMemIncrRefCounter(cellRegion); 107 108 args->maskVal = maskVal; 109 args->markVal = markVal; 110 111 // allocate a job -- if threads are not defined, this just runs the job 112 psThreadJob *job = psThreadJobAlloc ("PSPHOT_GUESS_MODEL"); 113 psArrayAdd(job->args, 1, args); 114 if (!psThreadJobAddPending(job)) { 115 psError(PS_ERR_UNKNOWN, false, "Unable to guess model."); 116 return false; 117 } 118 psFree(cellRegion); 119 psFree(job); 120 psFree(args); 121 } 122 } 123 124 // wait for the threads to finish and manage results 125 // wait here for the threaded jobs to finish 126 // fprintf (stderr, "wait for threads (%d, %d)\n", jx, jy); 127 if (!psThreadPoolWait (false)) { 60 psArray *cellGroups = psphotAssignSources (Cx, Cy, sources); 61 62 for (int i = 0; i < cellGroups->n; i++) { 63 64 psArray *cells = cellGroups->data[i]; 65 66 for (int j = 0; j < cells->n; j++) { 67 68 // allocate a job -- if threads are not defined, this just runs the job 69 psThreadJob *job = psThreadJobAlloc ("PSPHOT_GUESS_MODEL"); 70 psArrayAdd(job->args, 1, readout); 71 psArrayAdd(job->args, 1, cells->data[j]); // sources 72 psArrayAdd(job->args, 1, psf); 73 74 // XXX change these to use abstract mask type info 75 PS_ARRAY_ADD_SCALAR(job->args, maskVal, PS_TYPE_U8); 76 PS_ARRAY_ADD_SCALAR(job->args, markVal, PS_TYPE_U8); 77 78 if (!psThreadJobAddPending(job)) { 128 79 psError(PS_ERR_UNKNOWN, false, "Unable to guess model."); 80 psFree (job); 129 81 return false; 130 82 } 131 132 // we have only supplied one type of job, so we can assume the types here 133 psThreadJob *job = NULL; 134 while ((job = psThreadJobGetDone()) != NULL) { 135 // we have no returned data from this operation 136 if (job->args->n < 1) { 137 fprintf (stderr, "error with job\n"); 138 } 139 psFree(job); 140 } 141 } 142 } 143 83 psFree(job); 84 } 85 86 // wait for the threads to finish and manage results 87 // wait here for the threaded jobs to finish 88 // fprintf (stderr, "wait for threads (%d, %d)\n", jx, jy); 89 if (!psThreadPoolWait (false)) { 90 psError(PS_ERR_UNKNOWN, false, "Unable to guess model."); 91 return false; 92 } 93 94 // we have only supplied one type of job, so we can assume the types here 95 psThreadJob *job = NULL; 96 while ((job = psThreadJobGetDone()) != NULL) { 97 // we have no returned data from this operation 98 if (job->args->n < 1) { 99 fprintf (stderr, "error with job\n"); 100 } 101 psFree(job); 102 } 103 } 104 105 // XXX check that all sources that should have models 106 int nMiss = 0; 107 for (int i = 0; i < sources->n; i++) { 108 109 pmSource *source = sources->data[i]; 110 if (source->mode & PM_SOURCE_MODE_EXT_LIMIT) { 111 source->mode &= ~PM_SOURCE_MODE_EXT_LIMIT; 112 continue; 113 } 114 115 nMiss ++; 116 } 117 psLogMsg ("psphot.models", 4, "failed to build models for %d objects\n", nMiss); 118 119 psFree (cellGroups); 120 144 121 psLogMsg ("psphot.models", 4, "built models for %ld objects: %f sec\n", sources->n, psTimerMark ("psphot.models")); 145 122 return true; 146 123 } 147 124 148 static void psphotGuessModelForRegionArgsFree(psphotGuessModelForRegionArgs *args)149 {150 psFree(args->readout);151 psFree(args->sources);152 psFree(args->psf);153 psFree(args->region);154 return;155 }156 157 psphotGuessModelForRegionArgs *psphotGuessModelForRegionArgsAlloc()158 {159 psphotGuessModelForRegionArgs *args = psAlloc(sizeof(psphotGuessModelForRegionArgs));160 psMemSetDeallocator(args, (psFreeFunc)psphotGuessModelForRegionArgsFree);161 162 args->readout = NULL;163 args->sources = NULL;164 args->psf = NULL;165 args->region = NULL;166 167 args->maskVal = 0;168 args->markVal = 0;169 return args;170 }171 172 125 // construct models only for sources in the specified region 173 bool psphotGuessModel ForRegion (psphotGuessModelForRegionArgs *args) {174 175 pmReadout *readout = args->readout;176 psArray *sources = args->sources;177 pmPSF *psf = args->psf;178 psRegion *region = args->region;179 psMaskType maskVal = args->maskVal;180 psMaskType markVal = args->markVal;126 bool psphotGuessModel_Threaded (psThreadJob *job) { 127 128 pmReadout *readout = job->args->data[0]; 129 psArray *sources = job->args->data[1]; 130 pmPSF *psf = job->args->data[2]; 131 132 psMaskType maskVal = PS_SCALAR_VALUE(job->args->data[3],U8); 133 psMaskType markVal = PS_SCALAR_VALUE(job->args->data[4],U8); 181 134 182 135 int nSrc = 0; … … 184 137 for (int i = 0; i < sources->n; i++) { 185 138 pmSource *source = sources->data[i]; 139 140 // XXXX this is just for a test: use this to mark sources for which the model is measured 141 // check later that all are used. 142 source->mode |= PM_SOURCE_MODE_EXT_LIMIT; 186 143 187 144 // skip non-astronomical objects (very likely defects) … … 189 146 if (source->type == PM_SOURCE_TYPE_SATURATED) continue; 190 147 if (!source->peak) continue; 191 192 if (source->peak->xf < region->x0) continue;193 if (source->peak->yf < region->y0) continue;194 if (source->peak->xf >= region->x1) continue;195 if (source->peak->yf >= region->y1) continue;196 148 197 149 nSrc ++; … … 256 208 } 257 209 258 // fprintf (stderr, "%d for region %lf,%lf - %lf,%lf\n", nSrc, region->x0, region->y0, region->x1, region->y1);259 210 return true; 260 211 } 261 212 262 bool psphotChooseCellSizes (int *Cx, int *Cy, pmReadout *readout, int nThreads) {263 264 int nCells = nThreads * NFILL; // number of cells in a single set265 int C = sqrt(nCells) + 0.5;266 267 // we need to assign Cx and Cy based on the dimensionality of the image268 // crude way to find most evenly balanced factors of nCells:269 for (int i = C; i >= 1; i--) {270 int C1 = nCells / C;271 int C2 = nCells / C1;272 if (C1*C2 != nCells) continue;273 274 if (readout->image->numRows > readout->image->numCols) {275 *Cx = PS_MAX (C1, C2);276 *Cy = PS_MIN (C1, C2);277 } else {278 *Cx = PS_MAX (C1, C2);279 *Cy = PS_MIN (C1, C2);280 }281 return true;282 }283 *Cx = 1;284 *Cy = 1;285 286 return true;287 }
Note:
See TracChangeset
for help on using the changeset viewer.
