/* ADIFFSQP version0.9(experimental) Released March, 1997 */ /* source code: adiffsqp.c */ /* Copyright (c) 1997 by Mingyan D. Liu and Andre L. Tits */ /* All Rights Reserved */ #include #include #include #include "adiffsqp.h" int call_adifor( arg_name ) char * arg_name; { char str1[MAX_ID_LEN], str2[MAX_ID_LEN]; char strf[MAX_ID_LEN]; FILE *test; strcpy(str1,arg_name); strcat(str1,".adf"); strcpy(str2,"Adifor2.0 AD_SCRIPT="); strcat(str2,str1); strcpy(strf,"g_"); strcat(strf,arg_name); strcat(strf,"dmy.f"); fprintf(stdout,"Now calling Adifor2.0 to generate gradient code\n"); system(str2); test=fopen(strf,"r"); if (test != NULL) { fclose(test); printf("DONE\n"); return(0); } else return(1); } MatchNode *CallList, *FnList, *ProcessList; int user_asked = 0; int mode; char hold_nparam[MAX_ID_LEN]; char obj_name[MAX_ID_LEN], cntr_name[MAX_ID_LEN]; char *arg[100]; main(argc, argv) int argc; char *argv[]; { FILE *inpf, *outf; int exitcode; int create_list(), change_name(),change_confirm(),conversion(); int call_adifor(); char outstr[MAX_ID_LEN]; int i; if (argc <= 1) { fprintf(stderr, "%s%s%s", "adiffsqp: one or more parameters required.\n", "Usage: adiffsqp source_file1,[source_file2],", "...[source_filen]\n"); return(1); } if ((inpf = fopen(argv[1], "r")) == (FILE *)NULL) { fprintf(stderr, "adiffsqp: Cannot open input file %s.\n", argv[1]); return(1); } strcpy(outstr, "ad_"); strcat(outstr, argv[1]); if ((outf = fopen(outstr, "w")) == (FILE *)NULL) { fprintf(stderr, "adiffsqp: Cannot open output file %s.\n", outstr); fclose(inpf); return(1); } if (argc == 2) { mode = 0; for (i=0; i<=argc-2; i++) arg[i]="\0"; } else { mode = 1; for (i=0; i<=argc-3; i++) { arg[i]=argv[i+2]; strcat(arg[i],"\0"); } } fprintf(stdout, " \n\ ADIFFSQP Version 0.9(experimental) \n\ \n\ Institute for Systems Research \n\ University of Maryland \n\ College Park, MD 20742 \n\ \n\ March 1997 \n\ \n\ Copyright (c) 1997 by Mingyan D. Liu and Andre L. Tits.\n\ All Rights Reserved.\n" ); exitcode = create_list(inpf, outf); if (exitcode != 0) { error("Conversion failed in creating a filename list.\n"); exit(exitcode); } exitcode = change_name(); if (exitcode != 0) { error("Fail in making name changes.\n"); exit(exitcode); } exitcode = change_confirm(); if (exitcode != 0) { error("User aborted conversion. \n"); exit(exitcode); } exitcode = conversion(inpf, outf, argc, argv[1]); if (exitcode != 0) { error("Conversion failed in creating output file.\n"); exit(exitcode); } fclose(inpf); fclose(outf); fprintf(stdout, "********** CONGRATULATIONS!!\n"); fprintf(stdout, "********** Conversion successful.\n"); fprintf(stdout, "\n"); return(exitcode); } int create_list(inpf, outf) FILE *inpf, *outf; { int x,i; int stat, cardtype; char card[MAX_CARD_LEN],rmcard[MAX_CARD_LEN]; char nameparms[5][MAX_ID_LEN], hold_subname[MAX_ID_LEN]; char typeparms[5],sub_name[MAX_ID_LEN]; CallList = initmatchtable(); FnList = initmatchtable(); if (getcard(inpf, card) == 1) { error("Source file is empty."); return(1); } strncpy(sub_name,arg,(strlen(arg)-2)); sub_name[strlen(arg)-2]='\0'; strcat(sub_name,"sub.f"); do { stat = getcard(inpf, card); switch (classify(card)) { case CALL: if (strcmp(getcalledfnname(card+6), "FFSQP")==0) { if (numparms(card+6) != 27) { errorl("Number of parameters to call FFSQP must be 27."); return(1); } else { CallList = newmatchnode(CallList); addfntonode(CallList, getparmname(card+6, 24)); strcpy(obj_name, getparmname(card+6, 24)); addgrtonode(CallList, getparmname(card+6, 26)); CallList = newmatchnode(CallList); addfntonode(CallList, getparmname(card+6, 25)); strcpy(cntr_name, getparmname(card+6, 25)); addgrtonode(CallList, getparmname(card+6, 27)); } strcpy(hold_nparam,getparmname(card+6, 1)); } break; case SUBR: x = numparms(card+6); strcpy(hold_subname, getsubname(card+6)); if ( (x == 4 && findfnname(CallList, hold_subname)!= NULL) || (x == 5 && findgrname(CallList, hold_subname)!= NULL) ) { for (i=0;i= 'i' && *nameparms[i] <= 'n' ) typeparms[i] = 'i'; else typeparms[i] = 'r'; } do { stat = getcard(inpf, card); cardtype = classify(card); if (cardtype == DATA) { rm_argument(card,rmcard); classifytypedata(rmcard+6, nameparms, typeparms, x); } } while (stat != 1 && cardtype == DATA); if (strncmp(typeparms, "iidde",x) == 0) { FnList = newmatchnode(FnList); if (x == 4) { addfntonode(FnList, hold_subname); addgrtonode(FnList, ""); } else { addgrtonode(FnList, hold_subname); addfntonode(FnList, ""); } } } break; } } while (stat != 1); return(0); } int change_name() { MatchNode *tmp,*tmp2; int found, lastmsg =0; char usr_ip[MAX_ID_LEN], hold_grname[MAX_ID_LEN]; tmp = FnList; ProcessList = initmatchtable(); while (tmp != NULL) { if (*(tmp->fn_name) != NULL) { tmp2 = findfnname(CallList, tmp->fn_name); if (tmp2 == (MatchNode *)NULL) { fprintf(stdout, "\nIf subroutine %s is an objective or constraint subroutine,\n", tmp->fn_name); fprintf(stdout, "then please enter the name for the gradient subroutine\n"); fprintf(stdout, "that will be created from it (press RETURN if this is not\n"); fprintf(stdout, "an objective or a constraint):\n"); lastmsg = 0; gets(usr_ip); fprintf(stdout, "\n"); strcpy(hold_grname,""); sscanf(usr_ip, "%s", hold_grname); if (*hold_grname != NULL) { ProcessList = newmatchnode(ProcessList); addfntonode(ProcessList, tmp->fn_name); addgrtonode(ProcessList, hold_grname); user_asked = 1; } } else { found = 0; while (tmp2 != (MatchNode *)NULL && found == 0) if (strcmp(tmp2->gr_name, "grcnfd") == 0 || strcmp(tmp2->gr_name, "grobfd") == 0) /* Go through list of FFSQP calls and see if a non-fd */ /* gradient call exists */ tmp2 = findfnname(tmp2->next, tmp->fn_name); else found = 1; if (tmp2 == (MatchNode *)NULL) { strcpy(hold_grname+1, tmp->fn_name); *hold_grname = 'g'; if (strlen(hold_grname) > 6) *(hold_grname + strlen(tmp->fn_name)) = NULL; if (lastmsg != 1) { fprintf(stdout, "\nLooks like you were calling FSQP's built-in finite \n"); fprintf(stdout, "differences method to evaluate the gradient of %s.\n", tmp->fn_name); fprintf(stdout, "I will create a new subroutine, called %s, to evaluate \n", hold_grname); fprintf(stdout, "this function.\n"); lastmsg = 1; } else { fprintf(stdout, "\nAs above, I will create %s to evaluate gradient of %s.\n", hold_grname, tmp->fn_name); } } else strcpy(hold_grname, tmp2->gr_name); ProcessList = newmatchnode(ProcessList); addfntonode(ProcessList, tmp->fn_name); addgrtonode(ProcessList, hold_grname); } } tmp = tmp->next; } return 0; } int change_confirm() { MatchNode *tmp, *last; int itemno, i; char fn_name[35], gr_name[35]; char usr_ip[MAX_ID_LEN], hold_grname[MAX_ID_LEN]; do { itemno = 1; fprintf(stdout, "\nThe following actions are being taken :\n"); fprintf(stdout, "\n\t Create objective or\n"); fprintf(stdout, "\t Gradient subroutine for constraint subroutine\n"); fprintf(stdout, "\t~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); tmp = ProcessList; while (tmp != NULL) { strncpy(fn_name, tmp->fn_name, 27); fn_name[27] = NULL; if (strlen(tmp->fn_name) > 27) strcat(fn_name, "..."); strncpy(gr_name, tmp->gr_name, 27); gr_name[27] = NULL; if (strlen(tmp->gr_name) > 27) strcat(gr_name, "..."); fprintf(stdout, "[%3d]\t%-34s%-34s\n", itemno++, gr_name, fn_name); tmp=tmp->next; } fprintf(stdout, "\nCAUTION: Any old gradient subroutines found in input file\n"); fprintf(stdout,"will be removed and replaced by those generated\n"); fprintf(stdout,"by Adifor2.0\n"); fprintf(stdout, "If you have gradient subroutines in a file other than this one, \n"); fprintf(stdout, "you must exclude those subroutines yourself before compiling.\n"); if (user_asked != 1 || itemno == 1) return 0; fprintf(stdout, "\nPress RETURN to continue\n"); fprintf(stdout, " or enter the line number of \n"); fprintf(stdout, "the gradient name you want to change: \n"); gets(usr_ip); i = atoi(usr_ip); if (i==0) return(0); if (i>=itemno) fprintf(stdout, "Invalid choice\n"); else { tmp = ProcessList; itemno = 1; last = NULL; while (itemno++ < i && tmp != NULL) { last = tmp; tmp=tmp->next; } fprintf(stdout, "\nChange %s to?\n", tmp->gr_name); fprintf(stdout, "(RETURN keeps the previous name; 0 deletes this entry)?\n"); gets(usr_ip); fprintf(stdout, "\n"); strcpy(hold_grname,""); sscanf(usr_ip, "%s", hold_grname); if (*hold_grname != NULL && *hold_grname != '0') { free(tmp->gr_name); addgrtonode(tmp, hold_grname); } else if (*hold_grname == '0') { free(tmp->gr_name); free(tmp->fn_name); if (last != NULL) last->next = tmp->next; else ProcessList = tmp->next; free(tmp); } } } while (i!=0 && i!=-1); return(i); } int dummy (arg_name,n) /* create a dummy main program for calling adifor */ char arg_name[]; int n; { FILE *fpt; char str1[MAX_ID_LEN]; char str2[MAX_ID_LEN]; strcpy(str1,arg_name); strcat(str1,"dmy.f"); strcpy(str2,arg_name); strcat(str2,"top"); fpt=fopen(str1,"w"); fprintf(fpt," program main\n"); fprintf(fpt," integer nparam,j\n"); fprintf(fpt," parameter (nparam=%d)\n",n); fprintf(fpt," double precision x(nparam),fj(2)\n"); fprintf(fpt," call %s(nparam,j,x,fj)\n",str2); fprintf(fpt," end\n"); fprintf(fpt,"c\n"); fprintf(fpt,"c\n"); fprintf(fpt," subroutine %s(nparam,j,x,fj)\n",str2); fprintf(fpt," integer nparam,j\n"); fprintf(fpt," double precision x(nparam),fj(2)\n"); fprintf(fpt," call %s(nparam,j,x,fj(1))\n",obj_name); fprintf(fpt," call %s(nparam,j,x,fj(2))\n",cntr_name); fprintf(fpt," end\n"); fclose (fpt); return(0); } int cmp( arg_name, argc ) /* create .cmp file required by adifor */ char arg_name[]; int argc; { char dummy[MAX_ID_LEN],strf[MAX_ID_LEN]; char str1[MAX_ID_LEN]; FILE *fpt, *fpt2; int i; strcpy(dummy,arg_name); strcat(dummy,"dmy.f"); strcpy(strf,arg_name); strcat(strf,".cmp"); strcpy(str1,arg_name); strcat(str1,"sub.f"); fpt=fopen(strf,"w"); fprintf(fpt,"%s\n",dummy); if ( (fpt2=fopen(str1,"r")) != NULL) fprintf(fpt,"%s\n",str1); fprintf(fpt,"# other\n"); if(mode==1) for(i=0;i<=argc-3;i++) { fprintf(fpt,"%s \n",arg[i]); if (i%5==0) fprintf(fpt,"\n"); } fclose (fpt); return(0); } int adf(arg_name,n) /* create .adf file required by adifor */ char arg_name[]; int n; { char strf[MAX_ID_LEN],prog[MAX_ID_LEN],top[MAX_ID_LEN]; FILE *fpt; strcpy(strf,arg_name); strcat(strf,".adf"); strcpy(prog,arg_name); strcat(prog,".cmp"); strcpy(top,arg_name); strcat(top,"top"); fpt=fopen(strf,"w"); fprintf(fpt,"AD_PROG = %s\n",prog); fprintf(fpt,"AD_TOP = %s\n",top); fprintf(fpt,"AD_IVARS = x\n"); fprintf(fpt,"AD_OVARS = fj\n"); fprintf(fpt,"AD_PMAX = %d\n",n); fprintf(fpt,"AD_OUTPUT_DIR = \n"); fclose (fpt); return(0); } int wt_sub(outf,fn_name,gr_name,n) /* create the interface gradient subroutine calling ad-generated code */ int n; FILE *outf; char fn_name[],gr_name[]; { char str1[MAX_ID_LEN]; int i; strcpy(str1,"g_"); strcat(str1,fn_name); fprintf(outf," subroutine %s(nparam,j,x,gradj,dummy)\n",gr_name); fprintf(outf," integer nparam,j\n"); fprintf(outf," double precision dummy,x(nparam),gradj(%d),\n",n); fprintf(outf," * g_x(%d,%d),gj\n",n,n); fprintf(outf," external dummy\n"); for(i=1;i<=n;i++) fprintf(outf," g_x(%d,%d)=1.0\n",i,i); fprintf(outf," call %s(nparam,nparam,j,x,g_x,nparam,gj,\n",str1); fprintf(outf," * gradj,nparam)\n"); fprintf(outf," return\n"); fprintf(outf," end\n"); return(0); } int delfile(arg_name, argc) /* delete all the used files */ char arg_name[]; int argc; { char str1[MAX_ID_LEN],str2[MAX_ID_LEN]; int i; strcpy(str1,arg_name); strcat(str1,"dmy"); strcpy(str2,str1); strcat(str2,".f"); unlink(str2); strcpy(str2,"g_"); strcat(str2,str1); strcpy(str1,str2); strcat(str2,".f"); unlink(str2); strcpy(str2,str1); strcat(str2,".A"); unlink(str2); strcpy(str2,str1); strcat(str2,".aux"); unlink(str2); strcpy(str1,arg_name); strcat(str1,".adf"); unlink(str1); strcpy(str1,arg_name); strcat(str1,".cmp"); unlink(str1); strcpy(str1,arg_name); strcat(str1,"sub.f"); unlink(str1); strcpy(str1,"g_"); strcat(str1,arg_name); strcat(str1,"sub"); strcpy(str2,str1); strcat(str2,".f"); unlink(str2); strcpy(str2,str1); strcat(str2,".A"); unlink(str2); strcpy(str2,str1); strcat(str2,".aux"); unlink(str2); if (mode==1) for (i=0; i<=argc-3; i++) { strcpy(str1, "g_"); strncpy(str2, arg[i], (strlen(arg[i])-2) ); str2[strlen(arg[i])-2]='\0'; strcat(str1,str2); strcat(str1, ".A"); unlink(str1); strcpy(str1, "g_"); strcat(str1,str2); strcat(str1, ".aux"); unlink(str1); } return(0); } int get_nparam(str) char *str; { char number[MAX_ID_LEN]; char *str1,*str2,*sp; int i,nparam; str1=str+strlen(hold_nparam); while(! isalnum(*str1)) str1++; str2=str1; while( *str2!=',') str2++; i=0; for( sp=str1; spfn_name,tmp->gr_name,nparam ); putcard(outf, card); putcard(subf,card); com_stat = 0; do { stat = getcard(inpf1, card); putcard(outf, card); putcard(subf,card); cardtype = classify(card); } while (stat != 1 && cardtype != END); } else if ((tmp = findgrname(ProcessList, getsubname(card+6)) ) != NULL) { do stat = getcard(inpf1, card); while (stat != 1 && classify(card) != END); } else { putcard(outf, card); putcard(subf, card); do { stat = getcard(inpf1, card); putcard(outf,card); putcard(subf,card); cardtype = classify(card); } while (stat !=1 && cardtype != END); } break; case CALL: if (strcmp(getcalledfnname(card+6), "FFSQP") == 0) { strncpy(card2, card, 6); card2[6] = NULL; strcat(card2, "call FFSQP("); for (i=1; i<26; i++) { strcpy(parm_name, getparmname(card, i)); strcat(card2, parm_name); strcat(card2, ","); } strcpy(parm_name, getparmname(card, 24)); if ((tmp = findfnname(ProcessList, parm_name)) != NULL) { strcat(card2, tmp->gr_name); strcat(card2, ","); } else { strcat(card2, getparmname(card, 26)); strcat(card2, ","); } strcpy(parm_name, getparmname(card, 25)); if ((tmp = findfnname(ProcessList, parm_name)) != NULL) { strcat(card2, tmp->gr_name); strcat(card2, ")"); } else { strcat(card2, getparmname(card, 27)); strcat(card2, ")"); } putcard(outf, card2); } else putcard(outf, card); break; case DATA: if ( strstr(card,"parameter")!=NULL && (str=(strstr(card,hold_nparam)))!=NULL) { nparam = get_nparam(str); } putcard(outf, card); com_stat = 0; break; case EXEC: if (com_stat == 0 && ProcessList != (MatchNode *)NULL && strstr(card+6, "program") != card+6) { com_stat = 1; strcpy(card2, " external "); tmp = ProcessList; while (tmp != (MatchNode *)NULL) { strcat(card2, tmp->gr_name); strcat(card2, ","); strcpy(stem,"g_"); strcat(stem,tmp->fn_name); strcat(card2,stem); strcat(card2,","); tmp=tmp->next; } card2[strlen(card2)-1] = NULL; putcard(outf, card2); } putcard(outf, card); break; default: putcard(outf, card); break; } } while (stat != 1); fclose(subf); cmp (arg_name, argc); adf (arg_name, nparam); dummy (arg_name, nparam); if (call_adifor(arg_name)!=0) { fprintf(stderr, "adiffsqp: Conversion failed on call to Adifor2.0\n"); return(1); } suboutf = fopen(subout_name, "r"); do { stat=getcard(suboutf,card); cardtype=classify(card); switch (cardtype) { case SUBR: strcpy(hold_subname, getsubname(card+6)); hold_subname[2]='\0'; if (strcmp(hold_subname,"g_")==0) { fprintf(outf,card); do { stat = getcard(suboutf,card); putcard(outf,card); cardtype=classify(card); } while(stat!=1 && cardtype != END); } else { do stat = getcard(suboutf,card); while (stat!=1 && cardtype != END); } break; default: break; } }while (stat != 1); fclose(suboutf); delfile(arg_name, argc); return(0); } /* ADIFFSQP version0.9(experimental) Released March, 1997*/ /* source code: adiffsqp.c */ /* Copyright (c) 1997 by Mingyan D. Liu and Andre L. Tits */ /* All Rights Reserved */ /* ***************** LAST LINE OF FILE ******************** */