/*File: rosenbrock1.c Purpose: it is the GA version of rosenbrock1.c to test the class TaoGAApplication. Acknowledgement: the code was originally developed by Dr.Steve Bensor and others at ANL and modified by Dr. Limin Zhang and Dr. Jarek Nieplochai from PNNL. */ /************************************************************** Author: Limin Zhang, Ph.D. Mathematics Department Columbia Basin College Pasco, WA 99301 Limin.Zhang@cbc2.org Mentor: Jarek Naplocha, Ph.D. Environmental Molecular Science Laboratory Pacific Northwest National Laboratory Richland, WA 99352 Date: 4/22/2002 Purpose: to design and implement an application for between TAO and global arrays. **************************************************************/ /*$Id: s.rosenbrock1.c 1.41 02/02/14 14:22:13-06:00 sarich@holmes.mcs.anl.gov $*/ /* Program usage: mpirun -machinefile m -np 1 rosenbrock1 [-help] [all TAO options] */ /* Program usage: mpirun -machinefile m -np 4 rosenbrock1 [-help] [all TAO options] */ /*MPI header*/ #include <mpi.h> /* Include "tao.h" so we can use TAO solvers. */ #include "tao.h" //for tao initialization /*include "ga.h" so that we can use GA*/ #include "ga.h" #include "taovec_ga.h" #include "taoapp_ga.h" #include "macdecls.h" /*some standard C header files */ #include <iostream> #include <stdio.h> #include <stdlib.h> //for malloc function #include <math.h> static char help[] = "This example demonstrates use of the TAO package to \n\ solve an unconstrained minimization problem on a single processor. We \n\ minimize the extended Rosenbrock function: \n\ sum_{i=0}^{n/2-1} ( alpha*(x_{2i+1}-x_{2i}^2)^2 + (1-x_{2i})^2 ) \n"; /*T Concepts: TAO - Solving an unconstrained minimization problem Routines: TaoInitialize(); TaoFinalize(); TaoSetFromOptions(); Routines: TaoGAApplicationCreate(); TaoSetApplication(); Routines: TaoCreate(); TaoSetGAFunctionGradient(); Routines: TaoSetGAHessian(); TaoSetGAInitialVector(); Routines: TaoSolve(); TaoDestroy(); TaoApplicationDestroy(); Routines: TaoGetTerminationReason(); Processors: 1 T*/ /* User-defined application context - contains data needed by the application-provided call-back routines that evaluate the function, gradient, and hessian. */ typedef struct { int n; /* dimension */ double alpha; /* condition parameter */ } AppCtx; /* -------------- User-defined routines ---------- */ int FormFunctionGradient (TAO_GA_APPLICATION, GAVec, double *, GAVec, void *); int SetVariableBounds (TAO_GA_APPLICATION, GAVec, GAVec, void*); int main (int argc, char **argv) { int info; /* used to check for functions returning nonzeros */ GAVec ga_x; /* solution, gradient vectors */ TAO_SOLVER tao; /* TAO_SOLVER solver context */ TAO_GA_APPLICATION taoapp; /* TAO application context */ TaoTerminateReason reason; AppCtx user; /* user-defined application context */ /*initialize GA and MPI */ int heap = 20000, stack = 20000; int me, nproc; MPI_Init (&argc, &argv); /* initialize MPI */ GA_Initialize (); /* initialize GA */ me = GA_Nodeid (); nproc = GA_Nnodes (); if (me == 0) { if (GA_Uses_fapi ()) GA_Error ("Program runs with C array API only", 0); printf ("Using %ld processes\n", (long) nproc); fflush (stdout); } heap /= nproc; stack /= nproc; if (!MA_init (MT_F_DBL, stack, heap)) GA_Error ("MA_init failed", stack + heap); /* initialize memory allocator */ /* Initialize TAO */ TaoInitialize (&argc, &argv, (char *) 0, help); /* Initialize problem parameters */ user.n = 2; user.alpha = 99.0; /* Allocate vectors for the solution and gradient */ int ndim = 1, dims[2], type = C_DBL; dims[0] = user.n; ga_x = NGA_Create (type, ndim, dims, "GA_X", NULL); if (!ga_x) GA_Error ("rosenbrock1.main::NGA_Create ga_x", ga_x); /* ga_g = GA_Duplicate (ga_x, "GA_G"); if (!ga_g) GA_Error ("rosenbrock1.main::NGA_Create ga_g", ga_g); */ /* The TAO code begins here */ /* Create TAO solver with desired solution method */ info = TaoCreate (MPI_COMM_WORLD, "tao_blmvm", &tao); CHKERRQ(info); info = TaoGAApplicationCreate (MPI_COMM_WORLD, &taoapp); CHKERRQ(info); info = TaoGAAppSetInitialSolutionVec(taoapp, ga_x); CHKERRQ(info); info = TaoGAAppSetVariableBoundsRoutine(taoapp, SetVariableBounds, (void*)&user); CHKERRQ(info); /* Set routines for function, gradient */ info = TaoGAAppSetObjectiveAndGradientRoutine (taoapp, FormFunctionGradient, (void *) &user); CHKERRQ(info); /* Check for TAO command line options */ info = TaoSetFromOptions (tao); CHKERRQ(info); /* SOLVE THE APPLICATION */ info = TaoSolveGAApplication (taoapp,tao); CHKERRQ(info); /* To View TAO solver information use */ info = TaoView(tao); CHKERRQ(info); /* Get termination information */ info = TaoGetTerminationReason (tao, &reason); CHKERRQ(info); if (reason <= 0) printf ("Try a different TAO method, adjust some parameters, or check the function evaluation routines\n"); /*output the solutions */ if (me == 0) printf ("The solution is :\n"); GA_Print (ga_x); /* Free TAO data structures */ info = TaoDestroy (tao); CHKERRQ(info); info = TaoGAAppDestroy (taoapp); CHKERRQ(info); /* Free GA data structures */ GA_Destroy (ga_x); /* Finalize TAO, GA, and MPI */ TaoFinalize (); GA_Terminate (); MPI_Finalize (); if (me == 0) printf ("Normal exit...\n"); return 0; } /* -------------------------------------------------------------------- */ /* FormFunctionGradient - Evaluates the function, f(X), and gradient, G(X). Input Parameters: . tao - the TAO_SOLVER context . ga_X - input vector . ptr - optional user-defined context, as set by TaoSetFunctionGradient() Output Parameters: . ga_G - vector containing the newly evaluated gradient . f - function value Note: Some optimization methods ask for the function and the gradient evaluation at the same time. Evaluating both at once may be more efficient that evaluating each separately. */ int FormFunctionGradient (TAO_GA_APPLICATION gaapp, GAVec ga_X, double *f, GAVec ga_G, void *ptr) { AppCtx *user = (AppCtx *) ptr; int i, nn = user->n / 2; double ff = 0., t1, t2, alpha = user->alpha; double glocal[2],xlocal[2]; int me = GA_Nodeid (); GA_Sync(); if(me ==0){ /* given the size of the problem we will execute this part on process 0 only */ int lo=0,hi=1; /* range of array indices */ NGA_Get (ga_X, &lo, &hi, xlocal, &hi); /* Compute G(X) */ for (i=0; i<nn; i++){ t1 = xlocal[2*i+1]-xlocal[2*i]*xlocal[2*i]; t2= 1-xlocal[2*i]; ff += alpha*t1*t1 + t2*t2; glocal[2*i] = -4*alpha*t1*xlocal[2*i]-2.0*t2; glocal[2*i+1] = 2*alpha*t1; } GA_Init_fence(); NGA_Put(ga_G, &lo, &hi, glocal, &hi); GA_Fence(); } /* broadcast the result to everybody */ GA_Brdcst(&ff, sizeof(double), 0); *f = ff; return 0; } int SetVariableBounds(TAO_GA_APPLICATION gaapp, GAVec ga_xl, GAVec ga_xu, void *ctx) { double lb = 0.0, ub = 2.0; GA_Fill(ga_xl, (void*)&lb); GA_Fill(ga_xu, (void*)&ub); return 0; }