Changeset 899
- Timestamp:
- Feb 22, 2008, 2:08:40 PM (16 years ago)
- Location:
- trunk/optimizer
- Files:
-
- 2 added
- 1 deleted
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/optimizer/examples/simple.tcl
r898 r899 48 48 Rappture::optimizer optim -tool $tool -using pgapack 49 49 50 optim add number input.number( temperature) -min 200 -max 40051 optim add number input.number( Ef) -min 0 -max 1.152 optim configure - popsize 500 -maxruns 550 optim add number input.number(x1) -min -2 -max 2 51 optim add number input.number(x2) -min -2 -max 2 52 optim configure -operation minimize -popsize 100 -maxruns 200 53 53 54 set status [optim perform -updatecommand {puts "checking"}] 54 set status [optim perform \ 55 -fitness output.number(f).current \ 56 -updatecommand {puts "checking"}] 55 57 56 58 puts "done: $status" -
trunk/optimizer/examples/tool.xml
r898 r899 2 2 <run> 3 3 <tool> 4 <about>Press Simulate to view results.</about> 5 <command>tclsh @tool/fermi.tcl @driver</command> 4 <about>This tool is a good example for optimization. It implements the Rosenbrock function: 5 6 f(x1,x2) = 100(x2 - x1**2)**2 + (1-x1)**2 7 8 This has a minimum at (x1,x2) = (1,1). 9 10 Press Simulate to view results.</about> 11 <command>tclsh @tool/rosenbrock.tcl @driver</command> 6 12 </tool> 7 13 <input> 8 <number id=" temperature">14 <number id="x1"> 9 15 <about> 10 <label> Ambient temperature</label>11 <description> Temperature of the environment.</description>16 <label>X1</label> 17 <description>first coordinate</description> 12 18 </about> 13 <units>K</units> 14 <min>0K</min> 15 <max>500K</max> 16 <default>300K</default> 17 <preset> 18 <value>300K</value> 19 <label>300K (room temperature)</label> 20 </preset> 21 <preset> 22 <value>77K</value> 23 <label>77K (liquid nitrogen)</label> 24 </preset> 25 <preset> 26 <value>4.2K</value> 27 <label>4.2K (liquid helium)</label> 28 </preset> 19 <min>-2</min> 20 <max>2</max> 21 <default>0</default> 29 22 </number> 30 <number id=" Ef">23 <number id="x2"> 31 24 <about> 32 <label> Fermi Level</label>33 <description> Energy at center of distribution.</description>25 <label>X2</label> 26 <description>second coordinate</description> 34 27 </about> 35 <units>eV</units> 36 <min>-10eV</min> 37 <max>10eV</max> 38 <default>0eV</default> 28 <min>-2</min> 29 <max>2</max> 30 <default>0</default> 39 31 </number> 40 32 </input> 41 33 </run> 42 -
trunk/optimizer/src/plugin_pgapack.c
r898 r899 15 15 */ 16 16 #include "pgapack.h" 17 #include "rp_optimizer _plugin.h"17 #include "rp_optimizer.h" 18 18 19 19 typedef struct PgapackData { … … 92 92 */ 93 93 RpOptimStatus 94 PgapackRun(envPtr, evalProc )94 PgapackRun(envPtr, evalProc, fitnessExpr) 95 95 RpOptimEnv *envPtr; /* optimization environment */ 96 96 RpOptimEvaluator *evalProc; /* call this proc to run tool */ 97 char *fitnessExpr; /* fitness function in string form */ 97 98 { 98 99 PgapackData *dataPtr =(PgapackData*)envPtr->pluginData; … … 109 110 PGASetPopSize(ctx, dataPtr->popSize); 110 111 PGASetPopReplaceType(ctx, dataPtr->popRepl); 112 PGASetCrossoverType(ctx, PGA_CROSSOVER_UNIFORM); 111 113 112 114 PGASetUserFunction(ctx, PGA_USERFUNCTION_CREATESTRING, PgapCreateString); … … 118 120 PGASetUserFunction(ctx, PGA_USERFUNCTION_BUILDDATATYPE, PgapBuildDT); 119 121 120 envPtr->evalProc = evalProc; /* call this later for evaluations */ 122 envPtr->evalProc = evalProc; /* plug these in for later during eval */ 123 envPtr->fitnessExpr = fitnessExpr; 121 124 122 125 /* -
trunk/optimizer/src/rp_optimizer.c
r898 r899 33 33 */ 34 34 RpOptimEnv* 35 RpOptimCreate(pluginData, cleanupProc) 36 ClientData pluginData; /* special data created for this env */ 37 RpOptimCleanup *cleanupProc; /* routine to clean up pluginData */ 35 RpOptimCreate(pluginDefn) 36 RpOptimPlugin *pluginDefn; /* plug-in handling this optimization */ 38 37 { 39 38 RpOptimEnv *envPtr; 40 39 envPtr = (RpOptimEnv*)malloc(sizeof(RpOptimEnv)); 41 envPtr->pluginData = pluginData; 42 envPtr->cleanupProc = cleanupProc; 43 envPtr->toolData = NULL; 40 41 envPtr->pluginDefn = pluginDefn; 42 envPtr->pluginData = NULL; 43 envPtr->toolData = NULL; 44 45 if (pluginDefn->initProc) { 46 envPtr->pluginData = (*pluginDefn->initProc)(); 47 } 44 48 45 49 envPtr->numParams = 0; … … 211 215 int n; 212 216 217 if (envPtr->pluginDefn && envPtr->pluginDefn->cleanupProc) { 218 (*envPtr->pluginDefn->cleanupProc)(envPtr->pluginData); 219 } 213 220 for (n=0; n < envPtr->numParams; n++) { 214 221 RpOptimCleanupParam(envPtr->paramList[n]); 215 }216 if (envPtr->cleanupProc) {217 (*envPtr->cleanupProc)(envPtr->pluginData);218 222 } 219 223 free(envPtr->paramList); -
trunk/optimizer/src/rp_optimizer.h
r898 r899 23 23 #include <string.h> 24 24 #include <malloc.h> 25 #include "rp_tcloptions.h" 25 26 26 27 /* … … 48 49 49 50 typedef RpOptimStatus (RpOptimHandler) _ANSI_ARGS_(( 50 struct RpOptimEnv *envPtr, RpOptimEvaluator *evalProc)); 51 struct RpOptimEnv *envPtr, RpOptimEvaluator *evalProc, 52 char *fitnessExpr)); 53 54 /* 55 * Each optimization package is plugged in to this infrastructure 56 * by defining the following data at the top of rp_optimizer_tcl.c 57 */ 58 typedef struct RpOptimPlugin { 59 char *name; /* name of this package for -using */ 60 RpOptimInit *initProc; /* initialization routine */ 61 RpOptimHandler *runProc; /* handles the core optimization */ 62 RpOptimCleanup *cleanupProc; /* cleanup routine */ 63 RpTclOption *optionSpec; /* specs for config options */ 64 } RpOptimPlugin; 51 65 52 66 /* … … 98 112 */ 99 113 typedef struct RpOptimEnv { 114 RpOptimPlugin *pluginDefn; /* plug-in handling this optimization */ 115 ClientData pluginData; /* data created by plugin init routine */ 100 116 RpOptimEvaluator *evalProc; /* called during optimization to do run */ 101 ClientData pluginData; /* data created by plugin init routine */ 102 RpOptimCleanup *cleanupProc; /* cleanup routine for pluginData */ 117 char *fitnessExpr; /* fitness function in string form */ 103 118 ClientData toolData; /* data used during tool execution */ 104 119 RpOptimParam **paramList; /* list of input parameters to vary */ … … 110 125 * Here are the functions in the API: 111 126 */ 112 EXTERN RpOptimEnv* RpOptimCreate _ANSI_ARGS_((ClientData pluginData, 113 RpOptimCleanup *cleanupProc)); 127 EXTERN RpOptimEnv* RpOptimCreate _ANSI_ARGS_((RpOptimPlugin *pluginDefn)); 114 128 115 129 EXTERN RpOptimParam* RpOptimAddParamNumber _ANSI_ARGS_((RpOptimEnv *envPtr, -
trunk/optimizer/src/rp_optimizer_tcl.c
r898 r899 15 15 */ 16 16 #include "rp_optimizer.h" 17 #include "rp_optimizer_plugin.h"18 17 19 18 /* … … 35 34 }; 36 35 37 typedef struct RpOptimPluginData {38 RpOptimPlugin *pluginDefn; /* points back to plugin definition */39 ClientData clientData; /* data needed for particular plugin */40 } RpOptimPluginData;41 42 36 typedef struct RpOptimToolData { 43 37 Tcl_Interp *interp; /* interp handling this tool */ … … 67 61 static int RpOptimInstanceCmd _ANSI_ARGS_((ClientData clientData, 68 62 Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); 69 static void RpOptimInstanceCleanup _ANSI_ARGS_((ClientData cdata));70 63 static RpOptimStatus RpOptimizerPerformInTcl _ANSI_ARGS_((RpOptimEnv *envPtr, 71 64 RpOptimParam *values, int numValues, double *fitnessPtr)); 72 static int RpOptimizerUpdateInTcl _ANSI_ARGS_((RpOptimEnv *envPtr));73 65 74 66 #ifdef BUILD_Rappture … … 129 121 RpOptimEnv* envPtr; 130 122 RpOptimPlugin* pluginPtr; 131 RpOptimPluginData* pluginDataPtr;132 123 RpOptimToolData* toolDataPtr; 133 124 … … 222 213 * Create an optimizer and install a Tcl command to access it. 223 214 */ 224 pluginDataPtr = (RpOptimPluginData*)malloc(sizeof(RpOptimPluginData)); 225 pluginDataPtr->pluginDefn = usingPluginPtr; 226 pluginDataPtr->clientData = NULL; 227 if (usingPluginPtr->initProc) { 228 pluginDataPtr->clientData = (*usingPluginPtr->initProc)(); 229 } 230 envPtr = RpOptimCreate((ClientData)pluginDataPtr, RpOptimInstanceCleanup); 215 envPtr = RpOptimCreate(usingPluginPtr); 231 216 232 217 toolDataPtr = (RpOptimToolData*)malloc(sizeof(RpOptimToolData)); … … 298 283 * <name> get ?<glob>? ?-option? 299 284 * <name> configure ?-option? ?value -option value ...? 300 * <name> perform ?-tool <tool>? ?-updatecommand <varName>? 285 * <name> perform ?-tool <tool>? ?-fitness <expr>? \ 286 * ?-updatecommand <varName>? 301 287 * <name> using 302 288 * … … 314 300 { 315 301 RpOptimEnv* envPtr = (RpOptimEnv*)cdata; 316 RpOptimPluginData* pluginDataPtr = (RpOptimPluginData*)envPtr->pluginData;317 302 RpOptimToolData* toolDataPtr = (RpOptimToolData*)envPtr->toolData; 318 303 319 304 int n, j, nvals, nmatches; 320 char *option, *type, *path ;305 char *option, *type, *path, *fitnessExpr; 321 306 RpOptimParam *paramPtr; 322 307 RpOptimParamString *strPtr; … … 510 495 */ 511 496 else if (*option == 'c' && strcmp(option,"configure") == 0) { 512 optSpecPtr = pluginDataPtr->pluginDefn->optionSpec;497 optSpecPtr = envPtr->pluginDefn->optionSpec; 513 498 if (objc == 2) { 514 499 /* report all values: -option val -option val ... */ … … 519 504 for (n=0; optSpecPtr[n].optname; n++) { 520 505 if (RpTclOptionGet(interp, optSpecPtr, 521 (ClientData) pluginDataPtr->clientData,506 (ClientData)envPtr->pluginData, 522 507 optSpecPtr[n].optname) != TCL_OK) { 523 508 Tcl_DecrRefCount(rval); … … 543 528 option = Tcl_GetStringFromObj(objv[2], (int*)NULL); 544 529 return RpTclOptionGet(interp, optSpecPtr, 545 (ClientData) pluginDataPtr->clientData, option);530 (ClientData)envPtr->pluginData, option); 546 531 } 547 532 else { 548 533 return RpTclOptionsProcess(interp, objc-2, objv+2, 549 optSpecPtr, pluginDataPtr->clientData);550 } 551 } 552 553 /* 554 * OPTION: perform ?-tool name? ?- updatecommand name?534 optSpecPtr, envPtr->pluginData); 535 } 536 } 537 538 /* 539 * OPTION: perform ?-tool name? ?-fitness expr? ?-updatecommand name? 555 540 */ 556 541 else if (*option == 'p' && strcmp(option,"perform") == 0) { 557 542 /* use this tool by default */ 558 543 toolPtr = toolDataPtr->toolPtr; 544 545 /* no -fitness function by default */ 546 fitnessExpr = NULL; 559 547 560 548 /* no -updatecommand by default */ … … 574 562 n += 2; 575 563 } 564 else if (strcmp(option,"-fitness") == 0) { 565 fitnessExpr = Tcl_GetStringFromObj(objv[n+1], (int*)NULL); 566 n += 2; 567 } 576 568 else if (strcmp(option,"-updatecommand") == 0) { 577 569 updateCmdPtr = objv[n+1]; … … 580 572 else { 581 573 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), 582 "bad option \"", option, "\": should be - tool,"574 "bad option \"", option, "\": should be -fitness, -tool," 583 575 " -updatecommand", (char*)NULL); 584 576 return TCL_ERROR; … … 587 579 588 580 /* 589 * Must have a tool object a t this point, or else we590 * don't know what to optimize.581 * Must have a tool object and a fitness function at this point, 582 * or else we don't know what to optimize. 591 583 */ 592 584 if (toolPtr == NULL) { … … 596 588 return TCL_ERROR; 597 589 } 590 if (fitnessExpr == NULL) { 591 Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), 592 "missing -fitness function for optimization", 593 (char*)NULL); 594 return TCL_ERROR; 595 } 598 596 599 597 Tcl_IncrRefCount(toolPtr); … … 604 602 605 603 /* call the main optimization routine here */ 606 status = (* pluginDataPtr->pluginDefn->runProc)(envPtr,607 RpOptimizerPerformInTcl );604 status = (*envPtr->pluginDefn->runProc)(envPtr, 605 RpOptimizerPerformInTcl, fitnessExpr); 608 606 609 607 Tcl_DecrRefCount(toolPtr); … … 639 637 return TCL_ERROR; 640 638 } 641 Tcl_SetResult(interp, pluginDataPtr->pluginDefn->name, TCL_STATIC);639 Tcl_SetResult(interp, envPtr->pluginDefn->name, TCL_STATIC); 642 640 return TCL_OK; 643 641 } … … 650 648 } 651 649 return TCL_OK; 652 }653 654 /*655 * ----------------------------------------------------------------------656 * RpOptimInstanceCleanup()657 *658 * Called whenever a optimizer environment is being delete to clean659 * up any plugin data associated with it. It's a little convoluted.660 * Here's the sequence: A Tcl command is deleted, RpOptimCmdDelete()661 * gets called to clean it up, RpOptimDelete() is called within that,662 * and this method gets called to clean up the client data associated663 * with the underlying environment.664 * ----------------------------------------------------------------------665 */666 static void667 RpOptimInstanceCleanup(cdata)668 ClientData cdata; /* plugin data being deleted */669 {670 RpOptimPluginData *pluginDataPtr = (RpOptimPluginData*)cdata;671 672 /* if there are config options, clean them up first */673 if (pluginDataPtr->pluginDefn->optionSpec) {674 RpTclOptionsCleanup(pluginDataPtr->pluginDefn->optionSpec,675 pluginDataPtr->clientData);676 }677 678 /* call a specialized cleanup routine to handle the rest */679 if (pluginDataPtr->pluginDefn->cleanupProc) {680 (*pluginDataPtr->pluginDefn->cleanupProc)(pluginDataPtr->clientData);681 }682 pluginDataPtr->clientData = NULL;683 684 /* free the container */685 free((char*)pluginDataPtr);686 650 } 687 651 … … 706 670 double *fitnessPtr; /* returns: computed value of fitness func */ 707 671 { 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 { 672 RpOptimStatus result = RP_OPTIM_SUCCESS; 727 673 RpOptimToolData *toolDataPtr = (RpOptimToolData*)envPtr->toolData; 728 int status; 729 674 Tcl_Interp *interp = toolDataPtr->interp; 675 int n, status; 676 #define MAXBUILTIN 10 677 int objc; Tcl_Obj **objv, *storage[MAXBUILTIN], *getcmd[3]; 678 int rc; Tcl_Obj **rv; 679 Tcl_Obj *dataPtr; 680 char *out; 681 682 /* 683 * Set up the arguments for a Tcl evaluation. 684 */ 685 objc = 2*numValues + 2; /* "tool run" + (name value)*numValues */ 686 if (objc > MAXBUILTIN) { 687 objv = (Tcl_Obj**)malloc(objc*sizeof(Tcl_Obj)); 688 } else { 689 objv = storage; 690 } 691 objv[0] = toolDataPtr->toolPtr; 692 objv[1] = Tcl_NewStringObj("run",-1); Tcl_IncrRefCount(objv[1]); 693 for (n=0; n < numValues; n++) { 694 objv[2*n+2] = Tcl_NewStringObj(values[n].name, -1); 695 Tcl_IncrRefCount(objv[2*n+2]); 696 697 switch (values[n].type) { 698 case RP_OPTIMPARAM_NUMBER: 699 objv[2*n+3] = Tcl_NewDoubleObj(values[n].value.dval); 700 Tcl_IncrRefCount(objv[2*n+3]); 701 break; 702 case RP_OPTIMPARAM_STRING: 703 objv[2*n+3] = Tcl_NewStringObj(values[n].value.sval.str,-1); 704 Tcl_IncrRefCount(objv[2*n+3]); 705 break; 706 default: 707 panic("bad parameter type in RpOptimizerPerformInTcl()"); 708 } 709 } 710 711 /* 712 * Invoke the tool and pick apart its results. 713 */ 714 status = Tcl_EvalObjv(interp, objc, objv, TCL_EVAL_GLOBAL); 715 716 if (status != TCL_OK) { 717 result = RP_OPTIM_FAILURE; 718 fprintf(stderr, "== JOB FAILED: %s\n", Tcl_GetStringResult(interp)); 719 } else { 720 dataPtr = Tcl_GetObjResult(interp); 721 /* hang on to this while we pick it apart into rv[] */ 722 Tcl_IncrRefCount(dataPtr); 723 724 if (Tcl_ListObjGetElements(interp, dataPtr, &rc, &rv) != TCL_OK) { 725 result = RP_OPTIM_FAILURE; 726 fprintf(stderr, "== JOB FAILED: %s\n", Tcl_GetStringResult(interp)); 727 } else if (rc != 2 728 || Tcl_GetIntFromObj(interp, rv[0], &status) != TCL_OK) { 729 result = RP_OPTIM_FAILURE; 730 fprintf(stderr, "== JOB FAILED: malformed result: expected {status output}\n"); 731 } else { 732 out = Tcl_GetStringFromObj(rv[1], (int*)NULL); 733 if (status != 0) { 734 result = RP_OPTIM_FAILURE; 735 fprintf(stderr, "== JOB FAILED with status code %d:\n%s\n", 736 status, out); 737 } else { 738 /* 739 * Get the output value from the tool output in the 740 * result we just parsed above: {status xmlobj} 741 * 742 * Eventually, we should write a whole parser to 743 * handle arbitrary fitness functions. For now, 744 * just query a single output value by calling: 745 * xmlobj get fitnessExpr 746 */ 747 getcmd[0] = rv[1]; 748 getcmd[1] = Tcl_NewStringObj("get",-1); 749 getcmd[2] = Tcl_NewStringObj(envPtr->fitnessExpr,-1); 750 for (n=0; n < 3; n++) { 751 Tcl_IncrRefCount(getcmd[n]); 752 } 753 754 status = Tcl_EvalObjv(interp, 3, getcmd, TCL_EVAL_GLOBAL); 755 756 if (status != TCL_OK) { 757 result = RP_OPTIM_FAILURE; 758 fprintf(stderr, "== UNEXPECTED ERROR while extracting output value:%s\n", Tcl_GetStringResult(interp)); 759 } else if (Tcl_GetDoubleFromObj(interp, 760 Tcl_GetObjResult(interp), fitnessPtr) != TCL_OK) { 761 result = RP_OPTIM_FAILURE; 762 fprintf(stderr, "== ERROR while extracting output value:%s\n", Tcl_GetStringResult(interp)); 763 } 764 for (n=0; n < 3; n++) { 765 Tcl_DecrRefCount(getcmd[n]); 766 } 767 } 768 } 769 Tcl_DecrRefCount(dataPtr); 770 } 771 772 /* 773 * Clean up objects created for command invocation. 774 */ 775 for (n=1; n < objc; n++) { 776 Tcl_DecrRefCount(objv[n]); 777 } 778 if (objv != storage) { 779 free(objv); 780 } 781 782 /* 783 * If there's the -updatecommand was specified, execute it here 784 * to bring the application up-to-date and see if the user wants 785 * to abort. 786 */ 730 787 if (toolDataPtr->updateCmdPtr) { 731 788 status = Tcl_GlobalEvalObj(toolDataPtr->interp, … … 734 791 if (status == TCL_ERROR) { 735 792 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... */ 793 } 794 else if (status == TCL_BREAK || status == TCL_RETURN) { 795 return RP_OPTIM_ABORTED; 796 } 797 } 798 return RP_OPTIM_SUCCESS; 743 799 }
Note: See TracChangeset
for help on using the changeset viewer.