M3_cache.c

00001 #include <stdlib.h>
00002 #include <stdio.h>
00003 
00004 #include "M3.h"
00005 #include "M3_cache.h"
00006 #include "M3_otfs.h"
00007 #include "M3_gcp.h"
00008 
00009 #ifdef USE_MPI
00010 #include "mpi.h"
00011 #include "M3_mpi.h"
00012 #endif
00013 
00014 int M3_RunConfigStruct_GetTODcache( M3_RunConfigStruct *runConfig, M3_TODcacheStruct **todCache )
00015 {
00016   *todCache = &(runConfig->todCache);
00017   return( M3_EFLAG_NONE );
00018 }
00019 
00020 int M3_TODcacheStruct_SetCacheAll( M3_TODcacheStruct *todCache )
00021 {
00022   todCache->useGCPcache = 1;
00023   todCache->useScanMapCache = 1;
00024   return( M3_EFLAG_NONE );
00025 }
00026 
00027 int M3_TODcacheStruct_SetCacheNone( M3_TODcacheStruct *todCache )
00028 {
00029   todCache->useGCPcache = 0;
00030   todCache->useScanMapCache = 0;
00031   return( M3_EFLAG_NONE );
00032 }
00033 
00034 int M3_TODcacheStruct_SetCacheGCPdata( M3_TODcacheStruct *todCache, int useGCPcache )
00035 {
00036   todCache->useGCPcache = useGCPcache;
00037   return( M3_EFLAG_NONE );
00038 }
00039 
00040 int M3_TODcacheStruct_SetCacheScanMapData( M3_TODcacheStruct *todCache, int useScanMapCache )
00041 {
00042   todCache->useScanMapCache = useScanMapCache;
00043   return( M3_EFLAG_NONE );
00044 }
00045 
00046 int M3_TODcacheStruct_AppendRequest( M3_TODcacheStruct *todCache, M3_DataSetLL *dataSet, M3_Interval requestInterval)
00047 {
00048   M3_TODrequestLL *thisRequest;
00049   /* Check to be sure that caching is turned on.  */
00050   if( todCache->useGCPcache || todCache->useScanMapCache )
00051   {     
00052     /* Add an empty node to the list. */
00053     if( todCache->todRequestList == NULL )
00054     {
00055       M3_MallocRecordLL_AppendToList( &(todCache->mallocRecordList), sizeof(M3_TODrequestLL), (void **)&(todCache->todRequestList ));
00056       thisRequest = todCache->todRequestList;
00057     }
00058     else
00059     {
00060       for( thisRequest = todCache->todRequestList;
00061            thisRequest->next;
00062            thisRequest = thisRequest->next );
00063       M3_MallocRecordLL_AppendToList( &(todCache->mallocRecordList), sizeof(M3_TODrequestLL), (void **)&(thisRequest->next));
00064       thisRequest = thisRequest->next;
00065     }
00066   
00067     /* Fill in the request values. */
00068     thisRequest->dataSetNode = dataSet;
00069     thisRequest->sampleInterval = requestInterval;
00070     thisRequest->next = NULL;
00071   }
00072   return( M3_EFLAG_NONE );
00073 }
00074 
00075 int M3_MallocRecordLL_AppendToList( M3_MallocRecordLL **recordList, size_t size, void **space )
00076 {
00077   M3_MallocRecordLL *record;
00078 
00079   if( size == 0 )
00080     return( M3_EFLAG_NONE );
00081 
00082   /* Add an empty node to the list.  */
00083   if( *recordList )
00084   {
00085     for( record = *recordList; record->next; record = record->next );
00086     record->next = calloc(1,sizeof(M3_MallocRecordLL));
00087     record = record->next;
00088   }
00089   else
00090   {
00091     *recordList = calloc(1,sizeof(M3_MallocRecordLL));
00092     record = *recordList;
00093   }
00094   M3_ErrorCheck(-1, "M3_MallocRecordLL_AppendToList()", (record ? 1:0), M3_EFLAG_MALLOC_FSTRING );
00095   /* Set the size and allocate the space. */
00096   record->size = size;
00097   record->space = calloc(size, 1);
00098   M3_ErrorCheck(-1, "M3_MallocRecordLL_AppendToList()", (record->space ? 1:0), M3_EFLAG_MALLOC_FSTRING );
00099 
00100   /* Set the output pointer */
00101   *space = record->space;
00102 
00103   return( M3_EFLAG_NONE );
00104 }
00105 
00106 
00107 int M3_MallocRecordLL_Destroy( M3_MallocRecordLL *recordList )
00108 {
00109   M3_MallocRecordLL *thisRecord, *tempRecord;
00110 
00111   thisRecord = recordList;
00112   while( thisRecord )
00113   {
00114     tempRecord = thisRecord->next;
00115     if( thisRecord->space )
00116       free( thisRecord->space );
00117     free(thisRecord);
00118     thisRecord = tempRecord;
00119   }
00120 
00121   return( M3_EFLAG_NONE );
00122 }
00123 
00124 
00125 int M3_TODcacheStruct_Initialize( M3_TODcacheStruct *todCache, M3_RunConfigStruct *runConfig, size_t *storeSize )
00126 {
00127   int32_t i, j, k, cacheMap;
00128   int64_t numHitPixel;
00129   M3_BitArray bitArray = {0};
00130   M3_PixelConvertStruct *pixelConvert;
00131   M3_TimeIntervalLL *timeIntervalList;
00132   M3_GCPointingGroupLL *thisGCPgroup, *thatGCPgroup;
00133   M3_TODrequestLL *thisRequest;
00134   M3_TimeInterval thisTimeInterval;
00135   M3_IntervalLL requestInterval;
00136   M3_PixelClassLL *thisPixelClass;
00137   M3_MallocRecordLL *thisRecord;
00138   M3_MapEl *mapPtr;
00139   M3_DataSetLL *thisDataSet;
00140   M3_ComponentLL *thisComponent;
00141   M3_SubcomponentLL *thisSubcomponent;
00142 
00143   size_t thisStoreSize;
00144   void *storeSpace;
00145   static int64_t diskBufferSize = -1;
00146   char *tempPtr;
00147 
00148   if( diskBufferSize == -1 )
00149   {
00150     tempPtr = getenv("M3_DISK_BUFFER_SIZE");
00151     if( tempPtr )
00152       diskBufferSize = strtoll( tempPtr, NULL, 10);
00153     else
00154       diskBufferSize = M3_DISK_BUFFER_SIZE;
00155   }
00156 
00157   /* Initialize the storeSize to zero.  */
00158   todCache->storeSize = 0;
00159   *storeSize = 0;
00160 
00161   /* Initialize the GCP cache from the request interval list. */
00162   if( todCache->useGCPcache )
00163   {
00164     timeIntervalList = NULL;
00165     for( thisGCPgroup = runConfig->GCPointingGroupList; 
00166          thisGCPgroup;
00167          thisGCPgroup = thisGCPgroup->next )
00168     {
00169       /* Go through the request intervals.  */  
00170       for( thisRequest = todCache->todRequestList; thisRequest; thisRequest = thisRequest->next )
00171       {
00172         M3_DataSetLL_GetGCPointingGroupNode( thisRequest->dataSetNode, &thatGCPgroup );
00173         if( thisGCPgroup == thatGCPgroup )
00174         {
00175           /* Convert the sample interval list into a time interval list for gcp initilization. */
00176           M3_DataSetLL_SampleIntervalToTimeInterval(thisRequest->dataSetNode, thisRequest->sampleInterval, &(thisTimeInterval));
00177           M3_TimeIntervalLL_InsertInterval( &timeIntervalList, thisTimeInterval);
00178         }
00179       }
00180       if( timeIntervalList )
00181       {
00182         /* Initialize GCP with the list just generated. */
00183         M3_GCPointingGroupLL_GetStoreSize( thisGCPgroup, timeIntervalList, &thisStoreSize );
00184         
00185         /* Allocate memory in the cache structure, and use it for GCP init.  */
00186         M3_MallocRecordLL_AppendToList(&(todCache->mallocRecordList), thisStoreSize, &storeSpace );
00187         M3_GCPointingGroupLL_InitializeStore( thisGCPgroup, timeIntervalList, storeSpace );
00188     
00189         M3_TimeIntervalLL_DestroyList( timeIntervalList );
00190         timeIntervalList = NULL;
00191       }
00192     }
00193   }
00194   
00195   /* Initialize scan map cache. */
00196   /* Make sure that simulated data exists*/
00197   cacheMap = 0;
00198   for( thisDataSet = runConfig->dataSetList; thisDataSet; thisDataSet = thisDataSet->next )
00199     for( thisComponent = thisDataSet->componentList; thisComponent; thisComponent = thisComponent->next )
00200       for( thisSubcomponent = thisComponent->subcomponentList; thisSubcomponent; thisSubcomponent = thisSubcomponent->next )
00201         if( thisSubcomponent->simType == M3_MAPSCAN_SIM_TYPE )
00202         {
00203           cacheMap = 1;
00204           break;
00205         }
00206 
00207   if( todCache->useScanMapCache && cacheMap )
00208   {
00209     /* Create a short cut to the pixel conversion structure.  */
00210     pixelConvert = &(runConfig->pixelConvert);
00211 
00212     /* Figure out the total number of pixels in all of the classes (not just those that were observed) */
00213     /* We will create a bit array which will keep track of which pixels are observed.  */
00214     M3_RunConfigStruct_SumNumClassPixels( runConfig, &i );
00215     bitArray.numEl = i;
00216     pixelConvert->numGlobalPix = i; 
00217 
00218     /* Determine if the total number of pixels is small enough that we should 
00219        store an indexed lookup table rather than requiring a binary search 
00220        to convert from global pixel index to observed pixel index.  
00221        This uses M3_DISK_BUFFER_SIZE as the measureing stick for determining 
00222        what is "small enough".  This may not be the best solution.  */
00223     if(pixelConvert->numGlobalPix*sizeof(int32_t) < diskBufferSize )
00224       pixelConvert->useFullLookup = 1;
00225     else
00226       pixelConvert->useFullLookup = 0;
00227   
00228     /* Allocate the bit array of length the number of global pixles 
00229        for deteriming observed pixels.  */
00230     bitArray.array = (unsigned char *)calloc(bitArray.numEl/8 + ( bitArray.numEl%8 ? 1 : 0 ), 1 );
00231     M3_ErrorCheck(-1, "M3_TODcacheStruct_GetSize() bit array of global pixels", (bitArray.array?1:0), M3_EFLAG_MALLOC_FSTRING );
00232 
00233     /* Now that we have initialized the GCP we can figure out which pixels were observed.*/
00234     /* requestInterval will be a list with only one element, so set next to NULL. */
00235     requestInterval.next = NULL;
00236     for( thisRequest = todCache->todRequestList; thisRequest; thisRequest = thisRequest->next )
00237     {    
00238       /* Flip bits of observed pixels. */
00239       requestInterval.interval = thisRequest->sampleInterval;
00240       M3_DataSetLL_AugmentHitBits( thisRequest->dataSetNode, runConfig->pixelClassList, &requestInterval, &bitArray, 0);
00241     }
00242 
00243     /* Figure out the total number of observed pixels.  */
00244     M3_BitArray_SumBits( &bitArray, &numHitPixel );
00245     pixelConvert->myNumPix = numHitPixel;
00246     
00247     /* Allocate space for the index array for the map that will be scanned.  */
00248     M3_MallocRecordLL_AppendToList( &(todCache->mallocRecordList), sizeof(int32_t)*numHitPixel, (void **)(&(pixelConvert->myPixToGlobalPix)) );
00249     M3_ErrorCheck(-1, "M3_TODcacheStruct_Initialize()", (pixelConvert->myPixToGlobalPix ? 1:0), M3_EFLAG_MALLOC_FSTRING );
00250 
00251     if( pixelConvert->useFullLookup )
00252     {
00253       M3_MallocRecordLL_AppendToList( &(todCache->mallocRecordList), sizeof(int32_t)*pixelConvert->numGlobalPix, (void **)(&(pixelConvert->globalPixToMyPix)) );
00254       M3_ErrorCheck(-1, "M3_TODcacheStruct_Initialize()", (pixelConvert->globalPixToMyPix ? 1:0), M3_EFLAG_MALLOC_FSTRING );  
00255     }
00256 
00257     /* Create lookup table from bit array.  */
00258     j = 0;
00259     for( i = 0; i < pixelConvert->numGlobalPix; i++ )
00260       if( M3_BitArray_GetBit( &bitArray, i ) )
00261       {
00262         pixelConvert->myPixToGlobalPix[j] = i;
00263         if( pixelConvert->useFullLookup )
00264           pixelConvert->globalPixToMyPix[i] = j;
00265         j++;
00266       }
00267     /* Free the bitArray, we no longer need it.  */
00268     free(bitArray.array);
00269 
00270     /* Find the largest pixel class index for classOffset array size */
00271     for( i = 0, M3_RunConfigStruct_GetPixelClassRoot( runConfig, &thisPixelClass );
00272          thisPixelClass;
00273          i++, M3_PixelClassLL_GetNextNodeInList(&thisPixelClass));
00274     pixelConvert->numPixelClass = i;
00275 
00276     /* Allocate classOffset array */
00277     M3_MallocRecordLL_AppendToList( &(todCache->mallocRecordList), sizeof(int32_t)*(pixelConvert->numPixelClass+1), (void **)(&(pixelConvert->classOffset)) );
00278     M3_ErrorCheck(-1, "M3_TODcacheStruct_Initialize()", (pixelConvert->classOffset ? 1 : 0), M3_EFLAG_MALLOC_FSTRING );
00279 
00280     i = 0;
00281     for( j = 0, M3_RunConfigStruct_GetPixelClassRoot( runConfig, &thisPixelClass );
00282          thisPixelClass;
00283          j++, M3_PixelClassLL_GetNextNodeInList(&thisPixelClass))
00284     {
00285       pixelConvert->classOffset[j] = i;
00286       M3_PixelClassLL_GetNumPixelInClass( thisPixelClass,&k );
00287       i += k;
00288     }
00289     pixelConvert->classOffset[j] = i;
00290 
00291     /* Allocate space for scan map.  */
00292     M3_MallocRecordLL_AppendToList( &(todCache->mallocRecordList), sizeof(M3_MapEl)*pixelConvert->myNumPix, (void **)(&(pixelConvert->mapSimStore)));
00293     M3_ErrorCheck(-1, "M3_TODcacheStruct_Initialize()", (pixelConvert->mapSimStore ? 1:0),M3_EFLAG_DEFAULT ); 
00294 
00295     /* Read the partial maps into memory.  */
00296     mapPtr = pixelConvert->mapSimStore;
00297     /* i is the index for the pixel classes.  */
00298     /* j is the index for myPixels */
00299     /* k keeps track of the number of observed pixels in each class.  */
00300     j = 0;
00301     for( i = 0, M3_RunConfigStruct_GetPixelClassRoot( runConfig, &thisPixelClass );
00302          thisPixelClass;
00303          i++, M3_PixelClassLL_GetNextNodeInList(&thisPixelClass))
00304     {
00305       k = 0;
00306       while( j < pixelConvert->myNumPix && pixelConvert->myPixToGlobalPix[j] < pixelConvert->classOffset[i+1] )
00307       {
00308         pixelConvert->mapSimStore[j].pixel = pixelConvert->myPixToGlobalPix[j] - pixelConvert->classOffset[i];
00309         j++;
00310         k++;
00311       }
00312       M3_ProfileStart( 193, "Map reading inside cache initialization");
00313 #ifdef USE_MPI
00314       M3_File_ReadDataMPI( thisPixelClass->mapFile, &k, mapPtr, MPI_COMM_WORLD );
00315 #else
00316       M3_PixelClassLL_GetIndexedMap( thisPixelClass, k, mapPtr );
00317 #endif
00318       M3_ProfileStop( 193 );
00319       mapPtr += k;
00320     }
00321 
00322     for( j = 0; j < pixelConvert->myNumPix; j++ )
00323       pixelConvert->mapSimStore[j].pixel = pixelConvert->myPixToGlobalPix[j];
00324   }
00325 
00326   /* Calculate the size of the cache. */
00327   todCache->storeSize = 0;
00328   for( thisRecord = todCache->mallocRecordList; 
00329        thisRecord;
00330        thisRecord = thisRecord->next )
00331     todCache->storeSize += thisRecord->size;
00332 
00333   *storeSize = todCache->storeSize;
00334 
00335   return(M3_EFLAG_NONE);
00336 }
00337 
00338 int M3_TODcacheStruct_Destroy( M3_TODcacheStruct *todCache )
00339 {
00340   M3_TODrequestLL *thisRequest, *thatRequest;
00341   M3_PointingClassLL *thisPointingClass;
00342 
00343   if( todCache == NULL )
00344     return( M3_EFLAG_NONE );
00345 
00346   if( todCache->todRequestList == NULL )
00347     return(M3_EFLAG_NONE);
00348   
00349   if( todCache->useScanMapCache )
00350   {
00351     memset( &(todCache->todRequestList->dataSetNode->runConfigNode->pixelConvert), 0, sizeof(M3_PixelConvertStruct));
00352   }
00353 
00354   if( todCache->useGCPcache )
00355   {
00356     thisRequest = todCache->todRequestList;
00357     while( thisRequest )
00358     {
00359       for( thisPointingClass = thisRequest->dataSetNode->pointingClassList; thisPointingClass; thisPointingClass = thisPointingClass->next )
00360         if( thisPointingClass->subclassList )
00361           if( thisPointingClass->subclassList->GCPointingGroupNode )
00362           {
00363             thisPointingClass->subclassList->GCPointingGroupNode->GCPointingStoreList = NULL;
00364             thisPointingClass->subclassList->GCPointingGroupNode->auxStore = NULL;
00365           }
00366             
00367       thisRequest = thisRequest->next; 
00368     }
00369   }
00370 
00371   M3_MallocRecordLL_Destroy( todCache->mallocRecordList );
00372   todCache->todRequestList = NULL;
00373   todCache->mallocRecordList = NULL;
00374  
00375   return( M3_EFLAG_NONE );
00376 }
00377  

Generated on Mon Nov 24 10:05:11 2008 for M3 by  doxygen 1.5.3-20071008