IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 20411


Ignore:
Timestamp:
Oct 26, 2008, 5:17:43 PM (18 years ago)
Author:
eugene
Message:

adding threading option (not quite ready; disabled), new psphotInit function

Location:
trunk/psphot
Files:
1 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/psphot/doc/notes.txt

    r18555 r20411  
     1
     22008.10.26
     3
     4  (note: this is unoptimized)
     5  0 threads: built models for 3921 objects: 15.223455 sec
     6             built models for 2868 objects: 10.698732 sec
     7
     8  2 threads: built models for 3921 objects: 37.529655 sec
     9             built models for 2862 objects: 28.142142 sec
     10
     11  (clearly, the threading is doing bad things, at least without optimization..)
     12
     13  old code (no threading): 
     14             built models for 3923 objects: 15.265046 sec
     15             built models for 2842 objects: 10.840331 sec
     16
     17  (so, the threaded version without threading is OK)
    118
    2192008.06.25
  • trunk/psphot/src/Makefile.am

    r20079 r20411  
    1818
    1919libpsphot_la_SOURCES = \
     20        psphotSetThreads.c             \
    2021        psphotErrorCodes.c             \
    2122        psphotImageQuality.c           \
  • trunk/psphot/src/psphot.c

    r14655 r20411  
    1010    psTimerStart ("complete");
    1111    pmErrorRegister();                  // register psModule's error codes/messages
    12     psphotErrorRegister();              // register our error codes/messages
    13     psphotModelClassInit ();            // load implementation-specific models
     12    psphotInit();
    1413
    1514    // load command-line arguments, options, and system config data
  • trunk/psphot/src/psphot.h

    r20080 r20411  
    1313#define PSPHOT_RECIPE_PSF_FAKE_ALLOW "PSF.FAKE.ALLOW" // Name for recipe component permitting fake PSFs
    1414
     15typedef struct {
     16    pmReadout *readout;
     17    psArray *sources;
     18    pmPSF *psf;
     19    psRegion *region;
     20    psMaskType maskVal;
     21    psMaskType markVal;
     22} psphotGuessModelForRegionArgs;
    1523
    1624// top-level psphot functions
     
    2028
    2129bool            psphotModelTest (pmConfig *config, const pmFPAview *view, psMetadata *recipe);
     30bool            psphotInit ();
    2231bool            psphotReadout (pmConfig *config, const pmFPAview *view);
    2332bool            psphotReadoutFindPSF(pmConfig *config, const pmFPAview *view);
     
    4150bool            psphotMomentsStats (pmReadout *readout, psMetadata *recipe, psArray *sources);
    4251bool            psphotFitSourcesLinear (pmReadout *readout, psArray *sources, psMetadata *recipe, pmPSF *psf, bool final);
    43 bool            psphotGuessModels (pmReadout *readout, psArray *sources, psMetadata *recipe, pmPSF *psf);
     52bool            psphotGuessModels (pmConfig *config, pmReadout *readout, psArray *sources, pmPSF *psf);
     53bool            psphotGuessModelForRegion (psphotGuessModelForRegionArgs *args);
    4454bool            psphotBlendFit (pmReadout *readout, psArray *sources, psMetadata *recipe, pmPSF *psf);
    4555bool            psphotReplaceUnfitSources (psArray *sources, psMaskType maskVal);
     
    5161bool            psphotExtendedSourceAnalysis (pmReadout *readout, psArray *sources, psMetadata *recipe);
    5262bool            psphotExtendedSourceFits (pmReadout *readout, psArray *sources, psMetadata *recipe);
     63bool            psphotSetThreads ();
    5364
    5465// used by psphotFindDetections
  • trunk/psphot/src/psphotArguments.c

    r19869 r20411  
    2929    // these options override the PSPHOT recipe values loaded from recipe files
    3030    psMetadata *options = pmConfigRecipeOptions (config, PSPHOT_RECIPE);
     31
     32    // Number of threads
     33    if ((N = psArgumentGet(argc, argv, "-threads"))) {
     34        psArgumentRemove(N, &argc, argv);
     35        int nThreads = atoi(argv[N]);
     36        psMetadataAddS32(config->arguments, PS_LIST_TAIL, "NTHREADS", 0, "number of psphot threads", nThreads);
     37        psArgumentRemove(N, &argc, argv);
     38
     39        // create the thread pool with number of desired threads, supplying our thread launcher function
     40        // XXX need to determine the number of threads from the config data
     41        psThreadPoolInit (nThreads);
     42    }
     43    psphotSetThreads();
    3144
    3245    // run the test model (requires X,Y coordinate)
  • trunk/psphot/src/psphotCleanup.c

    r14655 r20411  
    55    psFree (config);
    66
     7    psThreadPoolFinalize ();
    78    psTimerStop ();
    89    psMemCheckCorruption (stderr, true);
  • trunk/psphot/src/psphotGuessModels.c

    r19881 r20411  
    11# include "psphotInternal.h"
     2
     3bool psphotChooseCellSizes (int *Cx, int *Cy, pmReadout *readout, int nThreads);
     4psphotGuessModelForRegionArgs *psphotGuessModelForRegionArgsAlloc();
     5bool psphotGuessModelForRegion (psphotGuessModelForRegionArgs *args);
    26
    37// A guess for when the moments aren't available
     
    1620}
    1721
     22# define NFILL 4
     23
    1824// construct an initial PSF model for each object
    19 bool psphotGuessModels (pmReadout *readout, psArray *sources, psMetadata *recipe, pmPSF *psf) {
     25bool psphotGuessModels (pmConfig *config, pmReadout *readout, psArray *sources, pmPSF *psf) {
    2026
    2127    bool status;
    2228
    2329    psTimerStart ("psphot");
     30
     31    // select the appropriate recipe information
     32    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
     33    assert (recipe);
     34
     35    // int nThreads = psMetadataLookupS32(&status, config->arguments, "NTHREADS"); // Number of threads
     36    // if (!status) {
     37    // nThreads = 0;
     38    // }
     39    int nThreads = 0;
    2440
    2541    // bit-masks to test for good/bad pixels
     
    3753    psphotInitRadiusPSF (recipe, psf->type);
    3854
     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:
     66    int Cx = 1, Cy = 1;
     67    psphotChooseCellSizes (&Cx, &Cy, readout, nThreads);
     68
     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)) {
     128                psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
     129                return false;
     130            }
     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   
     144    psLogMsg ("psphot.models", 4, "built models for %ld objects: %f sec\n", sources->n, psTimerMark ("psphot"));
     145    return true;
     146}
     147
     148static 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
     157psphotGuessModelForRegionArgs *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// construct models only for sources in the specified region
     173bool psphotGuessModelForRegion (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;
     181
     182    int nSrc = 0;
     183
    39184    for (int i = 0; i < sources->n; i++) {
    40185        pmSource *source = sources->data[i];
     
    43188        if (source->type == PM_SOURCE_TYPE_DEFECT) continue;
    44189        if (source->type == PM_SOURCE_TYPE_SATURATED) continue;
    45 
     190        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
     197        nSrc ++;
     198       
    46199        // XXX if a source is faint, it will not have moments measured.
    47200        // it must be modelled as a PSF.  In this case, we need to use
     
    53206        } else {
    54207            // use the source moments, etc to guess basic model parameters
    55             modelEXT = pmSourceModelGuess (source, psf->type);
     208            modelEXT = pmSourceModelGuess (source, psf->type); // ALLOC
    56209            if (!modelEXT) {
    57210                modelEXT = wildGuess(source, psf);
     
    68221
    69222        // set PSF parameters for this model (apply 2D shape model)
    70         pmModel *modelPSF = pmModelFromPSF (modelEXT, psf);
     223        pmModel *modelPSF = pmModelFromPSF (modelEXT, psf); // ALLOC
    71224        if (modelPSF == NULL) {
    72225            psError(PSPHOT_ERR_PSF, false,
     
    92245        // XXX need to define the guess flux?
    93246        // set the fit radius based on the object flux limit and the model
     247        // this function affects the mask pixels
    94248        psphotCheckRadiusPSF (readout, source, modelPSF, markVal);
    95249
     
    99253
    100254        pmSourceCacheModel (source, maskVal);
     255
    101256    }
    102     psLogMsg ("psphot.models", 4, "built models for %ld objects: %f sec\n", sources->n, psTimerMark ("psphot"));
     257
     258    // fprintf (stderr, "%d for region %lf,%lf - %lf,%lf\n", nSrc, region->x0, region->y0, region->x1, region->y1);
    103259    return true;
    104260}
    105261
    106 // XXX do we always know which model is supposed to be used?
     262bool psphotChooseCellSizes (int *Cx, int *Cy, pmReadout *readout, int nThreads) {
     263
     264    int nCells = nThreads * NFILL; // number of cells in a single set
     265    int C = sqrt(nCells) + 0.5;
     266   
     267    // we need to assign Cx and Cy based on the dimensionality of the image
     268    // 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}
  • trunk/psphot/src/psphotReadout.c

    r20171 r20411  
    11# include "psphotInternal.h"
     2
     3// this should be called by every program that links against libpsphot
     4bool psphotInit () {
     5
     6    psphotErrorRegister();              // register our error codes/messages
     7    psphotModelClassInit ();            // load implementation-specific models
     8    psphotSetThreads ();
     9    return true;
     10}
    211
    312bool psphotReadout(pmConfig *config, const pmFPAview *view) {
     
    149158
    150159    // construct an initial model for each object
    151     psphotGuessModels (readout, sources, recipe, psf);
     160    psphotGuessModels (config, readout, sources, psf);
    152161
    153162    // XXX test output of models
     
    207216
    208217    // create full input models
    209     psphotGuessModels (readout, newSources, recipe, psf);
     218    psphotGuessModels (config, readout, newSources, psf);
    210219
    211220    // replace all sources so fit below applies to all at once
Note: See TracChangeset for help on using the changeset viewer.