Changeset 898
- Timestamp:
- Feb 21, 2008 6:43:57 PM (16 years ago)
- Location:
- trunk/optimizer
- Files:
-
- 4 added
- 6 deleted
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/optimizer/src/Makefile.in
r897 r898 396 396 fi; \ 397 397 done 398 # Uncomment when you are ready to install tcl rappture library bindings399 #$(TCLSH_PROG) $(srcdir)/tclconfig/mkindex.tcl $(DESTDIR)$(pkglibdir)/scripts400 $(INSTALL_DATA) init.tcl $(DESTDIR)$(pkglibdir)/init.tcl401 @list='$(PKG_TCL_SOURCES)'; for p in $$list; do \402 if test -f $(srcdir)/$$p; then \403 destp=`basename $$p`; \404 echo " Install $$destp $(DESTDIR)$(pkglibdir)/$$destp"; \405 $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkglibdir)/$$destp; \406 fi; \407 done408 398 @if test "x$(SHARED_BUILD)" = "x1"; then \ 409 399 echo " Install pkgIndex.tcl $(DESTDIR)$(pkglibdir)"; \ -
trunk/optimizer/src/configure.in
r897 r898 74 74 TEA_ADD_SOURCES([rp_optimizer.c rp_tcloptions.c rp_optimizer_tcl.c plugin_pgapack.c]) 75 75 TEA_ADD_HEADERS([]) 76 TEA_ADD_INCLUDES([ ])77 TEA_ADD_CFLAGS([ ])76 TEA_ADD_INCLUDES([-Ipgapack/pgapack/include]) 77 TEA_ADD_CFLAGS([-DWL=32]) 78 78 TEA_ADD_STUB_SOURCES([]) 79 79 # uncomment this and mkindex.tcl line in makefile when you are ready to … … 81 81 #TEA_ADD_TCL_SOURCES([scripts/exec.tcl scripts/value.tcl init.tcl ../../tcl/scripts/library.tcl ../../tcl/scripts/result.tcl]) 82 82 TEA_ADD_TCL_SOURCES([]) 83 TEA_ADD_LIBS([-Lpgapack/pgapack/lib/linux -lpgaO]) 83 84 84 85 #-------------------------------------------------------------------- -
trunk/optimizer/src/plugin_pgapack.c
r897 r898 14 14 * ====================================================================== 15 15 */ 16 #include "pgapack.h" 16 17 #include "rp_optimizer_plugin.h" 17 18 18 19 typedef struct PgapackData { 19 int foo; /* data used by Pgapack... */ 20 int operation; /* operation <=> PGA_MINIMIZE/PGA_MAXIMIZE */ 21 int maxRuns; /* maximum runs <=> PGASetMaxGAIterValue() */ 22 int popSize; /* population size <=> PGASetPopSize() */ 23 int popRepl; /* replacement <=> PGASetPopReplacementType() */ 20 24 } PgapackData; 21 25 26 RpCustomTclOptionParse RpOption_ParseOper; 27 RpCustomTclOptionGet RpOption_GetOper; 28 RpTclOptionType RpOption_Oper = { 29 "pga_operation", RpOption_ParseOper, RpOption_GetOper, NULL 30 }; 31 32 RpCustomTclOptionParse RpOption_ParsePopRepl; 33 RpCustomTclOptionGet RpOption_GetPopRepl; 34 RpTclOptionType RpOption_PopRepl = { 35 "pga_poprepl", RpOption_ParsePopRepl, RpOption_GetPopRepl, NULL 36 }; 37 22 38 RpTclOption PgapackOptions[] = { 23 {"-foo", RP_OPTION_INT, NULL, Rp_Offset(PgapackData,foo)}, 24 {NULL, NULL, NULL, 0} 39 {"-maxruns", RP_OPTION_INT, Rp_Offset(PgapackData,maxRuns)}, 40 {"-operation", &RpOption_Oper, Rp_Offset(PgapackData,operation)}, 41 {"-poprepl", &RpOption_PopRepl, Rp_Offset(PgapackData,popRepl)}, 42 {"-popsize", RP_OPTION_INT, Rp_Offset(PgapackData,popSize)}, 43 {NULL, NULL, 0} 25 44 }; 45 46 static double PgapEvaluate _ANSI_ARGS_((PGAContext *ctx, int p, int pop)); 47 static void PgapCreateString _ANSI_ARGS_((PGAContext *ctx, int, int, int)); 48 static int PgapMutation _ANSI_ARGS_((PGAContext *ctx, int, int, double)); 49 static void PgapCrossover _ANSI_ARGS_((PGAContext *ctx, int, int, int, 50 int, int, int)); 51 static void PgapPrintString _ANSI_ARGS_((PGAContext *ctx, FILE*, int, int)); 52 static void PgapCopyString _ANSI_ARGS_((PGAContext *ctx, int, int, int, int)); 53 static int PgapDuplicateString _ANSI_ARGS_((PGAContext *ctx, int, int, int, int)); 54 static MPI_Datatype PgapBuildDT _ANSI_ARGS_((PGAContext *ctx, int, int)); 55 56 static void PgapLinkContext2Env _ANSI_ARGS_((PGAContext *ctx, 57 RpOptimEnv *envPtr)); 58 static RpOptimEnv* PgapGetEnvForContext _ANSI_ARGS_((PGAContext *ctx)); 59 static void PgapUnlinkContext2Env _ANSI_ARGS_((PGAContext *ctx)); 60 26 61 27 62 /* … … 38 73 { 39 74 PgapackData *dataPtr; 75 40 76 dataPtr = (PgapackData*)malloc(sizeof(PgapackData)); 41 dataPtr->foo = 1; 77 dataPtr->operation = PGA_MINIMIZE; 78 dataPtr->maxRuns = 10000; 79 dataPtr->popRepl = PGA_POPREPL_BEST; 80 dataPtr->popSize = 200; 81 42 82 return (ClientData)dataPtr; 83 } 84 85 /* 86 * ---------------------------------------------------------------------- 87 * PgapackRun() 88 * 89 * This routine is called to kick off an optimization run. Sets up 90 * a PGApack context and starts invoking runs. 91 * ---------------------------------------------------------------------- 92 */ 93 RpOptimStatus 94 PgapackRun(envPtr, evalProc) 95 RpOptimEnv *envPtr; /* optimization environment */ 96 RpOptimEvaluator *evalProc; /* call this proc to run tool */ 97 { 98 PgapackData *dataPtr =(PgapackData*)envPtr->pluginData; 99 PGAContext *ctx; 100 101 /* pgapack requires at least one arg -- the executable name */ 102 /* fake it here by just saying something like "rappture" */ 103 int argc = 1; char *argv[] = {"rappture"}; 104 105 ctx = PGACreate(&argc, argv, PGA_DATATYPE_USER, envPtr->numParams, 106 dataPtr->operation); 107 108 PGASetMaxGAIterValue(ctx, dataPtr->maxRuns); 109 PGASetPopSize(ctx, dataPtr->popSize); 110 PGASetPopReplaceType(ctx, dataPtr->popRepl); 111 112 PGASetUserFunction(ctx, PGA_USERFUNCTION_CREATESTRING, PgapCreateString); 113 PGASetUserFunction(ctx, PGA_USERFUNCTION_MUTATION, PgapMutation); 114 PGASetUserFunction(ctx, PGA_USERFUNCTION_CROSSOVER, PgapCrossover); 115 PGASetUserFunction(ctx, PGA_USERFUNCTION_PRINTSTRING, PgapPrintString); 116 PGASetUserFunction(ctx, PGA_USERFUNCTION_COPYSTRING, PgapCopyString); 117 PGASetUserFunction(ctx, PGA_USERFUNCTION_DUPLICATE, PgapDuplicateString); 118 PGASetUserFunction(ctx, PGA_USERFUNCTION_BUILDDATATYPE, PgapBuildDT); 119 120 envPtr->evalProc = evalProc; /* call this later for evaluations */ 121 122 /* 123 * We need a way to convert from a PGAContext to our RpOptimEnv 124 * data. This happens when Pgapack calls routines like 125 * PgapCreateString, passing in the PGAContext, but nothing else. 126 * Call PgapLinkContext2Env() here, so later on we can figure 127 * out how many parameters, names, types, etc. 128 */ 129 PgapLinkContext2Env(ctx, envPtr); 130 131 PGASetUp(ctx); 132 PGARun(ctx, PgapEvaluate); 133 PGADestroy(ctx); 134 135 PgapUnlinkContext2Env(ctx); 136 137 return RP_OPTIM_SUCCESS; 138 } 139 140 /* 141 * ---------------------------------------------------------------------- 142 * PgapackEvaluate() 143 * 144 * Called by PGApack whenever a set of input values needs to be 145 * evaluated. Passes the values on to the underlying Rappture tool, 146 * launches a run, and computes the value of the fitness function. 147 * Returns the value for the fitness function. 148 * ---------------------------------------------------------------------- 149 */ 150 double 151 PgapEvaluate(ctx, p, pop) 152 PGAContext *ctx; /* pgapack context for this optimization */ 153 int p; /* sample #p being run */ 154 int pop; /* identifier for this population */ 155 { 156 double fit = 0.0; 157 RpOptimEnv *envPtr; 158 RpOptimParam *paramPtr; 159 RpOptimStatus status; 160 161 envPtr = PgapGetEnvForContext(ctx); 162 paramPtr = (RpOptimParam*)PGAGetIndividual(ctx, p, pop)->chrom; 163 164 status = (*envPtr->evalProc)(envPtr, paramPtr, envPtr->numParams, &fit); 165 166 if (status != RP_OPTIM_SUCCESS) { 167 fprintf(stderr, "==WARNING: run failed!"); 168 PgapPrintString(ctx, stderr, p, pop); 169 } 170 171 return fit; 43 172 } 44 173 … … 57 186 { 58 187 PgapackData *dataPtr = (PgapackData*)cdata; 59 dataPtr->foo = 0;60 188 free(dataPtr); 61 189 } 190 191 /* 192 * ====================================================================== 193 * ROUTINES FOR MANAGING DATA STRINGS 194 * ====================================================================== 195 * PgapCreateString() 196 * 197 * Called by pgapack to create the so-called "string" of data used for 198 * an evaluation. 199 * ---------------------------------------------------------------------- 200 */ 201 void 202 PgapCreateString(ctx, p, pop, initFlag) 203 PGAContext *ctx; /* pgapack context for this optimization */ 204 int p; /* sample #p being run */ 205 int pop; /* identifier for this population */ 206 int initFlag; /* non-zero => fields should be initialized */ 207 { 208 int n, ival; 209 double dval; 210 RpOptimEnv *envPtr; 211 RpOptimParam *oldParamPtr, *newParamPtr; 212 PGAIndividual *newData; 213 RpOptimParamNumber *numPtr; 214 RpOptimParamString *strPtr; 215 216 envPtr = PgapGetEnvForContext(ctx); 217 218 newData = PGAGetIndividual(ctx, p, pop); 219 newData->chrom = malloc(envPtr->numParams*sizeof(RpOptimParam)); 220 newParamPtr = (RpOptimParam*)newData->chrom; 221 222 for (n=0; n < envPtr->numParams; n++) { 223 oldParamPtr = envPtr->paramList[n]; 224 newParamPtr[n].name = oldParamPtr->name; 225 newParamPtr[n].type = oldParamPtr->type; 226 switch (oldParamPtr->type) { 227 case RP_OPTIMPARAM_NUMBER: 228 newParamPtr[n].value.dval = 0.0; 229 break; 230 case RP_OPTIMPARAM_STRING: 231 newParamPtr[n].value.sval.num = -1; 232 newParamPtr[n].value.sval.str = NULL; 233 break; 234 default: 235 panic("bad parameter type in PgapCreateString()"); 236 } 237 } 238 239 if (initFlag) { 240 for (n=0; n < envPtr->numParams; n++) { 241 switch (newParamPtr[n].type) { 242 case RP_OPTIMPARAM_NUMBER: 243 numPtr = (RpOptimParamNumber*)envPtr->paramList[n]; 244 dval = PGARandom01(ctx,0); 245 newParamPtr[n].value.dval = 246 (numPtr->max - numPtr->min)*dval + numPtr->min; 247 break; 248 case RP_OPTIMPARAM_STRING: 249 strPtr = (RpOptimParamString*)envPtr->paramList[n]; 250 ival = (int)floor(PGARandom01(ctx,0) * strPtr->numValues); 251 envPtr->paramList[n]->value.sval.num = ival; 252 envPtr->paramList[n]->value.sval.str = strPtr->values[ival]; 253 break; 254 default: 255 panic("bad parameter type in PgapCreateString()"); 256 } 257 } 258 } 259 } 260 261 /* 262 * ---------------------------------------------------------------------- 263 * PgapMutation() 264 * 265 * Called by pgapack to perform random mutations on the input data 266 * used for evaluation. 267 * ---------------------------------------------------------------------- 268 */ 269 int 270 PgapMutation(ctx, p, pop, mr) 271 PGAContext *ctx; /* pgapack context for this optimization */ 272 int p; /* sample #p being run */ 273 int pop; /* identifier for this population */ 274 double mr; /* probability of mutation for each gene */ 275 { 276 int count = 0; /* number of mutations */ 277 278 int n, ival; 279 RpOptimEnv *envPtr; 280 RpOptimParam *paramPtr; 281 RpOptimParamNumber *numPtr; 282 RpOptimParamString *strPtr; 283 284 envPtr = PgapGetEnvForContext(ctx); 285 paramPtr = (RpOptimParam*)PGAGetIndividual(ctx, p, pop)->chrom; 286 287 for (n=0; n < envPtr->numParams; n++) { 288 if (PGARandomFlip(ctx, mr)) { 289 /* won the coin toss -- change this parameter */ 290 count++; 291 292 switch (paramPtr[n].type) { 293 case RP_OPTIMPARAM_NUMBER: 294 /* bump the value up/down a little, randomly */ 295 if (PGARandomFlip(ctx, 0.5)) { 296 paramPtr[n].value.dval += 0.1*paramPtr[n].value.dval; 297 } else { 298 paramPtr[n].value.dval -= 0.1*paramPtr[n].value.dval; 299 } 300 /* make sure the resulting value is still in bounds */ 301 numPtr = (RpOptimParamNumber*)envPtr->paramList[n]; 302 if (paramPtr[n].value.dval > numPtr->max) { 303 paramPtr[n].value.dval = numPtr->max; 304 } 305 if (paramPtr[n].value.dval < numPtr->min) { 306 paramPtr[n].value.dval = numPtr->min; 307 } 308 break; 309 310 case RP_OPTIMPARAM_STRING: 311 ival = paramPtr[n].value.sval.num; 312 if (PGARandomFlip(ctx, 0.5)) { 313 ival += 1; 314 } else { 315 ival -= 1; 316 } 317 strPtr = (RpOptimParamString*)envPtr->paramList[n]; 318 if (ival < 0) ival = 0; 319 if (ival >= strPtr->numValues) ival = strPtr->numValues-1; 320 paramPtr[n].value.sval.num = ival; 321 paramPtr[n].value.sval.str = strPtr->values[ival]; 322 break; 323 324 default: 325 panic("bad parameter type in PgapMutation()"); 326 } 327 } 328 } 329 return count; 330 } 331 332 /* 333 * ---------------------------------------------------------------------- 334 * PgapCrossover() 335 * 336 * Called by pgapack to perform cross-over mutations on the input data 337 * used for evaluation. 338 * ---------------------------------------------------------------------- 339 */ 340 void 341 PgapCrossover(ctx, p1, p2, pop1, c1, c2, pop2) 342 PGAContext *ctx; /* pgapack context for this optimization */ 343 int p1; /* sample # for parent of input string1 */ 344 int p2; /* sample # for parent of input string2 */ 345 int pop1; /* population containing p1 and p2 */ 346 int c1; /* sample # for child of input string1 */ 347 int c2; /* sample # for child of input string2 */ 348 int pop2; /* population containing c1 and c2 */ 349 { 350 int n; 351 RpOptimEnv *envPtr; 352 RpOptimParam *parent1, *parent2, *child1, *child2; 353 double pu; 354 355 envPtr = PgapGetEnvForContext(ctx); 356 parent1 = (RpOptimParam*)PGAGetIndividual(ctx, p1, pop1)->chrom; 357 parent2 = (RpOptimParam*)PGAGetIndividual(ctx, p2, pop1)->chrom; 358 child1 = (RpOptimParam*)PGAGetIndividual(ctx, c1, pop2)->chrom; 359 child2 = (RpOptimParam*)PGAGetIndividual(ctx, c2, pop2)->chrom; 360 361 pu = PGAGetUniformCrossoverProb(ctx); 362 363 for (n=0; n < envPtr->numParams; n++) { 364 if (PGARandomFlip(ctx, pu)) { 365 /* child inherits from parent */ 366 memcpy(&child1[n], &parent1[n], sizeof(RpOptimParam)); 367 memcpy(&child2[n], &parent2[n], sizeof(RpOptimParam)); 368 } else { 369 /* crossover */ 370 memcpy(&child1[n], &parent2[n], sizeof(RpOptimParam)); 371 memcpy(&child2[n], &parent1[n], sizeof(RpOptimParam)); 372 } 373 } 374 } 375 376 /* 377 * ---------------------------------------------------------------------- 378 * PgapPrintString() 379 * 380 * Called by pgapack to format the values for a particular string of 381 * input data. 382 * ---------------------------------------------------------------------- 383 */ 384 void 385 PgapPrintString(ctx, fp, p, pop) 386 PGAContext *ctx; /* pgapack context for this optimization */ 387 FILE *fp; /* write to this file pointer */ 388 int p; /* sample #p being run */ 389 int pop; /* identifier for this population */ 390 { 391 int n; 392 RpOptimEnv *envPtr; 393 RpOptimParam *paramPtr; 394 395 envPtr = PgapGetEnvForContext(ctx); 396 paramPtr = (RpOptimParam*)PGAGetIndividual(ctx, p, pop)->chrom; 397 398 for (n=0; n < envPtr->numParams; n++) { 399 fprintf(fp, "#%4d: ", n); 400 switch (paramPtr[n].type) { 401 case RP_OPTIMPARAM_NUMBER: 402 fprintf(fp, "[%11.7g] (%s)\n", paramPtr[n].value.dval, 403 paramPtr[n].name); 404 break; 405 case RP_OPTIMPARAM_STRING: 406 fprintf(fp, "[%d]=\"%s\" (%s)\n", paramPtr[n].value.sval.num, 407 paramPtr[n].value.sval.str, paramPtr[n].name); 408 break; 409 default: 410 panic("bad parameter type in PgapPrintString()"); 411 } 412 } 413 } 414 415 /* 416 * ---------------------------------------------------------------------- 417 * PgapCopyString() 418 * 419 * Called by pgapack to copy one input string to another. 420 * ---------------------------------------------------------------------- 421 */ 422 void 423 PgapCopyString(ctx, p1, pop1, p2, pop2) 424 PGAContext *ctx; /* pgapack context for this optimization */ 425 int p1; /* source sample # being run */ 426 int pop1; /* population containing p1 */ 427 int p2; /* destination sample # being run */ 428 int pop2; /* population containing p1 */ 429 { 430 int n; 431 RpOptimEnv *envPtr; 432 RpOptimParam *src, *dst; 433 434 envPtr = PgapGetEnvForContext(ctx); 435 src = (RpOptimParam*)PGAGetIndividual(ctx, p1, pop1)->chrom; 436 dst = (RpOptimParam*)PGAGetIndividual(ctx, p2, pop2)->chrom; 437 438 for (n=0; n < envPtr->numParams; n++) { 439 dst[n].type = src[n].type; 440 switch (src[n].type) { 441 case RP_OPTIMPARAM_NUMBER: 442 dst[n].value.dval = src[n].value.dval; 443 break; 444 case RP_OPTIMPARAM_STRING: 445 dst[n].value.sval.num = src[n].value.sval.num; 446 dst[n].value.sval.str = src[n].value.sval.str; 447 break; 448 default: 449 panic("bad parameter type in PgapCopyString()"); 450 } 451 } 452 } 453 454 /* 455 * ---------------------------------------------------------------------- 456 * PgapDuplicateString() 457 * 458 * Called by pgapack to compare two input strings. Returns non-zero if 459 * the two are duplicates and 0 otherwise. 460 * ---------------------------------------------------------------------- 461 */ 462 int 463 PgapDuplicateString(ctx, p1, pop1, p2, pop2) 464 PGAContext *ctx; /* pgapack context for this optimization */ 465 int p1; /* sample #p being run */ 466 int pop1; /* population containing p1 */ 467 int p2; /* sample #p being run */ 468 int pop2; /* population containing p1 */ 469 { 470 int n; 471 RpOptimEnv *envPtr; 472 RpOptimParam *param1, *param2; 473 474 envPtr = PgapGetEnvForContext(ctx); 475 param1 = (RpOptimParam*)PGAGetIndividual(ctx, p1, pop1)->chrom; 476 param2 = (RpOptimParam*)PGAGetIndividual(ctx, p2, pop2)->chrom; 477 478 for (n=0; n < envPtr->numParams; n++) { 479 if (param1[n].type != param2[n].type) { 480 return 0; /* different! */ 481 } 482 switch (param1[n].type) { 483 case RP_OPTIMPARAM_NUMBER: 484 if (param1[n].value.dval != param2[n].value.dval) { 485 return 0; /* different! */ 486 } 487 break; 488 case RP_OPTIMPARAM_STRING: 489 if (param1[n].value.sval.num != param2[n].value.sval.num) { 490 return 0; /* different! */ 491 } 492 break; 493 default: 494 panic("bad parameter type in PgapDuplicateString()"); 495 } 496 } 497 return 1; 498 } 499 500 /* 501 * ---------------------------------------------------------------------- 502 * PgapCopyString() 503 * 504 * Called by pgapack to copy one input string to another. 505 * ---------------------------------------------------------------------- 506 */ 507 MPI_Datatype 508 PgapBuildDT(ctx, p, pop) 509 PGAContext *ctx; /* pgapack context for this optimization */ 510 int p; /* sample # being run */ 511 int pop; /* population containing sample */ 512 { 513 panic("MPI support not implemented!"); 514 return NULL; 515 } 516 517 /* 518 * ====================================================================== 519 * OPTION: -operation <=> PGA_MINIMIZE / PGA_MAXIMIZE 520 * ====================================================================== 521 */ 522 int 523 RpOption_ParseOper(interp, valObj, cdata, offset) 524 Tcl_Interp *interp; /* interpreter handling this request */ 525 Tcl_Obj *valObj; /* set option to this new value */ 526 ClientData cdata; /* save in this data structure */ 527 int offset; /* save at this offset in cdata */ 528 { 529 int *ptr = (int*)(cdata+offset); 530 char *val = Tcl_GetStringFromObj(valObj, (int*)NULL); 531 if (strcmp(val,"minimize") == 0) { 532 *ptr = PGA_MINIMIZE; 533 } 534 else if (strcmp(val,"maximize") == 0) { 535 *ptr = PGA_MAXIMIZE; 536 } 537 else { 538 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), 539 "bad value \"", val, "\": should be minimize, maximize", 540 (char*)NULL); 541 return TCL_ERROR; 542 } 543 return TCL_OK; 544 } 545 546 int 547 RpOption_GetOper(interp, cdata, offset) 548 Tcl_Interp *interp; /* interpreter handling this request */ 549 ClientData cdata; /* get from this data structure */ 550 int offset; /* get from this offset in cdata */ 551 { 552 int *ptr = (int*)(cdata+offset); 553 switch (*ptr) { 554 case PGA_MINIMIZE: 555 Tcl_SetResult(interp, "minimize", TCL_STATIC); 556 break; 557 case PGA_MAXIMIZE: 558 Tcl_SetResult(interp, "maximize", TCL_STATIC); 559 break; 560 default: 561 Tcl_SetResult(interp, "???", TCL_STATIC); 562 break; 563 } 564 return TCL_OK; 565 } 566 567 /* 568 * ====================================================================== 569 * OPTION: -poprepl <=> PGASetPopReplacementType() 570 * ====================================================================== 571 */ 572 int 573 RpOption_ParsePopRepl(interp, valObj, cdata, offset) 574 Tcl_Interp *interp; /* interpreter handling this request */ 575 Tcl_Obj *valObj; /* set option to this new value */ 576 ClientData cdata; /* save in this data structure */ 577 int offset; /* save at this offset in cdata */ 578 { 579 int *ptr = (int*)(cdata+offset); 580 char *val = Tcl_GetStringFromObj(valObj, (int*)NULL); 581 if (*val == 'b' && strcmp(val,"best") == 0) { 582 *ptr = PGA_POPREPL_BEST; 583 } 584 else if (*val == 'r' && strcmp(val,"random-repl") == 0) { 585 *ptr = PGA_POPREPL_RANDOM_REP; 586 } 587 else if (*val == 'r' && strcmp(val,"random-norepl") == 0) { 588 *ptr = PGA_POPREPL_RANDOM_NOREP; 589 } 590 else { 591 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), 592 "bad value \"", val, "\": should be best, random-norepl," 593 " or random-repl", (char*)NULL); 594 return TCL_ERROR; 595 } 596 return TCL_OK; 597 } 598 599 int 600 RpOption_GetPopRepl(interp, cdata, offset) 601 Tcl_Interp *interp; /* interpreter handling this request */ 602 ClientData cdata; /* get from this data structure */ 603 int offset; /* get from this offset in cdata */ 604 { 605 int *ptr = (int*)(cdata+offset); 606 switch (*ptr) { 607 case PGA_POPREPL_BEST: 608 Tcl_SetResult(interp, "best", TCL_STATIC); 609 break; 610 case PGA_POPREPL_RANDOM_REP: 611 Tcl_SetResult(interp, "random-repl", TCL_STATIC); 612 break; 613 case PGA_POPREPL_RANDOM_NOREP: 614 Tcl_SetResult(interp, "random-norepl", TCL_STATIC); 615 break; 616 default: 617 Tcl_SetResult(interp, "???", TCL_STATIC); 618 break; 619 } 620 return TCL_OK; 621 } 622 623 /* 624 * ====================================================================== 625 * ROUTINES FOR CONNECTING PGACONTEXT <=> RPOPTIMENV 626 * ====================================================================== 627 * PgapLinkContext2Env() 628 * This routine is used internally to establish a relationship between 629 * a PGAContext token and its corresponding RpOptimEnv data. The 630 * PGA routines don't provide a way to pass the RpOptimEnv data along, 631 * so we use these routines to find the correspondence. 632 * 633 * PgapGetEnvForContext() 634 * Returns the RpOptimEnv associated with a given PGAContext. If the 635 * link has not been established via PgapLinkContext2Env(), then this 636 * routine returns NULL. 637 * 638 * PgapUnlinkContext2Env() 639 * Breaks the link between a PGAContext and its RpOptimEnv. Should 640 * be called when the PGAContext is destroyed and is no longer valid. 641 * ---------------------------------------------------------------------- 642 */ 643 static Tcl_HashTable *Pgacontext2Rpenv = NULL; 644 645 void 646 PgapLinkContext2Env(ctx, envPtr) 647 PGAContext *ctx; /* pgapack context for this optimization */ 648 RpOptimEnv *envPtr; /* corresponding Rappture optimization data */ 649 { 650 Tcl_HashEntry *ctxEntry; 651 int newEntry; 652 653 if (Pgacontext2Rpenv == NULL) { 654 Pgacontext2Rpenv = (Tcl_HashTable*)malloc(sizeof(Tcl_HashTable)); 655 Tcl_InitHashTable(Pgacontext2Rpenv, TCL_ONE_WORD_KEYS); 656 } 657 ctxEntry = Tcl_CreateHashEntry(Pgacontext2Rpenv, (char*)ctx, &newEntry); 658 Tcl_SetHashValue(ctxEntry, (ClientData)envPtr); 659 } 660 661 RpOptimEnv* 662 PgapGetEnvForContext(ctx) 663 PGAContext *ctx; 664 { 665 Tcl_HashEntry *entryPtr; 666 667 if (Pgacontext2Rpenv) { 668 entryPtr = Tcl_FindHashEntry(Pgacontext2Rpenv, (char*)ctx); 669 if (entryPtr) { 670 return (RpOptimEnv*)Tcl_GetHashValue(entryPtr); 671 } 672 } 673 return NULL; 674 } 675 676 void 677 PgapUnlinkContext2Env(ctx) 678 PGAContext *ctx; 679 { 680 Tcl_HashEntry *entryPtr; 681 682 if (Pgacontext2Rpenv) { 683 entryPtr = Tcl_FindHashEntry(Pgacontext2Rpenv, (char*)ctx); 684 if (entryPtr) { 685 Tcl_DeleteHashEntry(entryPtr); 686 } 687 } 688 } -
trunk/optimizer/src/rp_optimizer.c
r897 r898 33 33 */ 34 34 RpOptimEnv* 35 RpOptimCreate(pluginData, cleanupP tr)35 RpOptimCreate(pluginData, cleanupProc) 36 36 ClientData pluginData; /* special data created for this env */ 37 RpOptimCleanup *cleanupP tr;/* routine to clean up pluginData */37 RpOptimCleanup *cleanupProc; /* routine to clean up pluginData */ 38 38 { 39 39 RpOptimEnv *envPtr; 40 40 envPtr = (RpOptimEnv*)malloc(sizeof(RpOptimEnv)); 41 envPtr->pluginData = pluginData; 42 envPtr->cleanupPtr = cleanupPtr; 41 envPtr->pluginData = pluginData; 42 envPtr->cleanupProc = cleanupProc; 43 envPtr->toolData = NULL; 43 44 44 45 envPtr->numParams = 0; … … 106 107 numPtr->base.name = strdup(name); 107 108 numPtr->base.type = RP_OPTIMPARAM_NUMBER; 108 numPtr->base.value. num= 0.0;109 numPtr->base.value.dval = 0.0; 109 110 numPtr->min = -DBL_MAX; 110 111 numPtr->max = DBL_MAX; … … 134 135 strPtr->base.name = strdup(name); 135 136 strPtr->base.type = RP_OPTIMPARAM_STRING; 136 strPtr->base.value.str = NULL; 137 strPtr->base.value.sval.num = -1; 138 strPtr->base.value.sval.str = NULL; 137 139 strPtr->values = NULL; 140 strPtr->numValues = 0; 138 141 139 142 RpOptimAddParam(envPtr, (RpOptimParam*)strPtr); … … 194 197 /* 195 198 * ---------------------------------------------------------------------- 196 * RpOptimPerform()197 *198 * Used to perform an optimization in the given context. Each run is199 * performed by calling an evaluation function represented by a200 * function pointer. If an optimum value is found within the limit201 * on the number of runs, then this procedure returns RP_OPTIM_SUCCESS.202 * Values for the optimum input parameters are returned through the203 * paramList within the context. If the optimization fails, this204 * function returns RP_OPTIM_FAILURE.205 * ----------------------------------------------------------------------206 */207 RpOptimStatus208 RpOptimPerform(envPtr, evalFuncPtr, maxRuns)209 RpOptimEnv *envPtr; /* context for this optimization */210 RpOptimEvaluator *evalFuncPtr; /* function called to handle run */211 int maxRuns; /* limit on number of runs,212 * or 0 for no limit */213 {214 RpOptimStatus status = RP_OPTIM_UNKNOWN;215 216 int n, nruns, ival, nvals;217 double dval, fitness;218 RpOptimParamNumber *numPtr;219 RpOptimParamString *strPtr;220 RpOptimStatus runStatus;221 222 if (envPtr->numParams == 0) { /* no input parameters? */223 return RP_OPTIM_FAILURE; /* then we can't optimize! */224 }225 226 /*227 * Call the evaluation function a number of times with different228 * values and perform the optimization.229 */230 nruns = 0;231 while (status == RP_OPTIM_UNKNOWN) {232 /*233 * Pick random values for all inputs.234 */235 for (n=0; n < envPtr->numParams; n++) {236 switch (envPtr->paramList[n]->type) {237 case RP_OPTIMPARAM_NUMBER:238 numPtr = (RpOptimParamNumber*)envPtr->paramList[n];239 dval = drand48();240 envPtr->paramList[n]->value.num =241 (numPtr->max - numPtr->min)*dval + numPtr->min;242 break;243 case RP_OPTIMPARAM_STRING:244 strPtr = (RpOptimParamString*)envPtr->paramList[n];245 for (nvals=0; strPtr->values[nvals]; nvals++)246 ; /* count values */247 ival = (int)floor(drand48() * nvals);248 envPtr->paramList[n]->value.str = strPtr->values[ival];249 break;250 }251 }252 253 /*254 * Call the evaluation function to get the fitness value.255 */256 runStatus = (*evalFuncPtr)(envPtr->paramList, envPtr->numParams,257 &fitness);258 259 if (runStatus == RP_OPTIM_SUCCESS) {260 /*261 * Is the fitness function any better?262 * Change the input values here based on fitness.263 * ...264 */265 }266 267 if (++nruns >= maxRuns && maxRuns > 0) {268 status = RP_OPTIM_FAILURE; /* reached the limit of runs */269 }270 }271 272 return status;273 }274 275 /*276 * ----------------------------------------------------------------------277 199 * RpOptimDelete() 278 200 * … … 292 214 RpOptimCleanupParam(envPtr->paramList[n]); 293 215 } 294 if (envPtr->cleanupP tr) {295 (*envPtr->cleanupP tr)(envPtr->pluginData);216 if (envPtr->cleanupProc) { 217 (*envPtr->cleanupProc)(envPtr->pluginData); 296 218 } 297 219 free(envPtr->paramList); -
trunk/optimizer/src/rp_optimizer.h
r897 r898 32 32 33 33 /* 34 * During each optimization, a function of the following type is 35 * called again and again to evaluate input parameters and compute 36 * the fitness function. 37 */ 38 typedef enum { 39 RP_OPTIM_SUCCESS=0, RP_OPTIM_UNKNOWN, RP_OPTIM_FAILURE, RP_OPTIM_ABORTED 40 } RpOptimStatus; 41 42 struct RpOptimEnv; /* defined below */ 43 struct RpOptimParam; 44 45 typedef RpOptimStatus (RpOptimEvaluator) _ANSI_ARGS_(( 46 struct RpOptimEnv *envPtr, struct RpOptimParam *values, int numValues, 47 double *fitnessPtr)); 48 49 typedef RpOptimStatus (RpOptimHandler) _ANSI_ARGS_(( 50 struct RpOptimEnv *envPtr, RpOptimEvaluator *evalProc)); 51 52 /* 34 53 * This is the basic definition for each parameter within an optimization. 35 54 * Each parameter has a name, type, and value. The value is important … … 41 60 } RpOptimParamType; 42 61 62 typedef struct RpDiscreteString { 63 int num; /* integer representing this string */ 64 char *str; /* actual string selected */ 65 } RpDiscreteString; 66 43 67 typedef struct RpOptimParam { 44 68 char *name; /* name of this parameter */ 45 69 RpOptimParamType type; /* paramter type -- number, string, etc */ 46 70 union { 47 double num; /* slot for number value */ 48 char *str; /* slot for string value */ 71 double dval; /* slot for number value */ 72 int ival; /* slot for integer value */ 73 RpDiscreteString sval; /* slot for string value */ 49 74 } value; 50 75 } RpOptimParam; … … 65 90 RpOptimParam base; /* basic parameter info */ 66 91 char **values; /* array of allowed values */ 92 int numValues; /* number of allowed values */ 67 93 } RpOptimParamString; 68 94 … … 72 98 */ 73 99 typedef struct RpOptimEnv { 100 RpOptimEvaluator *evalProc; /* called during optimization to do run */ 74 101 ClientData pluginData; /* data created by plugin init routine */ 75 RpOptimCleanup *cleanupPtr; /* cleanup routine for pluginData */ 102 RpOptimCleanup *cleanupProc; /* cleanup routine for pluginData */ 103 ClientData toolData; /* data used during tool execution */ 76 104 RpOptimParam **paramList; /* list of input parameters to vary */ 77 105 int numParams; /* current number of parameters */ … … 80 108 81 109 /* 82 * During each optimization, a function of the following type is83 * called againa and again to evaluate input parameters and compute84 * the fitness function.85 */86 typedef enum {87 RP_OPTIM_SUCCESS=0, RP_OPTIM_UNKNOWN, RP_OPTIM_FAILURE88 } RpOptimStatus;89 90 typedef RpOptimStatus (RpOptimEvaluator)_ANSI_ARGS_((RpOptimParam **values,91 int numValues, double *fitnessPtr));92 93 /*94 110 * Here are the functions in the API: 95 111 */ 96 112 EXTERN RpOptimEnv* RpOptimCreate _ANSI_ARGS_((ClientData pluginData, 97 RpOptimCleanup *cleanupP tr));113 RpOptimCleanup *cleanupProc)); 98 114 99 115 EXTERN RpOptimParam* RpOptimAddParamNumber _ANSI_ARGS_((RpOptimEnv *envPtr, … … 108 124 EXTERN void RpOptimDeleteParam _ANSI_ARGS_((RpOptimEnv *envPtr, char *name)); 109 125 110 EXTERN RpOptimStatus RpOptimPerform _ANSI_ARGS_((RpOptimEnv *envPtr,111 RpOptimEvaluator *evalFuncPtr, int maxRuns));112 113 126 EXTERN void RpOptimDelete _ANSI_ARGS_((RpOptimEnv *envPtr)); 114 127 -
trunk/optimizer/src/rp_optimizer_plugin.h
r897 r898 30 30 */ 31 31 typedef struct RpOptimPlugin { 32 char *name; /* name of this package for -using */ 33 RpOptimInit *initPtr; /* initialization routine */ 34 RpOptimCleanup *cleanupPtr; /* cleanup routine */ 35 RpTclOption *optionSpec; /* specs for config options */ 32 char *name; /* name of this package for -using */ 33 RpOptimInit *initProc; /* initialization routine */ 34 RpOptimHandler *runProc; /* handles the core optimization */ 35 RpOptimCleanup *cleanupProc; /* cleanup routine */ 36 RpTclOption *optionSpec; /* specs for config options */ 36 37 } RpOptimPlugin; 37 38 -
trunk/optimizer/src/rp_optimizer_tcl.c
r897 r898 26 26 */ 27 27 RpOptimInit PgapackInit; 28 RpOptimHandler PgapackRun; 28 29 RpOptimCleanup PgapackCleanup; 29 30 extern RpTclOption PgapackOptions; 30 31 31 32 static RpOptimPlugin rpOptimPlugins[] = { 32 {"pgapack", PgapackInit, Pgapack Cleanup, &PgapackOptions},33 {"pgapack", PgapackInit, PgapackRun, PgapackCleanup, &PgapackOptions}, 33 34 {NULL, NULL, NULL}, 34 35 }; … … 39 40 } RpOptimPluginData; 40 41 42 typedef struct RpOptimToolData { 43 Tcl_Interp *interp; /* interp handling this tool */ 44 Tcl_Obj *toolPtr; /* command for tool object */ 45 Tcl_Obj *updateCmdPtr; /* command used to look for abort */ 46 } RpOptimToolData; 47 41 48 /* 42 49 * ---------------------------------------------------------------------- … … 45 52 */ 46 53 RpTclOption rpOptimNumberOpts[] = { 47 {"-min", RP_OPTION_DOUBLE, NULL,Rp_Offset(RpOptimParamNumber,min)},48 {"-max", RP_OPTION_DOUBLE, NULL,Rp_Offset(RpOptimParamNumber,max)},49 {NULL, NULL, NULL,0}54 {"-min", RP_OPTION_DOUBLE, Rp_Offset(RpOptimParamNumber,min)}, 55 {"-max", RP_OPTION_DOUBLE, Rp_Offset(RpOptimParamNumber,max)}, 56 {NULL, NULL, 0} 50 57 }; 51 58 52 59 RpTclOption rpOptimStringOpts[] = { 53 {"-values", RP_OPTION_LIST, NULL,Rp_Offset(RpOptimParamString,values)},54 {NULL, NULL, NULL,0}60 {"-values", RP_OPTION_LIST, Rp_Offset(RpOptimParamString,values)}, 61 {NULL, NULL, 0} 55 62 }; 56 63 … … 61 68 Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); 62 69 static void RpOptimInstanceCleanup _ANSI_ARGS_((ClientData cdata)); 70 static RpOptimStatus RpOptimizerPerformInTcl _ANSI_ARGS_((RpOptimEnv *envPtr, 71 RpOptimParam *values, int numValues, double *fitnessPtr)); 72 static int RpOptimizerUpdateInTcl _ANSI_ARGS_((RpOptimEnv *envPtr)); 63 73 64 74 #ifdef BUILD_Rappture … … 111 121 RpOptimPlugin *usingPluginPtr = &rpOptimPlugins[0]; 112 122 123 /* no good default for the tool being optimized */ 124 Tcl_Obj *toolPtr = NULL; 125 126 /* no name for this object by default */ 113 127 char *name = NULL; 114 128 … … 116 130 RpOptimPlugin* pluginPtr; 117 131 RpOptimPluginData* pluginDataPtr; 132 RpOptimToolData* toolDataPtr; 133 118 134 int n; 119 135 char *option, autoname[32], *sep; … … 174 190 n += 2; 175 191 } 192 else if (strcmp(option,"-tool") == 0) { 193 if (n+1 >= objc) { 194 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), 195 "missing value for option \"", option, "\"", 196 (char*)NULL); 197 return TCL_ERROR; 198 } 199 toolPtr = objv[n+1]; 200 Tcl_IncrRefCount(toolPtr); 201 n += 2; 202 } 176 203 else { 177 204 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), 178 205 "bad option \"", option, "\": should be ", 179 "- using", (char*)NULL);206 "-tool, -using", (char*)NULL); 180 207 return TCL_ERROR; 181 208 } … … 198 225 pluginDataPtr->pluginDefn = usingPluginPtr; 199 226 pluginDataPtr->clientData = NULL; 200 if (usingPluginPtr->initP tr) {201 pluginDataPtr->clientData = (*usingPluginPtr->initP tr)();227 if (usingPluginPtr->initProc) { 228 pluginDataPtr->clientData = (*usingPluginPtr->initProc)(); 202 229 } 203 230 envPtr = RpOptimCreate((ClientData)pluginDataPtr, RpOptimInstanceCleanup); 231 232 toolDataPtr = (RpOptimToolData*)malloc(sizeof(RpOptimToolData)); 233 toolDataPtr->interp = interp; 234 toolDataPtr->toolPtr = toolPtr; 235 toolDataPtr->updateCmdPtr = NULL; 236 envPtr->toolData = (ClientData)toolDataPtr; 204 237 205 238 Tcl_CreateObjCommand(interp, name, RpOptimInstanceCmd, … … 224 257 { 225 258 RpOptimEnv *envPtr = (RpOptimEnv*)cdata; 259 RpOptimToolData *toolDataPtr; 226 260 int n; 227 261 ClientData paramdata; 262 263 if (envPtr->toolData) { 264 toolDataPtr = (RpOptimToolData*)envPtr->toolData; 265 if (toolDataPtr->toolPtr) { 266 Tcl_DecrRefCount(toolDataPtr->toolPtr); 267 } 268 if (toolDataPtr->updateCmdPtr) { 269 Tcl_DecrRefCount(toolDataPtr->updateCmdPtr); 270 } 271 free(toolDataPtr); 272 envPtr->toolData = NULL; 273 } 228 274 229 275 for (n=0; n < envPtr->numParams; n++) { … … 252 298 * <name> get ?<glob>? ?-option? 253 299 * <name> configure ?-option? ?value -option value ...? 254 * <name> perform ?-maxruns <num>? ?-abortvar <varName>? 300 * <name> perform ?-tool <tool>? ?-updatecommand <varName>? 301 * <name> using 255 302 * 256 303 * The "add" command is used to add various parameter types to the … … 268 315 RpOptimEnv* envPtr = (RpOptimEnv*)cdata; 269 316 RpOptimPluginData* pluginDataPtr = (RpOptimPluginData*)envPtr->pluginData; 270 271 int n, j, nmatches; 317 RpOptimToolData* toolDataPtr = (RpOptimToolData*)envPtr->toolData; 318 319 int n, j, nvals, nmatches; 272 320 char *option, *type, *path; 273 321 RpOptimParam *paramPtr; 322 RpOptimParamString *strPtr; 323 RpOptimStatus status; 274 324 RpTclOption *optSpecPtr; 275 Tcl_Obj *rval, *rrval ;325 Tcl_Obj *rval, *rrval, *toolPtr, *updateCmdPtr; 276 326 277 327 if (objc < 2) { … … 314 364 return TCL_ERROR; 315 365 } 366 367 /* list of values just changed -- patch up the count */ 368 strPtr = (RpOptimParamString*)paramPtr; 369 for (nvals=0; strPtr->values[nvals]; nvals++) 370 ; /* count the values */ 371 strPtr->numValues = nvals; 316 372 } 317 373 else { … … 496 552 497 553 /* 498 * OPTION: perform ?- maxruns num? ?-abortvarname?554 * OPTION: perform ?-tool name? ?-updatecommand name? 499 555 */ 500 556 else if (*option == 'p' && strcmp(option,"perform") == 0) { 557 /* use this tool by default */ 558 toolPtr = toolDataPtr->toolPtr; 559 560 /* no -updatecommand by default */ 561 updateCmdPtr = NULL; 562 563 n = 2; 564 while (n < objc) { 565 option = Tcl_GetStringFromObj(objv[n], (int*)NULL); 566 if (n+1 >= objc) { 567 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), 568 "missing value for option \"", option, "\"", 569 (char*)NULL); 570 return TCL_ERROR; 571 } 572 if (strcmp(option,"-tool") == 0) { 573 toolPtr = objv[n+1]; 574 n += 2; 575 } 576 else if (strcmp(option,"-updatecommand") == 0) { 577 updateCmdPtr = objv[n+1]; 578 n += 2; 579 } 580 else { 581 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), 582 "bad option \"", option, "\": should be -tool," 583 " -updatecommand", (char*)NULL); 584 return TCL_ERROR; 585 } 586 } 587 588 /* 589 * Must have a tool object at this point, or else we 590 * don't know what to optimize. 591 */ 592 if (toolPtr == NULL) { 593 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), 594 "tool being optimized not specified via -tool option", 595 (char*)NULL); 596 return TCL_ERROR; 597 } 598 599 Tcl_IncrRefCount(toolPtr); 600 if (updateCmdPtr) { 601 Tcl_IncrRefCount(updateCmdPtr); 602 toolDataPtr->updateCmdPtr = updateCmdPtr; 603 } 604 605 /* call the main optimization routine here */ 606 status = (*pluginDataPtr->pluginDefn->runProc)(envPtr, 607 RpOptimizerPerformInTcl); 608 609 Tcl_DecrRefCount(toolPtr); 610 if (updateCmdPtr) { 611 Tcl_DecrRefCount(updateCmdPtr); 612 toolDataPtr->updateCmdPtr = NULL; 613 } 614 615 switch (status) { 616 case RP_OPTIM_SUCCESS: 617 Tcl_SetResult(interp, "success", TCL_STATIC); 618 break; 619 case RP_OPTIM_FAILURE: 620 Tcl_SetResult(interp, "failure", TCL_STATIC); 621 break; 622 case RP_OPTIM_ABORTED: 623 Tcl_SetResult(interp, "aborted", TCL_STATIC); 624 break; 625 case RP_OPTIM_UNKNOWN: 626 default: 627 Tcl_SetResult(interp, "???", TCL_STATIC); 628 break; 629 } 630 return TCL_OK; 631 } 632 633 /* 634 * OPTION: using 635 */ 636 else if (*option == 'u' && strcmp(option,"using") == 0) { 637 if (objc > 2) { 638 Tcl_WrongNumArgs(interp, 1, objv, "using"); 639 return TCL_ERROR; 640 } 641 Tcl_SetResult(interp, pluginDataPtr->pluginDefn->name, TCL_STATIC); 642 return TCL_OK; 501 643 } 502 644 503 645 else { 504 646 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), 505 "bad option \"", option, "\": should be add, perform",506 (char*)NULL);647 "bad option \"", option, "\": should be add, configure, " 648 "get, perform, using", (char*)NULL); 507 649 return TCL_ERROR; 508 650 } … … 535 677 536 678 /* call a specialized cleanup routine to handle the rest */ 537 if (pluginDataPtr->pluginDefn->cleanupP tr) {538 (*pluginDataPtr->pluginDefn->cleanupP tr)(pluginDataPtr->clientData);679 if (pluginDataPtr->pluginDefn->cleanupProc) { 680 (*pluginDataPtr->pluginDefn->cleanupProc)(pluginDataPtr->clientData); 539 681 } 540 682 pluginDataPtr->clientData = NULL; … … 543 685 free((char*)pluginDataPtr); 544 686 } 687 688 /* 689 * ------------------------------------------------------------------------ 690 * RpOptimizerPerformInTcl() 691 * 692 * Invoked as a call-back within RpOptimPerform() to handle each 693 * optimization run. Launches a run of a Rappture-based tool using 694 * the given values and computes the value for the fitness function. 695 * 696 * Returns RP_OPTIM_SUCCESS if the run was successful, along with 697 * the value in the fitness function in fitnessPtr. If something 698 * goes wrong with the run, it returns RP_OPTIM_FAILURE. 699 * ------------------------------------------------------------------------ 700 */ 701 static RpOptimStatus 702 RpOptimizerPerformInTcl(envPtr, values, numValues, fitnessPtr) 703 RpOptimEnv *envPtr; /* optimization environment */ 704 RpOptimParam *values; /* incoming values for the simulation */ 705 int numValues; /* number of incoming values */ 706 double *fitnessPtr; /* returns: computed value of fitness func */ 707 { 708 printf("running...\n"); 709 *fitnessPtr = 0.0; 710 return RP_OPTIM_SUCCESS; 711 } 712 713 /* 714 * ------------------------------------------------------------------------ 715 * RpOptimizerUpdateInTcl() 716 * 717 * Invoked as a call-back within RpOptimPerform() to update the 718 * application and look for an "abort" signal. Evaluates a bit of 719 * optional code stored in the optimization environment. Returns 0 720 * if everything is okay, and non-zero if the user wants to abort. 721 * ------------------------------------------------------------------------ 722 */ 723 static int 724 RpOptimizerUpdateInTcl(envPtr) 725 RpOptimEnv *envPtr; /* optimization environment */ 726 { 727 RpOptimToolData *toolDataPtr = (RpOptimToolData*)envPtr->toolData; 728 int status; 729 730 if (toolDataPtr->updateCmdPtr) { 731 status = Tcl_GlobalEvalObj(toolDataPtr->interp, 732 toolDataPtr->updateCmdPtr); 733 734 if (status == TCL_ERROR) { 735 Tcl_BackgroundError(toolDataPtr->interp); 736 return 0; 737 } 738 if (status == TCL_BREAK || status == TCL_RETURN) { 739 return 1; /* abort! */ 740 } 741 } 742 return 0; /* keep going... */ 743 } -
trunk/optimizer/src/rp_tcloptions.c
r897 r898 23 23 * Built-in types: 24 24 */ 25 RpCustomTclOptionParse RpOption_ParseBoolean; 26 RpCustomTclOptionGet RpOption_GetBoolean; 27 RpTclOptionType RpOption_Boolean = { 28 "boolean", RpOption_ParseBoolean, RpOption_GetBoolean, NULL 29 }; 30 25 31 RpCustomTclOptionParse RpOption_ParseInt; 26 32 RpCustomTclOptionGet RpOption_GetInt; … … 175 181 /* 176 182 * ====================================================================== 183 * BOOLEAN 184 * ====================================================================== 185 */ 186 int 187 RpOption_ParseBoolean(interp, valObj, cdata, offset) 188 Tcl_Interp *interp; /* interpreter handling this request */ 189 Tcl_Obj *valObj; /* set option to this new value */ 190 ClientData cdata; /* save in this data structure */ 191 int offset; /* save at this offset in cdata */ 192 { 193 int *ptr = (int*)(cdata+offset); 194 if (Tcl_GetBooleanFromObj(interp, valObj, ptr) != TCL_OK) { 195 return TCL_ERROR; 196 } 197 return TCL_OK; 198 } 199 200 int 201 RpOption_GetBoolean(interp, cdata, offset) 202 Tcl_Interp *interp; /* interpreter handling this request */ 203 ClientData cdata; /* get from this data structure */ 204 int offset; /* get from this offset in cdata */ 205 { 206 int *ptr = (int*)(cdata+offset); 207 Tcl_SetObjResult(interp, Tcl_NewBooleanObj(*ptr)); 208 return TCL_OK; 209 } 210 211 /* 212 * ====================================================================== 177 213 * INTEGER 178 214 * ====================================================================== … … 335 371 *(char***)(cdata+offset) = NULL; 336 372 } 373 374 /* 375 * ====================================================================== 376 * CHOICES 377 * ====================================================================== 378 */ 379 int 380 RpOption_ParseChoices(interp, valObj, cdata, offset) 381 Tcl_Interp *interp; /* interpreter handling this request */ 382 Tcl_Obj *valObj; /* set option to this new value */ 383 ClientData cdata; /* save in this data structure */ 384 int offset; /* save at this offset in cdata */ 385 { 386 char **ptr = (char**)(cdata+offset); 387 char *value = Tcl_GetStringFromObj(valObj, (int*)NULL); 388 *ptr = strdup(value); 389 return TCL_OK; 390 } 391 392 int 393 RpOption_GetChoices(interp, cdata, offset) 394 Tcl_Interp *interp; /* interpreter handling this request */ 395 ClientData cdata; /* get from this data structure */ 396 int offset; /* get from this offset in cdata */ 397 { 398 char *ptr = (char*)(cdata+offset); 399 Tcl_SetObjResult(interp, Tcl_NewStringObj(ptr,-1)); 400 return TCL_OK; 401 } 402 403 void 404 RpOption_CleanupChoices(cdata, offset) 405 ClientData cdata; /* cleanup in this data structure */ 406 int offset; /* cleanup at this offset in cdata */ 407 { 408 char **ptr = (char**)(cdata+offset); 409 if (*ptr != NULL) { 410 free((char*)(*ptr)); 411 *ptr = NULL; 412 } 413 } -
trunk/optimizer/src/rp_tcloptions.h
r897 r898 49 49 char *optname; /* name of option: -switch */ 50 50 RpTclOptionType *typePtr; /* type of this switch */ 51 ClientData extraInfo; /* extra data needed for switch type */52 51 int offset; /* location of data within struct */ 53 52 } RpTclOption; … … 56 55 * Built-in types defined in rp_tcloptions.c 57 56 */ 57 extern RpTclOptionType RpOption_Boolean; 58 #define RP_OPTION_BOOLEAN &RpOption_Boolean 59 58 60 extern RpTclOptionType RpOption_Int; 59 61 #define RP_OPTION_INT &RpOption_Int … … 67 69 extern RpTclOptionType RpOption_List; 68 70 #define RP_OPTION_LIST &RpOption_List 71 72 extern RpTclOptionType RpOption_Choices; 73 #define RP_OPTION_CHOICES &RpOption_Choices 69 74 70 75 /* -
trunk/optimizer/tests/aaa.test
r897 r898 43 43 test aaa-1.4 {optimizer creation takes certain args} { 44 44 list [catch {Rappture::optimizer -foo} result] $result 45 } {1 {bad option "-foo": should be - using}}45 } {1 {bad option "-foo": should be -tool, -using}} 46 46 47 47 test aaa-1.5 {optimizer creation: -using requires a value} { … … 55 55 test aaa-1.7 {optimizer creation: extra args are processed} { 56 56 list [catch {Rappture::optimizer -using pgapack -foo bar} result] $result 57 } {1 {bad option "-foo": should be - using}}57 } {1 {bad option "-foo": should be -tool, -using}} 58 58 59 59 test aaa-1.8 {optimizer can be destroyed without dumping core} {
Note: See TracChangeset
for help on using the changeset viewer.