/** \brief Retrieve data from the RTDB of unknown size Retrieve the data associated with the specified key from the RTDB. In this case the size of the data is not known a priory. Hence the size is retrieved from the RTDB as well, an array of the appropriate size is allocated, and the MA handle as well as the size are returned. The calling program is responsible for deallocating the memory. \param handle [Input] the RTDB handle \param name [Input] the key for the data \param ma_type [Output] the type of the data specified by one of the MA data types (see mafdecls.fh) \param nelem [Output] the number of elements of the specified type \param array [Output] the actual data retrieved \return the status of the read operation */ int rtdb_ma_get(const int handle, const char *name, int *ma_type, int *nelem, int *ma_handle) { int status; #ifdef GAGROUPS int me = GA_Nodeid(); #endif if (!verify_parallel_access()) return 0; if (handle < 0 || handle >= MAX_RTDB) { (void) fprintf(stderr, "rtdb_ma_get: handle out of range %d\n", handle); (void) fflush(stderr); return 0; } if (par_mode[handle] == INACTIVE) { (void) fprintf(stderr, "rtdb_ma_get: handle not active %d\n",handle); (void) fflush(stderr); return 0; } if (par_mode[handle] == RTDB_SEQ_MODE && parallel_mode == RTDB_PAR_MODE) { (void) fprintf(stderr, "rtdb_ma_get: seq. open and par. get\n"); (void) fflush(stderr); return 0; } if (parallel_mode == RTDB_SEQ_MODE || me == 0) status = rtdb_seq_ma_get(handle, name, ma_type, nelem, ma_handle); if (parallel_mode == RTDB_PAR_MODE) { rtdb_broadcast(TYPE_RTDB_STATUS, MT_INT, 1, (void *) &status); if (status) { void *ma_data; rtdb_broadcast(TYPE_RTDB_TYPE, MT_INT, 1, (void *) ma_type); rtdb_broadcast(TYPE_RTDB_NELEM, MT_INT, 1, (void *) nelem); if (me > 0) { Integer ma_handle_buf; Integer ma_type_buf = *ma_type; Integer nelem_buf = *nelem; if (!MA_allocate_heap(ma_type_buf, nelem_buf, name, &ma_handle_buf)) { /* Cannot just return and error here since cannot propogate the error condition to all the other processes ... exit via the TCGMSG error routine */ GA_Error("rtdb_get_ma: rtdb_get_ma: MA_alloc failed, nelem=", (Integer)nelem); } *ma_handle = (int) ma_handle_buf; } if (!MA_get_pointer((Integer) *ma_handle, &ma_data)) { GA_Error("rtdb_get_ma: rtdb_get_ma: MA_get_ptr failed, nelem=", (Integer) nelem); } rtdb_broadcast(TYPE_RTDB_ARRAY, *ma_type, *nelem, (void *) ma_data); } } return status; }
PyObject *wrap_rtdb_get(PyObject *self, PyObject *args) { int nelem, ma_type; char *name; #define MAXPTRS 2048 char *ptrs[MAXPTRS]; PyObject *returnObj = NULL; char format_char; void *array=NULL; int ma_handle; if (PyArg_ParseTuple(args, "s", &name)) { if (!rtdb_seq_ma_get(rtdb_handle, name, &ma_type, &nelem, &ma_handle)) { PyErr_SetString(NwchemError, "rtdb_ma_get failed"); return NULL; } if (!MA_get_pointer(ma_handle, &array)) { PyErr_SetString(NwchemError, "rtdb_ma_get failed"); return NULL; } // printf("name=%s ma_type=%d nelem=%d ptr=%x\n",name, ma_type, // nelem, array); switch (ma_type) { case MT_F_INT: case MT_INT : case MT_BASE + 11 : format_char = 'i'; break; case MT_F_DBL: case MT_DBL : format_char = 'd'; break; break; case MT_CHAR : format_char = 's'; break; default: PyErr_SetString(NwchemError, "rtdb_get: ma type incorrect"); (void) MA_free_heap(ma_handle); return NULL; break; } /* For character string need to build an array of pointers */ if (ma_type == MT_CHAR) { char *ptr, *next; nelem = 0; next = ptr = array; while (1) { int eos = (*ptr == 0); if ((*ptr == '\n') || (*ptr == 0)) { *ptr = 0; if (nelem >= MAXPTRS) { PyErr_SetString(PyExc_MemoryError,"rtdb_get too many strings"); (void) MA_free_heap(ma_handle); return NULL; } if (strlen(next) > 0) { ptrs[nelem] = next; nelem++; } next = ptr+1; if (eos) break; } ptr++; } } switch (format_char) { case 'i': returnObj = nwwrap_integers(nelem, array); break; case 'd': returnObj = nwwrap_doubles(nelem, array); break; case 's': returnObj = nwwrap_strings(nelem, ptrs); break; } (void) MA_free_heap(ma_handle); if (!returnObj) { PyErr_SetString(PyExc_TypeError, "rtdb_get: conversion to python object failed."); } } else { PyErr_SetString(PyExc_TypeError, "Usage: value = rtdb_get(name)"); } return returnObj; }
int main(int argc, char *argv[]) { int rtdb = -1, ma_type, nelem; char filename[256], mode[256], name[1024], date[26]; void *data; char carray[MAX_NELEM+1]; int iarray[MAX_NELEM]; double darray[MAX_NELEM]; #define N_OPTS 9 const char *opts[N_OPTS] = {"quit", "open", "close", "info", "put", "get", "first", "next", "print"}; if (!MA_init(MT_DBL, -1, -1)) exit(1); while (1) { int opt; printf("\n\n\n Interactive RTDB\n ----------------\n\n"); for (opt=0; opt<N_OPTS; opt++) printf(" %-8s %3d\n", opts[opt], opt); printf("\nEnter option number -> "); fflush(stdout); if (scanf("%d", &opt) != 1) break; switch (opt) { case 0: exit(0); break; case 1: printf("\nOpen database\n-----------\n\n"); printf("Enter filename -> "); fflush(stdout); if (scanf("%s",filename) != 1) exit(1); printf("Enter mode (new, old, unknown, empty, scratch) -> "); fflush(stdout); if (scanf("%s",mode) != 1) exit(1); if (!rtdb_seq_open(filename, mode, &rtdb)) printf("\nOpen of %s with mode %s failed\n", filename, mode); break; case 2: printf("\nClose database\n-------------\n\n"); fflush(stdout); if (rtdb < 0) printf("database is not open\n"); else { printf("Enter mode (keep, delete) -> "); fflush(stdout); if (scanf("%s",mode) != 1) exit(1); if (!rtdb_seq_close(rtdb, mode)) printf("Close of %s with mode %s failed\n", filename, mode); else rtdb = -1; } break; case 3: printf("\nInformation on entry\n--------------------\n\n"); if (rtdb < 0) printf("database is not open\n"); else { printf("Enter name -> "); fflush(stdout); if (!read_string(name, sizeof name)) exit(1); if (!rtdb_seq_get_info(rtdb, name, &ma_type, &nelem, date)) printf("Get info on \"%s\" failed\n", name); else printf("%s -> type=%s, nelem=%d, date=%s\n", name, ma_typename(ma_type), nelem, date); } break; case 4: printf("\nPut entry\n---------\n\n"); if (rtdb < 0) printf("database is not open\n"); else { printf("Enter name -> "); fflush(stdout); if (!read_string(name, sizeof name)) exit(1); printf("Enter type (int, char, double) -> "); fflush(stdout); if (scanf("%s", mode) != 1) exit(1); if (!strcmp(mode,"int")) { int i; if ((nelem = ReadNelem()) <= 0) break; ma_type = MT_INT; for (i=0; i<nelem; i++) if (scanf("%d", iarray+i) != 1) exit(1); data = (void *) iarray; } else if (!strcmp(mode, "char")) { int i; ma_type = MT_CHAR; if (!read_string(carray, MAX_NELEM)) break; nelem = strlen(carray) + 1; data = (void *) carray; } else if (!strcmp(mode, "double")) { int i; if ((nelem = ReadNelem()) <= 0) break; ma_type = MT_DBL; for (i=0; i<nelem; i++) if (scanf("%lf", darray+i) != 1) exit(1); data = (void *) darray; } else { printf("invalid type\n"); break; } if(!rtdb_seq_put(rtdb, name, ma_type, nelem, data)) printf("put %s, nelem=%d, type=%s failed", name, nelem, ma_typename(ma_type)); fflush(stdout); } break; case 5: printf("\nGet entry\n---------\n\n"); if (rtdb < 0) printf("database is not open\n"); else { int ma_handle; if(rtdb_seq_ma_get(rtdb, name, &ma_type, &nelem, &ma_handle)) { ma_print(stdout, ma_type, nelem, MA_get_pointer(ma_handle, &data)); MA_free_heap(ma_handle); } else printf("Get of %s failed\n", name); } break; case 8: printf("\nPrint database\n--------------\n\n"); if (rtdb < 0) printf("database is not open\n"); else { int values; printf("Print values (0=no, 1=yes) -> "); fflush(stdout); if (scanf("%d", &values) != 1) exit(1); rtdb_seq_print(rtdb, values); } break; default: break; } } return 0; }