Commit 61213cd5 authored by Uwe Schulzweida's avatar Uwe Schulzweida
Browse files

model.c: update from cdi-pio

parent 4b52d2dd
......@@ -5,6 +5,10 @@
#include "dmemory.h"
#include "cdi.h"
#include "stream_int.h"
#include "pio_util.h"
#include "resource_handle.h"
#include "pio_rpc.h"
#include "namespace.h"
#undef UNDEFID
#define UNDEFID -1
......@@ -16,8 +20,8 @@ int COSMO = UNDEFID;
typedef struct
{
int self;
int used;
int instID;
int used;
int instID;
int modelgribID;
char *name;
}
......@@ -25,257 +29,125 @@ model_t;
static int MODEL_Debug = 0; /* If set to 1, debugging */
static int * modelInitializedNsp;
static int _model_max = MAX_MODELS;
static void modelInit(void);
static void model_initialize(void);
static int _model_init = FALSE;
#if defined (HAVE_LIBPTHREAD)
# include <pthread.h>
static pthread_once_t _model_init_thread = PTHREAD_ONCE_INIT;
static pthread_mutex_t _model_mutex;
# define MODEL_LOCK pthread_mutex_lock(&_model_mutex);
# define MODEL_UNLOCK pthread_mutex_unlock(&_model_mutex);
# define MODEL_INIT \
if ( _model_init == FALSE ) pthread_once(&_model_init_thread, model_initialize);
#else
# define MODEL_LOCK
# define MODEL_UNLOCK
# define MODEL_INIT \
if ( _model_init == FALSE ) model_initialize();
static int modelCompareP ( void * modelptr1, void * modelptr2 );
static void modelDestroyP ( void * modelptr );
static void modelPrintP ( void * modelptr, FILE * fp );
#ifdef USE_MPI
static int modelGetSizeP ( void * modelptr, MPI_Comm comm );
static void modelPackP ( void * modelptr, void * buff, int size,
int *position, MPI_Comm comm);
static int modelTxCode ( void );
#endif
typedef struct _modelPtrToIdx {
int idx;
model_t *ptr;
struct _modelPtrToIdx *next;
} modelPtrToIdx;
static modelPtrToIdx *_modelList = NULL;
static modelPtrToIdx *_modelAvail = NULL;
static
void model_list_new(void)
{
assert(_modelList == NULL);
_modelList = (modelPtrToIdx *) malloc(_model_max*sizeof(modelPtrToIdx));
}
static
void model_list_delete(void)
{
if ( _modelList ) free(_modelList);
}
static
void model_init_pointer(void)
{
int i;
for ( i = 0; i < _model_max; i++ )
{
_modelList[i].next = _modelList + i + 1;
_modelList[i].idx = i;
_modelList[i].ptr = 0;
}
_modelList[_model_max-1].next = 0;
_modelAvail = _modelList;
}
static
model_t *model_to_pointer(int idx)
{
model_t *modelptr = NULL;
MODEL_INIT
if ( idx >= 0 && idx < _model_max )
{
MODEL_LOCK
modelptr = _modelList[idx].ptr;
MODEL_UNLOCK
}
else
Error("model index %d undefined!", idx);
return (modelptr);
}
/* Create an index from a pointer */
static
int model_from_pointer(model_t *ptr)
{
int idx = -1;
modelPtrToIdx *newptr;
if ( ptr )
{
MODEL_LOCK
if ( _modelAvail )
{
newptr = _modelAvail;
_modelAvail = _modelAvail->next;
newptr->next = 0;
idx = newptr->idx;
newptr->ptr = ptr;
if ( MODEL_Debug )
Message("Pointer %p has idx %d from model list", ptr, idx);
}
else
Warning("Too many open models (limit is %d)!", _model_max);
MODEL_UNLOCK
}
else
Error("Internal problem (pointer %p undefined)", ptr);
return (idx);
}
resOps modelOps = { modelCompareP, modelDestroyP, modelPrintP
#ifdef USE_MPI
, modelGetSizeP, modelPackP, modelTxCode
#endif
};
static
void model_init_entry(model_t *modelptr)
void modelDefaultValue ( model_t *modelptr )
{
modelptr->self = model_from_pointer(modelptr);
modelptr->used = 1;
modelptr->self = UNDEFID;
modelptr->used = 0;
modelptr->instID = UNDEFID;
modelptr->modelgribID = UNDEFID;
modelptr->name = NULL;
}
static
model_t *model_new_entry(void)
model_t *modelNewEntry ( void )
{
model_t *modelptr;
modelptr = (model_t *) malloc(sizeof(model_t));
if ( modelptr ) model_init_entry(modelptr);
modelptr = (model_t *) xmalloc(sizeof(model_t));
modelDefaultValue ( modelptr );
modelptr->self = reshPut (( void * ) modelptr, &modelOps );
modelptr->used = 1;
return (modelptr);
}
static
void model_delete_entry(model_t *modelptr)
{
int idx;
idx = modelptr->self;
MODEL_LOCK
free(modelptr);
_modelList[idx].next = _modelAvail;
_modelList[idx].ptr = 0;
_modelAvail = &_modelList[idx];
MODEL_UNLOCK
if ( MODEL_Debug )
Message("Removed idx %d from model list", idx);
}
int modelDef(int instID, int modelgribID, const char *name);
static
void model_defaults(void)
void modelDefaultEntries ( void )
{
int instID;
int instID, i;
cdiResH resH[10];
instID = institutInq( 0, 0, "ECMWF", NULL);
/* (void) modelDef(instID, 131, "ERA15"); */
/* (void) modelDef(instID, 199, "ERA40"); */
instID = institutInq( 0, 0, "MPIMET", NULL);
ECHAM5 = modelDef(instID, 64, "ECHAM5.4");
(void) modelDef(instID, 63, "ECHAM5.3");
(void) modelDef(instID, 62, "ECHAM5.2");
(void) modelDef(instID, 61, "ECHAM5.1");
resH[0] = ECHAM5 = modelDef(instID, 64, "ECHAM5.4");
resH[1] = modelDef(instID, 63, "ECHAM5.3");
resH[2] = modelDef(instID, 62, "ECHAM5.2");
resH[3] = modelDef(instID, 61, "ECHAM5.1");
instID = institutInq( 98, 255, "MPIMET", NULL);
(void) modelDef(instID, 60, "ECHAM5.0");
ECHAM4 = modelDef(instID, 50, "ECHAM4");
(void) modelDef(instID, 110, "MPIOM1");
resH[4] = modelDef(instID, 60, "ECHAM5.0");
resH[5] = ECHAM4 = modelDef(instID, 50, "ECHAM4");
resH[6] = modelDef(instID, 110, "MPIOM1");
instID = institutInq( 0, 0, "DWD", NULL);
(void) modelDef(instID, 149, "GME");
resH[7] = modelDef(instID, 149, "GME");
instID = institutInq( 0, 0, "MCH", NULL);
//(void) = modelDef(instID, 137, "COSMO");
COSMO = modelDef(instID, 255, "COSMO");
resH[8] = COSMO = modelDef(instID, 255, "COSMO");
instID = institutInq( 0, 1, "NCEP", NULL);
(void) modelDef(instID, 80, "T62L28MRF");
resH[9] = modelDef(instID, 80, "T62L28MRF");
if ( ! namespaceHasLocalFile ( namespaceGetActive ()))
for ( i = 0; i < 10 ; i++ )
reshSetStatus ( resH[i], &modelOps, SUSPENDED );
}
static
void model_initialize(void)
void modelFinalize ( void )
{
char *env;
#if defined (HAVE_LIBPTHREAD)
/* initialize global API mutex lock */
pthread_mutex_init(&_model_mutex, NULL);
#endif
env = getenv("MODEL_DEBUG");
if ( env ) MODEL_Debug = atoi(env);
model_list_new();
atexit(model_list_delete);
MODEL_LOCK
model_init_pointer();
MODEL_UNLOCK
_model_init = TRUE;
model_defaults();
free ( modelInitializedNsp );
}
static
void model_check_ptr(const char *caller, model_t *modelptr)
void modelInit(void)
{
if ( modelptr == NULL )
Errorc("model undefined!");
}
static int modelInitialized = 0;
int nsp, nspc;
char *env;
int modelSize(void)
{
int modelsize = 0;
int i;
nspc = namespaceGetNumber ();
MODEL_INIT
MODEL_LOCK
for ( i = 0; i < _model_max; i++ )
if ( _modelList[i].ptr ) modelsize++;
if ( !modelInitialized )
{
modelInitialized = 1;
modelInitializedNsp = xcalloc ( 1, nspc * sizeof ( int ));
atexit ( modelFinalize );
env = getenv("MODEL_DEBUG");
if ( env ) MODEL_Debug = atoi(env);
}
MODEL_UNLOCK
nsp = namespaceGetActive ();
if ( modelInitializedNsp[nsp] ) return;
modelInitializedNsp[nsp] = 1;
modelDefaultEntries ();
}
return (modelsize);
int modelSize ( void )
{
return reshCountType ( &modelOps );
}
......@@ -284,45 +156,51 @@ int modelInq(int instID, int modelgribID, char *name)
int modelID = UNDEFID;
size_t len;
int found;
int model_size;
int modelCount;
model_t *modelptr;
int i, * modelResHs;
MODEL_INIT
modelInit ();
model_size = modelSize();
modelCount = modelSize();
modelResHs = xmalloc ( modelCount * sizeof ( int ));
reshGetResHListOfType ( modelCount, modelResHs, &modelOps );
for( modelID = 0; modelID < model_size; modelID++ )
for( i = 0; i < modelCount; i++ )
{
modelptr = model_to_pointer(modelID);
modelID = modelResHs[i];
modelptr = ( model_t * ) reshGetVal ( modelID, &modelOps );
if ( modelptr->used )
{
if ( name )
{
found = 1;
if ( instID != -1 && modelptr->instID != instID ) found = 0;
if ( modelgribID != 0 && modelptr->modelgribID != modelgribID ) found = 0;
if ( found )
{
if ( modelptr->name )
{
len = strlen(modelptr->name);
if ( memcmp(modelptr->name, name, len) == 0 ) break;
len = strlen(name);
if ( memcmp(modelptr->name, name, len) == 0 ) break;
}
}
}
else
{
if ( modelptr->instID == instID &&
modelptr->modelgribID == modelgribID ) break;
}
}
{
if ( name )
{
found = 1;
if ( instID != -1 && modelptr->instID != instID ) found = 0;
if ( modelgribID != 0 && modelptr->modelgribID != modelgribID ) found = 0;
if ( found )
{
if ( modelptr->name )
{
len = strlen(modelptr->name);
if ( memcmp(modelptr->name, name, len) == 0 ) break;
len = strlen(name);
if ( memcmp(modelptr->name, name, len) == 0 ) break;
}
}
}
else
{
if ( modelptr->instID == instID &&
modelptr->modelgribID == modelgribID ) break;
}
}
}
if ( modelID == model_size ) modelID = UNDEFID;
if ( modelID == modelCount ) modelID = UNDEFID;
if ( modelResHs ) free ( modelResHs );
return (modelID);
}
......@@ -330,90 +208,140 @@ int modelInq(int instID, int modelgribID, char *name)
int modelDef(int instID, int modelgribID, const char *name)
{
int modelID = UNDEFID;
model_t *modelptr;
MODEL_INIT
/*
modelID = modelInq(instID, modelgribID, name);
*/
if ( modelID == UNDEFID )
{
modelptr = model_new_entry();
if ( ! modelptr ) Error("No memory");
modelInit ();
modelID = modelptr->self;
modelptr = modelNewEntry();
modelptr->instID = instID;
modelptr->modelgribID = modelgribID;
modelptr->instID = instID;
modelptr->modelgribID = modelgribID;
if ( name ) modelptr->name = strdupx(name);
if ( name ) modelptr->name = strdupx(name);
}
return (modelID);
return modelptr->self;
}
int modelInqInstitut(int modelID)
{
int instID = UNDEFID;
model_t *modelptr;
MODEL_INIT
modelInit ();
if ( modelID != UNDEFID )
{
modelptr = model_to_pointer(modelID);
modelptr = ( model_t * ) reshGetVal ( modelID, &modelOps );
model_check_ptr(__func__, modelptr);
instID = modelptr->instID;
}
return (instID);
return modelptr ? modelptr->instID : UNDEFID;
}
int modelInqGribID(int modelID)
{
int modelgribID = UNDEFID;
model_t *modelptr;
MODEL_INIT
if ( modelID != UNDEFID )
{
modelptr = model_to_pointer(modelID);
modelInit ();
model_check_ptr(__func__, modelptr);
modelgribID = modelptr->modelgribID;
}
modelptr = ( model_t * ) reshGetVal ( modelID, &modelOps );
return (modelgribID);
return modelptr ? modelptr->modelgribID : UNDEFID;
}
char *modelInqNamePtr(int modelID)
{
char *name = NULL;
model_t *modelptr;
MODEL_INIT
modelInit ();
if ( modelID != UNDEFID )
{
modelptr = model_to_pointer(modelID);
modelptr = ( model_t * ) reshGetVal ( modelID, &modelOps );
model_check_ptr(__func__, modelptr);
if ( modelptr->name )
name = modelptr->name;
}
return modelptr ? modelptr->name : NULL;
}
int modelCompareP ( void * modelptr1, void * modelptr2 )
{
return 0;
}
void modelDestroyP ( void * modelptr )
{
}
void modelPrintP ( void * modelptr, FILE * fp )
{
model_t * mp = ( model_t * ) modelptr;
if ( !mp ) return;
fprintf ( fp, "#\n");
fprintf ( fp, "# modelID %d\n", mp->self);
fprintf ( fp, "#\n");
fprintf ( fp, "self = %d\n", mp->self );
fprintf ( fp, "used = %d\n", mp->used );
fprintf ( fp, "instID = %d\n", mp->instID );
fprintf ( fp, "modelgribID = %d\n", mp->modelgribID );
fprintf ( fp, "name = %s\n", mp->name ? mp->name : "NN" );
}
#ifdef USE_MPI
return (name);
static int
modelTxCode ( void )
{
return MODEL;
}
enum {
model_nints = 4,
};
static
int modelGetSizeP ( void * modelptr, MPI_Comm comm )
{
model_t *p = modelptr;
int txsize = 0, txinc;
xmpi(MPI_Pack_size(model_nints, MPI_INT, comm, &txsize));
xmpi(MPI_Pack_size(strlen(p->name) + 1, MPI_CHAR, comm, &txinc));
txsize += txinc;
return txsize;
}
static
void modelPackP ( void * modelptr, void * buf, int size,
int *position, MPI_Comm comm )
{
model_t *p = modelptr;
int tempbuf[model_nints];
tempbuf[0] = p->self;
tempbuf[1] = p->instID;
tempbuf[2] = p->modelgribID;
tempbuf[3] = (int)strlen(p->name) + 1;
xmpi(MPI_Pack(tempbuf, model_nints, MPI_INT, buf, size, position, comm));
xmpi(MPI_Pack(p->name, tempbuf[3], MPI_CHAR, buf, size, position, comm));
}
int
modelUnpack(void *buf, int size, int *position, int nspTarget,
MPI_Comm comm)
{
int tempbuf[model_nints];
int modelID;
char *name;
xmpi(MPI_Unpack(buf, size, position, tempbuf, model_nints, MPI_INT, comm));
name = xmalloc(tempbuf[3]);
xmpi(MPI_Unpack(buf, size, position, name, tempbuf[3], MPI_CHAR, comm));
modelID = modelDef( namespaceAdaptKey ( tempbuf[1], nspTarget ), tempbuf[2], name);
// FIXME: this should work, once all types are transferred
//assert(modelID == tempbuf[0]);
return modelID;
}
#endif
/*
* Local Variables:
* c-file-style: "Java"
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment