Index: include/cctk_Schedule.h =================================================================== RCS file: /cactusdevcvs/Cactus/src/include/cctk_Schedule.h,v retrieving revision 1.14 diff -u -r1.14 cctk_Schedule.h --- include/cctk_Schedule.h 25 Aug 2007 02:23:39 -0000 1.14 +++ include/cctk_Schedule.h 2 Mar 2008 02:02:01 -0000 @@ -86,6 +86,7 @@ int n_before, int n_after, int n_while, + int n_if, ...); int CCTK_ScheduleGroup(const char *name, @@ -99,6 +100,7 @@ int n_before, int n_after, int n_while, + int n_if, ...); int CCTK_ScheduleGroupStorage(const char *group); Index: include/cctki_Schedule.h =================================================================== RCS file: /cactusdevcvs/Cactus/src/include/cctki_Schedule.h,v retrieving revision 1.6 diff -u -r1.6 cctki_Schedule.h --- include/cctki_Schedule.h 17 Feb 2003 17:28:31 -0000 1.6 +++ include/cctki_Schedule.h 2 Mar 2008 02:02:01 -0000 @@ -14,7 +14,11 @@ /* Types needed by other routines. */ -typedef enum {sched_mod_none, sched_before, sched_after, sched_while} t_sched_modifier_type; +typedef enum { + sched_mod_none, + sched_before, sched_after, + sched_while, sched_if +} t_sched_modifier_type; typedef struct T_SCHED_MODIFIER { @@ -58,7 +62,8 @@ int CCTKi_DoScheduleTraverse(const char *group_name, int (*item_entry)(void *, void *), int (*item_exit)(void *, void *), - int (*while_check)(int, char **, void *, void *, int), + int (*while_check)(int, char **, void *, void *, int), + int (*if_check)(int, char **, void *, void *), int (*function_process)(void *, void *, void *), void *data); Index: include/cctki_ScheduleBindings.h =================================================================== RCS file: /cactusdevcvs/Cactus/src/include/cctki_ScheduleBindings.h,v retrieving revision 1.8 diff -u -r1.8 cctki_ScheduleBindings.h --- include/cctki_ScheduleBindings.h 17 Feb 2003 17:28:31 -0000 1.8 +++ include/cctki_ScheduleBindings.h 2 Mar 2008 02:02:01 -0000 @@ -33,6 +33,7 @@ int n_before, int n_after, int n_while, + int n_if, const int *timelevels, ...); @@ -50,6 +51,7 @@ int n_before, int n_after, int n_while, + int n_if, const int *timelevels, ... ); Index: main/ScheduleInterface.c =================================================================== RCS file: /cactusdevcvs/Cactus/src/main/ScheduleInterface.c,v retrieving revision 1.99 diff -u -r1.99 ScheduleInterface.c --- main/ScheduleInterface.c 25 Aug 2007 02:23:39 -0000 1.99 +++ main/ScheduleInterface.c 2 Mar 2008 02:02:02 -0000 @@ -129,6 +129,7 @@ static t_sched_modifier *CreateModifiers(int n_before, int n_after, int n_while, + int n_if, va_list *ap); int ValidateModifiers(t_sched_modifier *modifier); @@ -149,6 +150,11 @@ t_attribute *attribute, t_sched_data *data, int first); +static int CCTKi_SchedulePrintIf(int n_if, + char **ifs, + t_attribute *attribute, + t_sched_data *data, + int first); static int CCTKi_SchedulePrintFunction(void *function, t_attribute *attribute, t_sched_data *data); static int CCTKi_ScheduleCallEntry(t_attribute *attribute, t_sched_data *data); @@ -158,6 +164,10 @@ t_attribute *attribute, t_sched_data *data, int first); +static int CCTKi_ScheduleCallIf(int n_ifs, + char **ifs, + t_attribute *attribute, + t_sched_data *data); static int CCTKi_ScheduleCallFunction(void *function, t_attribute *attribute, t_sched_data *data); @@ -369,6 +379,11 @@ @vtype int @vio in @endvar + @var n_if + @vdesc Number of vars to schedule if + @vtype int + @vio in + @endvar @var timelevels @vdesc The number of timelevels of the storage groups to enable. @vtype const int * @@ -400,6 +415,7 @@ int n_before, int n_after, int n_while, + int n_if, const int *timelevels, ... ) @@ -414,13 +430,14 @@ attribute = CreateAttribute(where,name,description, language, thorn, implementation, n_mem_groups, n_comm_groups, n_trigger_groups, n_sync_groups, n_options, timelevels, &ap); - modifier = CreateModifiers(n_before, n_after, n_while, &ap); + modifier = CreateModifiers(n_before, n_after, n_while, n_if, &ap); va_end(ap); ValidateModifiers(modifier); - if(attribute && (modifier || (n_before == 0 && n_after == 0 && n_while == 0))) + if(attribute && (modifier || (n_before == 0 && n_after == 0 && + n_while == 0 && n_if == 0))) { attribute->FunctionData.type = TranslateFunctionType(where); @@ -525,6 +542,11 @@ @vtype int @vio in @endvar + @var n_if + @vdesc Number of vars to schedule if + @vtype int + @vio in + @endvar @var timelevels @vdesc The number of timelevels of the storage groups to enable. @vtype const int * @@ -554,6 +576,7 @@ int n_before, int n_after, int n_while, + int n_if, const int *timelevels, ... ) @@ -568,13 +591,14 @@ attribute = CreateAttribute(where,name,description, NULL, thorn, implementation, n_mem_groups, n_comm_groups, n_trigger_groups, n_sync_groups, n_options, timelevels, &ap); - modifier = CreateModifiers(n_before, n_after, n_while, &ap); + modifier = CreateModifiers(n_before, n_after, n_while, n_if, &ap); va_end(ap); ValidateModifiers(modifier); - if(attribute && (modifier || (n_before == 0 && n_after == 0 && n_while == 0))) + if(attribute && (modifier || (n_before == 0 && n_after == 0 && + n_while == 0 && n_if == 0))) { retcode = CCTKi_DoScheduleGroup(where, name, realname, modifier, (void *)attribute); @@ -1207,6 +1239,7 @@ (int (*)(void *, void *)) CCTKi_ScheduleCallEntry, (int (*)(void *, void *)) CCTKi_ScheduleCallExit, (int (*)(int, char **, void *, void *, int)) CCTKi_ScheduleCallWhile, + (int (*)(int, char **, void *, void *)) CCTKi_ScheduleCallIf, (int (*)(void *, void *, void *)) calling_function, (void *)&data); @@ -1443,6 +1476,11 @@ @vtype int @vio in @endvar + @var n_if + @vdesc Number of vars to schedule if + @vtype int + @vio in + @endvar @var ap @vdesc options @vtype va_list of multiple const char * @@ -1459,6 +1497,7 @@ static t_sched_modifier *CreateModifiers(int n_before, int n_after, int n_while, + int n_if, va_list *ap) { t_sched_modifier *modifier; @@ -1466,6 +1505,7 @@ modifier = CreateTypedModifier(NULL, "before", n_before, ap); modifier = CreateTypedModifier(modifier, "after", n_after, ap); modifier = CreateTypedModifier(modifier, "while", n_while, ap); + modifier = CreateTypedModifier(modifier, "if", n_if, ap); return modifier; } @@ -1476,7 +1516,7 @@ @author Gabrielle Allen @desc Validates a schedule modifier list. At the moment just check that - the while modifier uses a CCTK_INT grid variable. + the while and if modifiers use a CCTK_INT grid variable. @enddesc @calls @@ -1511,6 +1551,18 @@ retval = -1; } } + else if (modifier->type == sched_if) + { + vindex = CCTK_VarIndex(modifier->argument); + type = CCTK_VarTypeI(vindex); + if (type != CCTK_VARIABLE_INT) + { + CCTK_VWarn(0,__LINE__,__FILE__,"Cactus", + "If qualifier %s is not a CCTK_INT grid variable", + modifier->argument); + retval = -1; + } + } } return retval; } @@ -1749,7 +1801,7 @@ @vtype const char * @vio in @vcomment - before, after, while + before, after, while, if @endvar @var n_items @vdesc Number of items on list @@ -1880,10 +1932,11 @@ if(where) { retcode = CCTKi_DoScheduleTraverse(where, - (int (*)(void *, void *)) CCTKi_SchedulePrintEntry, - (int (*)(void *, void *)) CCTKi_SchedulePrintExit, - (int (*)(int, char **, void *, void *, int))CCTKi_SchedulePrintWhile, - (int (*)(void *, void *, void *)) CCTKi_SchedulePrintFunction, + (int (*)(void *, void *)) CCTKi_SchedulePrintEntry, + (int (*)(void *, void *)) CCTKi_SchedulePrintExit, + (int (*)(int, char **, void *, void *, int))CCTKi_SchedulePrintWhile, + (int (*)(int, char **, void *, void *, int))CCTKi_SchedulePrintIf, + (int (*)(void *, void *, void *)) CCTKi_SchedulePrintFunction, (void *)&data); } else @@ -1936,7 +1989,7 @@ memset (data->total_time->vals, 0, data->total_time->n_vals * sizeof (data->total_time->vals[0])); - retcode = CCTKi_DoScheduleTraverse(where, NULL, NULL, NULL, + retcode = CCTKi_DoScheduleTraverse(where, NULL, NULL, NULL, NULL, (int (*)(void *, void *, void *)) CCTKi_SchedulePrintTimesFunction, (void *)data); @@ -2127,6 +2180,84 @@ } /*@@ + @routine CCTKi_SchedulePrintIf + @date Dec 27, 2005 + @author Erik Schnetter + @desc + Routine called for if of a group when traversing for printing. + @enddesc + @calls + + @var n_ifs + @vdesc number of if statements + @vtype int + @vio in + @endvar + @var ifs + @vdesc if statements + @vtype char ** + @vio in + @endvar + @var attribute + @vdesc schedule item attributes + @vtype t_attribute * + @vio in + @endvar + @var data + @vdesc data associated with schedule item + @vtype t_sched_data + @vio in + @endvar + @var first + @vdesc flag - is this the first time we are checking if on this schedule item + @vtype int + @vio in + @endvar + + @returntype int + @returndesc + 0 - schedule item is inactive + 1 - schedule item is active + @endreturndesc +@@*/ +static int CCTKi_SchedulePrintIf(int n_ifs, + char **ifs, + t_attribute *attribute, + t_sched_data *data, + int first) +{ + int i; + + /* prevent compiler warnings about unused parameters */ + attribute = attribute; + data = data; + + if(first) + { + printf("%*s", indent_level + 2 + 7, "if ("); + + for(i = 0; i < n_ifs; i++) + { + if(i > 0) + { + printf(" && "); + } + + printf(ifs[i]); + } + printf(")\n"); + indent_level += 2; + } + else + { + indent_level -= 2; + printf("%*s\n", indent_level + 9, "end if"); + } + + return first; +} + +/*@@ @routine CCTKi_SchedulePrintFunction @date Sun Sep 19 13:36:25 1999 @author Tom Goodale @@ -2436,6 +2567,64 @@ } /*@@ + @routine CCTKi_ScheduleCallIf + @date Dec 2007, 2005 + @author Erik Schnetter + @desc + Routine called to check variables to see if a group or function should be executed. + @enddesc + @calls + + @var n_ifs + @vdesc number of if statements + @vtype int + @vio in + @endvar + @var ifs + @vdesc if statements + @vtype char ** + @vio in + @endvar + @var attribute + @vdesc schedule item attributes + @vtype t_attribute * + @vio in + @endvar + @var data + @vdesc data associated with schedule item + @vtype t_sched_data + @vio in + @endvar + + @returntype int + @returndesc + 0 - schedule item is inactive + 1 - schedule item is active + @endreturndesc +@@*/ +static int CCTKi_ScheduleCallIf(int n_ifs, + char **ifs, + t_attribute *attribute, + t_sched_data *data) +{ + int i; + int retcode; + + /* prevent compiler warnings about unused parameters */ + attribute = attribute; + + retcode = 1; + + /* FIXME - should do a lot of validation either here or on registration */ + for(i = 0; i < n_ifs; i++) + { + retcode = retcode && *((CCTK_INT *)CCTK_VarDataPtr(data->GH, 0, ifs[i])); + } + + return retcode; +} + +/*@@ @routine CCTKi_ScheduleCallFunction @date Sun Sep 19 13:29:14 1999 @author Tom Goodale Index: schedule/Schedule.h =================================================================== RCS file: /cactusdevcvs/Cactus/src/schedule/Schedule.h,v retrieving revision 1.6 diff -u -r1.6 Schedule.h --- schedule/Schedule.h 26 Jan 2000 16:32:22 -0000 1.6 +++ schedule/Schedule.h 2 Mar 2008 02:02:02 -0000 @@ -55,6 +55,8 @@ int n_whiles; char **whiles; + int n_ifs; + char **ifs; void *attributes; Index: schedule/ScheduleCreater.c =================================================================== RCS file: /cactusdevcvs/Cactus/src/schedule/ScheduleCreater.c,v retrieving revision 1.15 diff -u -r1.15 ScheduleCreater.c --- schedule/ScheduleCreater.c 21 Mar 2005 15:42:01 -0000 1.15 +++ schedule/ScheduleCreater.c 2 Mar 2008 02:02:02 -0000 @@ -48,6 +48,7 @@ static int ScheduleSetupWhiles(t_sched_item *item); +static int ScheduleSetupIfs(t_sched_item *item); /******************************************************************** ********************* Other Routine Prototypes ********************* @@ -533,8 +534,11 @@ this->n_whiles = 0; this->whiles = NULL; + this->n_ifs = 0; + this->ifs = NULL; ScheduleSetupWhiles(this); + ScheduleSetupIfs(this); this->attributes = attributes; @@ -676,6 +680,10 @@ { retval = sched_while; } + else if(!strcmp(modifier, "if")) + { + retval = sched_if; + } #ifdef DEBUG_SCHEDULAR printf("Translated modifier type %s to %d\n", modifier, retval); @@ -747,7 +755,7 @@ #endif for(modifier = group->scheditems[item].modifiers; modifier; modifier = modifier->next) { - if(modifier->type == sched_while) + if(modifier->type == sched_while || modifier->type == sched_if) { continue; } @@ -969,6 +977,70 @@ return retval; } + /*@@ + @routine ScheduleSetupIfs + @date Dec 27, 2005 + @author Erik Schnetter + @desc + Make an array of all the ifs in the modifier list for a schedule item. + @enddesc + @calls + @calledby + @history + + @endhistory + @var item + @vdesc The schedule item to work on + @vtype t_sched_item * + @vio inout + @vcomment + + @endvar + @returntype int + @returndesc + Number of whiles + @endreturndesc +@@*/ +static int ScheduleSetupIfs(t_sched_item *item) +{ + int retval; + t_sched_modifier *modifier; + char **temp; + + retval = 0; + + for(modifier = item->modifiers; modifier; modifier = modifier->next) + { + if(modifier->type == sched_if) + { + item->n_ifs++; + temp = (char **)realloc(item->ifs, item->n_ifs*sizeof(char *)); + + if(temp) + { + item->ifs = temp; + + temp[item->n_ifs-1] = (char *)malloc((strlen(modifier->argument)+1)*sizeof(char)); + if(temp[item->n_ifs-1]) + { + strcpy(temp[item->n_ifs-1], modifier->argument); + } + else + { + item->n_ifs--; + retval--; + } + } + else + { + retval--; + } + } + } + + return retval; +} + /******************************************************************** ******************************************************************** ********************************************************************/ Index: schedule/ScheduleTraverse.c =================================================================== RCS file: /cactusdevcvs/Cactus/src/schedule/ScheduleTraverse.c,v retrieving revision 1.9 diff -u -r1.9 ScheduleTraverse.c --- schedule/ScheduleTraverse.c 17 Dec 2002 17:27:48 -0000 1.9 +++ schedule/ScheduleTraverse.c 2 Mar 2008 02:02:02 -0000 @@ -34,9 +34,12 @@ void *attributes, int n_whiles, char **whiles, + int n_ifs, + char **ifs, int (*item_entry)(void *, void *), int (*item_exit)(void *, void *), - int (*while_check)(int, char **, void *, void *, int), + int (*while_check)(int, char **, void *, void *, int), + int (*if_check)(int, char **, void *, void *), int (*function_process)(void *, void *, void *), void *data); @@ -44,9 +47,12 @@ void *attributes, int n_whiles, char **whiles, + int n_ifs, + char **ifs, int (*item_entry)(void *, void *), int (*item_exit)(void *, void *), - int (*while_check)(int, char **, void *, void *, int), + int (*while_check)(int, char **, void *, void *, int), + int (*if_check)(int, char **, void *, void *), int (*function_process)(void *, void *, void *), void *data); @@ -102,6 +108,13 @@ @vcomment @endvar + @var if_check + @vdesc function to be called to check an if statement + @vtype int (*)(int, char **, void *, void *, int) + @vio in + @vcomment + + @endvar @var function_process @vdesc function to be called on any function @vtype int (*)(void *, void *, void *) @@ -126,7 +139,8 @@ int CCTKi_DoScheduleTraverse(const char *group_name, int (*item_entry)(void *, void *), int (*item_exit)(void *, void *), - int (*while_check)(int, char **, void *, void *, int), + int (*while_check)(int, char **, void *, void *, int), + int (*if_check)(int, char **, void *, void *), int (*function_process)(void *, void *, void *), void *data) { @@ -146,9 +160,12 @@ NULL, 0, NULL, + 0, + NULL, item_entry, item_exit, while_check, + if_check, function_process, data); } @@ -211,6 +228,20 @@ @vcomment @endvar + @var n_ifs + @vdesc number of ifs + @vtype int + @vio in + @vcomment + + @endvar + @var ifs + @vdesc array of if strings + @vtype char ** + @vio in + @vcomment + + @endvar @var item_entry @vdesc function to be called on entry to an item @vtype int (*)(void *, void *) @@ -232,6 +263,13 @@ @vcomment @endvar + @var if_check + @vdesc function to be called to check a if statement + @vtype int (*)(int, char **, void *, void *, int) + @vio in + @vcomment + + @endvar @var function_process @vdesc function to be called on any function @vtype int (*)(void *, void *, void *) @@ -257,9 +295,12 @@ void *attributes, int n_whiles, char **whiles, + int n_ifs, + char **ifs, int (*item_entry)(void *, void *), int (*item_exit)(void *, void *), - int (*while_check)(int, char **, void *, void *, int), + int (*while_check)(int, char **, void *, void *, int), + int (*if_check)(int, char **, void *, void *), int (*function_process)(void *, void *, void *), void *data) { @@ -268,17 +309,35 @@ int called_item_entry; t_sched_group *newgroup; - /* If there is a while-list associated with this item, check if the group should be - * exectuted at all. + doit = 1; + + /* If there is an if-list associated with this item, check if the + * group should be exectuted at all. */ - if(n_whiles > 0 && while_check) + if(n_ifs > 0 && if_check) { - doit = while_check(n_whiles, whiles, attributes, data,1); + doit = doit && if_check(n_ifs, ifs, attributes, data); } - else + + /* If there is a while-list associated with this item, check if the + * group should be exectuted at all. + * + * If there are both an if-list and a while-list, then both are + * checked when the group is entered, but only the while-list is + * checked to determine whether the loop should continue. This + * means that the if-statement is outside the while-statement, as in + * + * IF (...) + * WHILE (...) + * schedule stuff + * END WHILE + * END IF + */ + + if(n_whiles > 0 && while_check) { - doit = 1; + doit = doit && while_check(n_whiles, whiles, attributes, data,1); } /* Call a item entry function if it is defined. */ @@ -297,7 +356,7 @@ } /* Now traverse the group. */ - while(doit ) + while(doit) { /* Traverse in the sorted order - assumes group has been sorted ! */ @@ -310,9 +369,12 @@ group->scheditems[group->order[item]].attributes, group->scheditems[group->order[item]].n_whiles, group->scheditems[group->order[item]].whiles, + group->scheditems[group->order[item]].n_ifs, + group->scheditems[group->order[item]].ifs, item_entry, - item_exit, + item_exit, while_check, + if_check, function_process, data); break; @@ -324,9 +386,12 @@ group->scheditems[group->order[item]].attributes, group->scheditems[group->order[item]].n_whiles, group->scheditems[group->order[item]].whiles, + group->scheditems[group->order[item]].n_ifs, + group->scheditems[group->order[item]].ifs, item_entry, item_exit, while_check, + if_check, function_process, data); break; @@ -398,6 +463,20 @@ @vcomment @endvar + @var n_ifs + @vdesc number of ifs + @vtype int + @vio in + @vcomment + + @endvar + @var ifs + @vdesc array of if strings + @vtype char ** + @vio in + @vcomment + + @endvar @var item_entry @vdesc function to be called on entry to an item @vtype int (*)(void *, void *) @@ -419,6 +498,13 @@ @vcomment @endvar + @var if_check + @vdesc function to be called to check a if statement + @vtype int (*)(int, char **, void *, void *, int) + @vio in + @vcomment + + @endvar @var function_process @vdesc function to be called on any function @vtype int (*)(void *, void *, void *) @@ -443,26 +529,36 @@ void *attributes, int n_whiles, char **whiles, + int n_ifs, + char **ifs, int (*item_entry)(void *, void *), int (*item_exit)(void *, void *), - int (*while_check)(int, char **, void *, void *, int), + int (*while_check)(int, char **, void *, void *, int), + int (*if_check)(int, char **, void *, void *), int (*function_process)(void *, void *, void *), void *data) { int doit; int called_item_entry; - /* If there is a while-list associated with this function, check if the function should be - * executed at all. + doit = 1; + + /* If there is an if-list associated with this function, check if + * the function should be executed at all. */ - if(n_whiles > 0 && while_check) + if(n_ifs > 0 && if_check) { - doit = while_check(n_whiles, whiles, attributes, data,1); + doit = doit && if_check(n_ifs, ifs, attributes, data); } - else + + /* If there is a while-list associated with this function, check if + * the function should be executed at all. + */ + + if(n_whiles > 0 && while_check) { - doit = 1; + doit = doit && while_check(n_whiles, whiles, attributes, data,1); } /* Call a item entry function if it is defined. */ @@ -481,7 +577,7 @@ } /* Now traverse the . */ - while(doit ) + while(doit) { /* Now actually do something with the function. */ @@ -493,7 +589,6 @@ doit = while_check(n_whiles, whiles, attributes, data,0) ; } else - { doit = 0; }