00001
00008
00009
00010
00011
00012 #include <stdlib.h>
00013 #include <stdio.h>
00014 #include <time.h>
00015 #include <string.h>
00016 #include <sys/types.h>
00017 #include <sys/stat.h>
00018 #include <fcntl.h>
00019
00020 #include "portability.h"
00021 #include "problem.h"
00022 #include "comm_encode.h"
00023 #include "utility.h"
00024 #include "proxylib.h"
00025
00026 static int
00027 gs_free_problem_common(gs_problem_t *, int);
00028
00030 char *gs_inout[] = {
00031 "in",
00032 "inout",
00033 "out",
00034 "workspace",
00035 "varout",
00036 "bad inout"
00037 };
00038
00040 char *gs_c_datatype[] = {
00041 "int",
00042 "float",
00043 "double",
00044 "gs_scomplex",
00045 "gs_dcomplex",
00046 "char",
00047 "bad data type"
00048 };
00049
00051 char *gs_objecttype[] = {
00052 "scalar",
00053 "vector",
00054 "matrix",
00055 "sparsematrix",
00056 "file",
00057 "packedfile",
00058 "bad object type"
00059 };
00060
00062 char *gs_probtype[] = {
00063 "subroutine",
00064 "function",
00065 "bad prob type"
00066 };
00067
00069 char *gs_const[] = {
00070 "10",
00071 "5.0",
00072 "10.0",
00073 "__scval",
00074 "__dcval",
00075 "'n'",
00076 "bad const"
00077 };
00078
00079 char *gs_service_error[] = {
00080 "Unused error code",
00081 "No error",
00082 "Unused error code",
00083 "malloc failed",
00084 "Error loading service XML file",
00085 "Error loading server info XML file",
00086 "Error creating problem XML for request",
00087 "Could not open data file obtain output",
00088 "Could not create data file to save output",
00089 "Could not create completion file",
00090 "Could not encode problem into XML",
00091 "Could not get current working directory",
00092 "Error creating request id",
00093 "Could not create request subdirectory",
00094 "Could not chdir to request subdirectory",
00095 "Failed to set up signal handler",
00096 "Failed to fork service process",
00097 "Failed to wait for service process",
00098 "Service process did not terminate properly",
00099 "I/O Error transferring args",
00100 "Error executing service (likely missing)",
00101 "Error reading problem file from disk",
00102 "Error restoring arg structures from disk",
00103 "Specified request ID not found on server",
00104 "Request subdirectory removed while waiting",
00105 "Request not finished yet",
00106 "Invalid request ID (can't parse pid)",
00107 "Could not kill service process",
00108 "Invalid blocking/nonblocking specifier tag",
00109 "Server has too many jobs running now",
00110 "Only accepts jobs during a restricted time",
00111 "Unsupported batch mode",
00112 "Could not obtain lock on file",
00113 "Could not release lock on file",
00114 "Unspecified server error"
00115 };
00116
00128 enum inout
00129 gs_parse_inout(const char *str)
00130 {
00131 if(!str)
00132 return GS_BAD_INOUT;
00133
00134 if(!strcasecmp(str, gs_inout[GS_IN]))
00135 return GS_IN;
00136 if(!strcasecmp(str, gs_inout[GS_INOUT]))
00137 return GS_INOUT;
00138 if(!strcasecmp(str, gs_inout[GS_OUT]))
00139 return GS_OUT;
00140 if(!strcasecmp(str, gs_inout[GS_VAROUT]))
00141 return GS_VAROUT;
00142 if(!strcasecmp(str, gs_inout[GS_WORKSPACE]))
00143 return GS_WORKSPACE;
00144
00145 return GS_BAD_INOUT;
00146 }
00147
00158 enum datatype
00159 gs_parse_datatype(const char *str)
00160 {
00161 if(!str)
00162 return GS_BAD_DTYPE;
00163
00164 if(!strcasecmp(str, gs_c_datatype[GS_INT]))
00165 return GS_INT;
00166 if(!strcasecmp(str, gs_c_datatype[GS_FLOAT]))
00167 return GS_FLOAT;
00168 if(!strcasecmp(str, gs_c_datatype[GS_DOUBLE]))
00169 return GS_DOUBLE;
00170 if(!strcasecmp(str, gs_c_datatype[GS_SCOMPLEX]))
00171 return GS_SCOMPLEX;
00172 if(!strcasecmp(str, gs_c_datatype[GS_DCOMPLEX]))
00173 return GS_DCOMPLEX;
00174 if(!strcasecmp(str, gs_c_datatype[GS_CHAR]))
00175 return GS_CHAR;
00176
00177 return GS_BAD_DTYPE;
00178 }
00179
00190 enum objecttype
00191 gs_parse_objecttype(const char *str)
00192 {
00193 if(!str)
00194 return GS_BAD_OTYPE;
00195
00196 if(!strcasecmp(str, gs_objecttype[GS_SCALAR]))
00197 return GS_SCALAR;
00198 if(!strcasecmp(str, gs_objecttype[GS_VECTOR]))
00199 return GS_VECTOR;
00200 if(!strcasecmp(str, gs_objecttype[GS_MATRIX]))
00201 return GS_MATRIX;
00202 if(!strcasecmp(str, gs_objecttype[GS_SPARSEMATRIX]))
00203 return GS_SPARSEMATRIX;
00204 if(!strcasecmp(str, gs_objecttype[GS_FILE]))
00205 return GS_FILE;
00206 if(!strcasecmp(str, gs_objecttype[GS_PACKEDFILE]))
00207 return GS_PACKEDFILE;
00208
00209 return GS_BAD_OTYPE;
00210 }
00211
00221 enum probtype
00222 gs_parse_probtype(const char *str)
00223 {
00224 if(!str)
00225 return GS_BAD_PTYPE;
00226
00227 if(!strcasecmp(str, gs_probtype[GS_SUBROUTINE]))
00228 return GS_SUBROUTINE;
00229 if(!strcasecmp(str, gs_probtype[GS_FUNCTION]))
00230 return GS_FUNCTION;
00231
00232 return GS_BAD_PTYPE;
00233 }
00234
00250 char *
00251 gs_problem_getinfo(gs_problem_t * problem, char *type, char *defaultvalue)
00252 {
00253 gs_info_t *info;
00254
00255 if(!problem || !type)
00256 return NULL;
00257
00258 for(info = problem->infolist; info != NULL; info = info->next)
00259 if(!strcmp(info->type, type))
00260 return info->value;
00261
00262 return defaultvalue;
00263 }
00264
00271 void
00272 gs_infolist_dump(gs_info_t * infolist)
00273 {
00274 gs_info_t *p;
00275
00276 if(!infolist)
00277 return;
00278
00279 printf("Problem attributes:\n");
00280 for(p = infolist; p != NULL; p = p->next)
00281 printf(" %s: %s\n", p->type, p->value);
00282 }
00283
00290 void
00291 gs_arg_dump(gs_argument_t * arg)
00292 {
00293 if(!arg) {
00294 printf("NULL arg\n");
00295 return;
00296 }
00297
00298 printf(" Argument Name: %s\n", arg->name);
00299 printf(" Description: %s\n", arg->description);
00300 printf(" In/out mode: %s\n", gs_inout[arg->inout]);
00301 printf(" Data type: %s\n", gs_c_datatype[arg->datatype]);
00302 printf(" Object type: %s\n", gs_objecttype[arg->objecttype]);
00303 printf(" Row size expr: %s\n", arg->rowexp);
00304 printf(" Column size expr: %s\n", arg->colexp);
00305 }
00306
00313 void
00314 gs_arglist_dump(gs_argument_t * arglist)
00315 {
00316 gs_argument_t *p;
00317 int i=0;
00318
00319 for(p = arglist; p != NULL; p = p->next) {
00320 printf("Argument %d:\n", i++);
00321 gs_arg_dump(p);
00322 printf("\n");
00323 }
00324 }
00325
00332 void
00333 gs_problem_dump(gs_problem_t * problem)
00334 {
00335 if(!problem) {
00336 printf("NULL problem\n");
00337 return;
00338 }
00339
00340 printf("\n");
00341 printf("Problem Name: %s\n", problem->name);
00342 printf("\n");
00343 printf("Problem Description:\n %s\n", problem->description);
00344 printf("\n");
00345 gs_arglist_dump(problem->arglist);
00346 gs_infolist_dump(problem->infolist);
00347 }
00348
00355 void
00356 gs_problemlist_dump(gs_problem_t * problem)
00357 {
00358 gs_problem_t *p;
00359
00360 printf("<problemlist>\n");
00361 for(p = problem; p != NULL; p = p->next)
00362 gs_problem_dump(p);
00363 printf("</problemlist>\n");
00364 }
00365
00380 char *
00381 gs_problem_prototype(gs_problem_t * problem)
00382 {
00383 char *s, *stmp = NULL;
00384 gs_argument_t *arg = NULL;
00385
00386 if(!problem) return NULL;
00387
00388 s = strdup("");
00389 for(arg = problem->arglist; arg != NULL; arg = arg->next) {
00390 stmp = dstring_sprintf("inout=\"%s\" datatype=\"%s\" \
00391 objecttype=\"%s\" rowexp=\"%s\" colexp=\"%s\" \n",
00392 gs_inout[arg->inout], gs_c_datatype[arg->datatype],
00393 gs_objecttype[arg->objecttype], arg->rowexp, arg->colexp);
00394 s = dstring_append_free(s, stmp);
00395 }
00396
00397 return s;
00398 }
00399
00412 int
00413 gs_dup_problem(gs_problem_t * dest, gs_problem_t * src)
00414 {
00415 gs_argument_t *src_arg, *dest_arg;
00416 char *msg = NULL;
00417
00418 if(!dest || !src)
00419 return -1;
00420
00421
00422
00423
00424 if(gs_encode_problem(&msg, src) < 0)
00425 return -1;
00426
00427 if(gs_decode_problem(msg, dest) < 0) {
00428 if(msg)
00429 free(msg);
00430 return -1;
00431 }
00432
00433 free(msg);
00434
00435
00436
00437
00438 src_arg = src->arglist;
00439 dest_arg = dest->arglist;
00440
00441 while(src_arg) {
00442 dest_arg->rows = src_arg->rows;
00443 dest_arg->cols = src_arg->cols;
00444 dest_arg->data = src_arg->data;
00445
00446 src_arg = src_arg->next;
00447 dest_arg = dest_arg->next;
00448 }
00449
00450 dest->major = src->major;
00451 dest->work = NULL;
00452 dest->worksize = 0;
00453
00454 return 0;
00455 }
00456
00470 int
00471 gs_create_request_id(char *template)
00472 {
00473 static char alphabet[] =
00474 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
00475 char *p;
00476 unsigned int seed;
00477
00478 if(!template)
00479 return -1;
00480
00481 #ifdef WIN32
00482 seed = (unsigned)time(NULL);
00483 #else
00484 {
00485 struct timeval tv;
00486 gettimeofday(&tv, NULL);
00487 seed = tv.tv_usec;
00488 }
00489 #endif
00490 srand(seed);
00491
00492 p = template;
00493
00494 while(*p) {
00495 if(*p == 'X')
00496 *p = alphabet[rand() % 62];
00497 p++;
00498 }
00499
00500 return 0;
00501 }
00502
00515 int
00516 gs_read_problem_from_file(char *fname, gs_problem_t * problem)
00517 {
00518 char *problemstring = NULL;
00519
00520 if(!fname || !problem)
00521 return -1;
00522
00523 if(gs_get_contents_of_file(fname, &problemstring) < 0)
00524 return -1;
00525
00526
00527 if(gs_decode_problem(problemstring, problem) < 0) {
00528 free(problemstring);
00529 return -1;
00530 }
00531
00532 free(problemstring);
00533
00534 return 0;
00535 }
00536
00549 int
00550 gs_read_server_from_file(char *fname, gs_server_t * server)
00551 {
00552 char *serverstring = NULL;
00553
00554 if(!fname || !server)
00555 return -1;
00556
00557 if(gs_get_contents_of_file(fname, &serverstring) < 0)
00558 return -1;
00559
00560
00561 if(gs_decode_server(serverstring, server) < 0) {
00562 free(serverstring);
00563 return -1;
00564 }
00565
00566 free(serverstring);
00567
00568 return 0;
00569 }
00570
00580 int
00581 gs_free_problem(gs_problem_t *problem)
00582 {
00583 return gs_free_problem_common(problem, FALSE);
00584 }
00585
00597 int
00598 gs_free_problem_and_data(gs_problem_t *problem)
00599 {
00600 return gs_free_problem_common(problem, TRUE);
00601 }
00602
00614 static int
00615 gs_free_problem_common(gs_problem_t *problem, int free_data)
00616 {
00617 gs_problem_t *tmpp, *prev;
00618
00619 if(!problem)
00620 return -1;
00621
00622 tmpp = problem;
00623 while(tmpp) {
00624 if(tmpp->name)
00625 free(tmpp->name);
00626 if(tmpp->description)
00627 free(tmpp->description);
00628 if(tmpp->callsig)
00629 free(tmpp->callsig);
00630 if(tmpp->work)
00631 free(tmpp->work);
00632
00633 gs_free_arglist(tmpp->arglist, free_data);
00634 gs_free_infolist(tmpp->infolist);
00635 prev = tmpp;
00636 tmpp = tmpp->next;
00637 free(prev);
00638 }
00639 return 0;
00640 }
00641
00642 int
00643 gs_free_enumlist(gs_arg_enum_t *elist)
00644 {
00645 gs_arg_enum_t *tmpe;
00646
00647 if(!elist)
00648 return -1;
00649
00650 tmpe = elist;
00651 while(tmpe) {
00652 if(tmpe->val)
00653 free(tmpe->val);
00654 tmpe = tmpe->next;
00655 }
00656
00657
00658
00659
00660
00661 free(elist);
00662
00663 return 0;
00664 }
00665
00676 int
00677 gs_free_arglist(gs_argument_t * arg, int free_data)
00678 {
00679 gs_argument_t *tmpa, *prev;
00680
00681 if(!arg)
00682 return -1;
00683
00684 tmpa = arg;
00685 while(tmpa) {
00686 if(tmpa->name)
00687 free(tmpa->name);
00688 if(tmpa->description)
00689 free(tmpa->description);
00690 if(tmpa->rowexp)
00691 free(tmpa->rowexp);
00692 if(tmpa->colexp)
00693 free(tmpa->colexp);
00694 if(tmpa->sparse_attr.nnzexp)
00695 free(tmpa->sparse_attr.nnzexp);
00696 if(tmpa->sparse_attr.indices)
00697 free(tmpa->sparse_attr.indices);
00698 if(tmpa->sparse_attr.pointer)
00699 free(tmpa->sparse_attr.pointer);
00700
00701 if(free_data && tmpa->data)
00702 free(tmpa->data);
00703
00704 gs_free_enumlist(tmpa->arg_enum);
00705
00706 prev = tmpa;
00707 tmpa = tmpa->next;
00708 free(prev);
00709 }
00710
00711 return 0;
00712 }
00713
00714
00715 #ifdef GS_SMART_GRIDSOLVE
00716
00717 int
00718 gs_smart_free_arg(gs_argument_t * arg, int free_data)
00719 {
00720 int i;
00721 if(!arg)
00722 return -1;
00723
00724 if(arg->name)
00725 free(arg->name);
00726 if(arg->description)
00727 free(arg->description);
00728 if(arg->rowexp)
00729 free(arg->rowexp);
00730 if(arg->colexp)
00731 free(arg->colexp);
00732 if(arg->sparse_attr.nnzexp)
00733 free(arg->sparse_attr.nnzexp);
00734 if(arg->sparse_attr.indices)
00735 free(arg->sparse_attr.indices);
00736 if(arg->sparse_attr.pointer)
00737 free(arg->sparse_attr.pointer);
00738 if(arg->input_arg_file)
00739 free(arg->input_arg_file);
00740 if(arg->output_arg_file)
00741 free(arg->output_arg_file);
00742
00743 for(i=0;i<arg->input_nb_dest_servers;i++){
00744 if(arg->enc_input_dest_servers[i])
00745 free(arg->enc_input_dest_servers[i]);
00746 }
00747 if(arg->enc_input_dest_servers)
00748 free(arg->enc_input_dest_servers);
00749
00750 for(i=0;i<arg->output_nb_dest_servers;i++){
00751 if(arg->enc_output_dest_servers[i])
00752 free(arg->enc_output_dest_servers[i]);
00753 }
00754 if(arg->enc_output_dest_servers)
00755 free(arg->enc_output_dest_servers);
00756
00757 if(free_data && arg->data)
00758 free(arg->data);
00759
00760 gs_free_enumlist(arg->arg_enum);
00761
00762 free(arg);
00763
00764 return 0;
00765 }
00766
00767 #endif
00768
00769
00770
00780 int
00781 gs_free_infolist(gs_info_t * info)
00782 {
00783 gs_info_t *tmpi, *prev;
00784
00785 if(!info)
00786 return -1;
00787
00788 tmpi = info;
00789 while(tmpi) {
00790 if(tmpi->type)
00791 free(tmpi->type);
00792 if(tmpi->value)
00793 free(tmpi->value);
00794 prev = tmpi;
00795 tmpi = tmpi->next;
00796 free(prev);
00797 }
00798
00799 return 0;
00800 }
00801
00812 int
00813 gs_create_error_file(char *req, int err)
00814 {
00815 char *filename;
00816 FILE *error_file;
00817
00818 if(!req) return -1;
00819
00820
00821 filename = malloc(strlen(req) + 7);
00822
00823 if(!filename)
00824 return -1;
00825
00826 sprintf(filename, "%s/error", req);
00827
00828 error_file = fopen(filename, "w");
00829
00830 free(filename);
00831
00832 if(error_file) {
00833 fprintf(error_file, "%d\n", err);
00834 fclose(error_file);
00835 }
00836 else
00837 return -1;
00838
00839 return 0;
00840 }
00841
00857 int
00858 gs_create_timestamp_file(char *req, char *fname, double run_time)
00859 {
00860 char *filename;
00861 FILE *timestamp_file;
00862
00863 if(!req || !fname)
00864 return -1;
00865
00866 filename = malloc(strlen(req) + strlen(fname) + 2);
00867
00868 if(!filename)
00869 return -1;
00870
00871 sprintf(filename, "%s/%s", req, fname);
00872
00873 timestamp_file = fopen(filename, "w");
00874
00875 free(filename);
00876
00877 if(timestamp_file) {
00878 char timestr[100];
00879 struct tm *ptr;
00880 time_t tm;
00881
00882 tm = time(NULL);
00883 ptr = localtime(&tm);
00884 strftime(timestr, 100, "%a %b %d %H:%M:%S %Z %Y", ptr);
00885
00886 fprintf(timestamp_file, "%s\n", timestr);
00887 fprintf(timestamp_file, "%lf\n", run_time);
00888
00889 fclose(timestamp_file);
00890 }
00891 else
00892 return -1;
00893
00894 return 0;
00895 }
00896
00897
00913 int
00914 gs_gen_sparse_mat_common(int datatype, size_t el_size, int m, int rmin, int rmax,
00915 void **a, int **ip, int **p)
00916 {
00917 int i, ii, j, idx, nnz, *ptr, *ind;
00918 void *mat;
00919
00920 nnz = 0;
00921
00922 ptr = (int *) malloc((m+1) * sizeof(int));
00923 if(!ptr) return -1;
00924
00925 ptr[0] = 0;
00926 for(i=1;i<=m;i++) {
00927 int colsize = random() % (rmax-rmin+1) + rmin;
00928
00929 ptr[i] = ptr[i-1] + colsize;
00930
00931 nnz += colsize;
00932 }
00933
00934 ind = (int *)malloc(nnz * sizeof(int));
00935 if(!ind) return -1;
00936 mat = (void *) malloc(sizeof(double) * nnz * el_size);
00937 if(!mat) return -1;
00938
00939 ii = idx = 0;
00940 for(i=0;i<m;i++) {
00941 int up, lo, remain, l = ptr[i+1]-ptr[i];
00942
00943 remain = l;
00944 lo = -1;
00945
00946 for(j=0;j<l;j++) {
00947 up = m - remain;
00948 lo = lo + 1;
00949
00950 switch(datatype) {
00951 case GS_DOUBLE:
00952 ((double *)mat)[ii] = drand48();
00953 break;
00954 case GS_FLOAT:
00955 ((float *)mat)[ii] = (float)drand48();
00956 break;
00957 case GS_INT:
00958 ((int *)mat)[ii] = random();
00959 break;
00960 case GS_CHAR:
00961 ((int *)mat)[ii] = (random() % 26) + 'a';
00962 break;
00963 default:
00964 ERRPRINTF("Bad data type\n");
00965 }
00966
00967 if(up != 0) {
00968 idx = random() % (up-lo) + lo;
00969
00970 remain--;
00971 }
00972 else
00973 idx = lo;
00974
00975 ind[ii] = idx;
00976 lo = idx;
00977 ii++;
00978 }
00979 }
00980
00981 *p = ptr;
00982 *ip = ind;
00983 *a = mat;
00984 return nnz;
00985 }
00986
01000 int
01001 gs_gen_sparse_mat_double(int m, int rmin, int rmax,
01002 double **a, int **ip, int **p)
01003 {
01004 return gs_gen_sparse_mat_common(GS_DOUBLE, sizeof(double), m, rmin, rmax,
01005 (void *)a, ip, p);
01006 }
01007
01021 int
01022 gs_gen_sparse_mat_float(int m, int rmin, int rmax,
01023 float **a, int **ip, int **p)
01024 {
01025 return gs_gen_sparse_mat_common(GS_FLOAT, sizeof(float), m, rmin, rmax,
01026 (void *)a, ip, p);
01027 }
01028
01042 int
01043 gs_gen_sparse_mat_int(int m, int rmin, int rmax,
01044 int **a, int **ip, int **p)
01045 {
01046 return gs_gen_sparse_mat_common(GS_INT, sizeof(int), m, rmin, rmax,
01047 (void *)a, ip, p);
01048 }
01049
01063 int
01064 gs_gen_sparse_mat_char(int m, int rmin, int rmax,
01065 char **a, int **ip, int **p)
01066 {
01067 return gs_gen_sparse_mat_common(GS_CHAR, sizeof(char), m, rmin, rmax,
01068 (void *)a, ip, p);
01069 }
01070
01084 gs_sparse_dup_t *
01085 gs_dup_sparse_mat(int nnz, int dim, size_t el_size,
01086 void *m, int *ind, int *ptr)
01087 {
01088 gs_sparse_dup_t *new_sp;
01089
01090 new_sp = (gs_sparse_dup_t *) malloc(sizeof(gs_sparse_dup_t));
01091
01092 if(!new_sp) return NULL;
01093
01094 new_sp->m = (void *)malloc(sizeof(double) * el_size * nnz);
01095 new_sp->ind = (int *)malloc(nnz * sizeof(int));
01096 new_sp->ptr = (int *)malloc(dim * sizeof(int));
01097
01098 if(!new_sp->m || !new_sp->ind || !new_sp->ptr) {
01099 if(new_sp->m) free(new_sp->m);
01100 if(new_sp->ind) free(new_sp->ind);
01101 if(new_sp->ptr) free(new_sp->ptr);
01102 if(new_sp) free(new_sp);
01103 ERRPRINTF("malloc failed.\n");
01104 return NULL;
01105 }
01106
01107 memcpy(new_sp->m, m, nnz * el_size);
01108 memcpy(new_sp->ind, ind, nnz * sizeof(int));
01109 memcpy(new_sp->ptr, ptr, dim * sizeof(int));
01110
01111 return new_sp;
01112 }
01113
01123 gs_argument_t *
01124 gs_arg_lookup_by_name(char *name, gs_argument_t *arglist)
01125 {
01126 gs_argument_t *arg;
01127 for (arg = arglist; arg != NULL; arg = arg->next)
01128 if (!strcmp(name, arg->name) )
01129 return(arg);
01130 return NULL;
01131 }
01132
01133
01145 int
01146 gs_arg_is_sparse_attr(char *name, gs_argument_t *arglist)
01147 {
01148 gs_argument_t *arg;
01149
01150 for(arg = arglist; arg != NULL; arg = arg->next) {
01151 if(arg->objecttype == GS_SPARSEMATRIX) {
01152 if(!strcmp(name, arg->sparse_attr.nnzexp) ||
01153 !strcmp(name, arg->sparse_attr.indices) ||
01154 !strcmp(name, arg->sparse_attr.pointer))
01155 return TRUE;
01156 }
01157 }
01158
01159 return FALSE;
01160 }
01161
01162
01163
01172 int gs_datatype_sizeof(int datatype)
01173 {
01174 switch(datatype) {
01175 case GS_INT:
01176 return sizeof(int);
01177 break;
01178 case GS_FLOAT:
01179 return sizeof(float);
01180 break;
01181 case GS_DOUBLE:
01182 return sizeof(double);
01183 break;
01184 case GS_SCOMPLEX:
01185 return sizeof(gs_scomplex);
01186 break;
01187 case GS_DCOMPLEX:
01188 return sizeof(gs_dcomplex);
01189 break;
01190 case GS_CHAR:
01191 return sizeof(char);
01192 break;
01193 default:
01194 return -1;
01195 break;
01196 }
01197 }