diff options
author | Ian Hinder <ian.hinder@aei.mpg.de> | 2013-04-03 20:26:58 +0200 |
---|---|---|
committer | Ian Hinder <ian.hinder@aei.mpg.de> | 2013-04-03 20:26:58 +0200 |
commit | 091608eace4f7ba1cf6840752e4266d1fcbe47f4 (patch) | |
tree | 3bf92d711d7a089783a45f1d4dbc04fd8d1f3c95 /Carpet/Requirements | |
parent | 0502d5c641c4a1f1685ea8fc2625ff4a5f9e78f7 (diff) |
Requirements: Move clause class into separate files
Diffstat (limited to 'Carpet/Requirements')
-rw-r--r-- | Carpet/Requirements/src/Requirements.cc | 193 | ||||
-rw-r--r-- | Carpet/Requirements/src/clause.cc | 168 | ||||
-rw-r--r-- | Carpet/Requirements/src/clause.hh | 37 | ||||
-rw-r--r-- | Carpet/Requirements/src/make.code.defn | 2 |
4 files changed, 208 insertions, 192 deletions
diff --git a/Carpet/Requirements/src/Requirements.cc b/Carpet/Requirements/src/Requirements.cc index 456e3d804..a76a1b8a2 100644 --- a/Carpet/Requirements/src/Requirements.cc +++ b/Carpet/Requirements/src/Requirements.cc @@ -19,15 +19,12 @@ #include <map> #include <string> #include <vector> +#include <clause.hh> using namespace std; - - namespace Requirements { - - - + // Rules: // // 1. Everything that is required by a routine must be provided by @@ -58,192 +55,6 @@ namespace Requirements { inline ostream& operator<< (ostream& os, const vector<T>& v) { return Requirements::output(os,v); } - - - // Represent scheduled functions and their dependencies - // This reflects exactly what was written in the schedule.ccl file - struct clause_t { - bool everywhere; // all grid points (everywhere) - bool interior; // all interior points - bool boundary; // all boundary points, excluding - // ghostzones - bool boundary_ghostzones; // all boundary ghost points - bool timelevel0, timelevel1, timelevel2; - bool all_timelevels; // all time levels - bool all_maps; // all maps (i.e. level mode) - bool all_reflevels; // all refinement levels (i.e. global mode) - vector<int> vars; - clause_t(): - everywhere(false), - interior(false), boundary(false), boundary_ghostzones(false), - timelevel0(false), timelevel1(false), timelevel2(false), - all_timelevels(false), all_maps(false), all_reflevels(false) - {} - void interpret_options(cFunctionData const* function_data); - void parse_clause(char const* clause); - int min_num_timelevels() const; - bool active_on_timelevel(int tl) const; - - // Input/Output helpers - void input (istream& is); - void output (ostream& os) const; - }; - - void clause_t::interpret_options(cFunctionData const* const function_data) - { - if (function_data->meta or - function_data->meta_early or - function_data->meta_late or - function_data->global or - function_data->global_early or - function_data->global_late) - { - assert(not all_reflevels); - all_reflevels = true; - } - if (function_data->level) { - assert(not all_maps); - all_maps = true; - } - // Ignore singlemap and local options - // Ignore loop_* options - } - - void clause_t::parse_clause(char const* const clause1) - { - char* const clause = strdup(clause1); - char* p = clause; - - // Remove trailing "(...)" modifier, if any - p = strchr(p, '('); - if (p) *p = '\0'; - int const gi = CCTK_GroupIndex(clause); - if (gi >= 0) { - // A group - int const v0 = CCTK_FirstVarIndexI(gi); assert(v0 >= 0); - int const nv = CCTK_NumVarsInGroupI(gi); assert(nv >= 0); - for (int vi=v0; vi<v0+nv; ++vi) { - vars.push_back(vi); - } - } else { - // Not a group - should be a variable - int const vi = CCTK_VarIndex(clause); - if (vi < 0) { - CCTK_VWarn(CCTK_WARN_ABORT, __LINE__, __FILE__, CCTK_THORNSTRING, - "could not obtain variable/group index for '%s' in clause '%s': %d", - clause, clause1, vi); - } - assert(vi >= 0); - vars.push_back(vi); - } - - // Parse modifiers - // TODO: Use CarpetLib parser for this - // TODO: add user friendly error messages - // TODO: teach the flesh about commas within the READS/WRITES block - if (p) { - ++p; - for (;;) { - size_t const len = strcspn(p, ";)"); - char const c = p[len]; - assert(c); - p[len] = '\0'; - if (CCTK_EQUALS(p, "everywhere")) { - assert(not everywhere and - not interior and not boundary and not boundary_ghostzones); - everywhere = true; - } else if (CCTK_EQUALS(p, "interior")) { - assert(not everywhere and not interior); - interior = true; - } else if (CCTK_EQUALS(p, "boundary")) { - assert(not everywhere and not boundary); - boundary = true; - } else if (CCTK_EQUALS(p, "boundary_ghostzones")) { - assert(not everywhere and not boundary_ghostzones); - boundary_ghostzones = true; - } else if (CCTK_EQUALS(p, "timelevel0")) { - assert(not timelevel0 and not all_timelevels); - timelevel0 = true; - } else if (CCTK_EQUALS(p, "timelevel1")) { - assert(not timelevel1 and not all_timelevels); - timelevel1 = true; - } else if (CCTK_EQUALS(p, "timelevel2")) { - assert(not timelevel2 and not all_timelevels); - timelevel2 = true; - } else if (CCTK_EQUALS(p, "all_timelevels")) { - // TODO: look at schedule group instead - assert(not timelevel0 and not timelevel1 and not timelevel2 and - not all_timelevels); - all_timelevels = true; - } else { - CCTK_VWarn(CCTK_WARN_ABORT, __LINE__, __FILE__, CCTK_THORNSTRING, - "Unknown modifier '%s' in clause '%s'", p, clause1); - } - if (c == ')') break; - assert(c==';'); - p += len+1; - } - } - - free(clause); - } - - int clause_t::min_num_timelevels() const - { - if (timelevel2) return 3; - if (timelevel1) return 2; - return 1; - } - - bool clause_t::active_on_timelevel(int const tl) const - { - assert(tl>=0); - if (all_timelevels) return true; - if (timelevel0 and tl==0) return true; - if (timelevel1 and tl==1) return true; - if (timelevel2 and tl==2) return true; - bool const no_timelevel_clause = - not timelevel0 and not timelevel1 and not timelevel2; - if (tl==0 and no_timelevel_clause) return true; - return false; - } - - inline ostream& operator<< (ostream& os, const clause_t& a) { - a.output(os); - return os; - } - - void clause_t::output(ostream& os) const - { - char* const groupname = CCTK_GroupNameFromVarI(vars.at(0)); - os << groupname; - free(groupname); - os << "{"; - for (vector<int>::const_iterator ivi = vars.begin(); - ivi != vars.end(); - ++ivi) - { - if (ivi != vars.begin()) - os << ","; - char* const fullname = CCTK_FullName(*ivi); - os << fullname; - free(fullname); - } - os << "}("; - if (everywhere) os << "everywhere;"; - if (interior) os << "interior;"; - if (boundary) os << "boundary;"; - if (boundary_ghostzones) os << "boundary_ghostzones;"; - if (timelevel0) os << "timelevel0;"; - if (timelevel1) os << "timelevel1;"; - if (timelevel2) os << "timelevel2;"; - if (all_timelevels) os << "all_timelevels;"; - if (all_maps) os << "all_maps;"; - if (all_reflevels) os << "all_reflevels;"; - os << ")"; - } - - struct clauses_t { vector<clause_t> reads, writes; diff --git a/Carpet/Requirements/src/clause.cc b/Carpet/Requirements/src/clause.cc new file mode 100644 index 000000000..2c160bbec --- /dev/null +++ b/Carpet/Requirements/src/clause.cc @@ -0,0 +1,168 @@ + +#include <cctk.h> +#include <cctki_Schedule.h> + +#include <cstdlib> +#include <cstring> +#include <vector> + +#include <clause.hh> + +using namespace std; + +namespace Requirements { + + void clause_t::interpret_options(cFunctionData const* const function_data) + { + if (function_data->meta or + function_data->meta_early or + function_data->meta_late or + function_data->global or + function_data->global_early or + function_data->global_late) + { + assert(not all_reflevels); + all_reflevels = true; + } + if (function_data->level) { + assert(not all_maps); + all_maps = true; + } + // Ignore singlemap and local options + // Ignore loop_* options + } + + void clause_t::parse_clause(char const* const clause1) + { + char* const clause = strdup(clause1); + char* p = clause; + + // Remove trailing "(...)" modifier, if any + p = strchr(p, '('); + if (p) *p = '\0'; + int const gi = CCTK_GroupIndex(clause); + if (gi >= 0) { + // A group + int const v0 = CCTK_FirstVarIndexI(gi); assert(v0 >= 0); + int const nv = CCTK_NumVarsInGroupI(gi); assert(nv >= 0); + for (int vi=v0; vi<v0+nv; ++vi) { + vars.push_back(vi); + } + } else { + // Not a group - should be a variable + int const vi = CCTK_VarIndex(clause); + if (vi < 0) { + CCTK_VWarn(CCTK_WARN_ABORT, __LINE__, __FILE__, CCTK_THORNSTRING, + "could not obtain variable/group index for '%s' in clause '%s': %d", + clause, clause1, vi); + } + assert(vi >= 0); + vars.push_back(vi); + } + + // Parse modifiers + // TODO: Use CarpetLib parser for this + // TODO: add user friendly error messages + // TODO: teach the flesh about commas within the READS/WRITES block + if (p) { + ++p; + for (;;) { + size_t const len = strcspn(p, ";)"); + char const c = p[len]; + assert(c); + p[len] = '\0'; + if (CCTK_EQUALS(p, "everywhere")) { + assert(not everywhere and + not interior and not boundary and not boundary_ghostzones); + everywhere = true; + } else if (CCTK_EQUALS(p, "interior")) { + assert(not everywhere and not interior); + interior = true; + } else if (CCTK_EQUALS(p, "boundary")) { + assert(not everywhere and not boundary); + boundary = true; + } else if (CCTK_EQUALS(p, "boundary_ghostzones")) { + assert(not everywhere and not boundary_ghostzones); + boundary_ghostzones = true; + } else if (CCTK_EQUALS(p, "timelevel0")) { + assert(not timelevel0 and not all_timelevels); + timelevel0 = true; + } else if (CCTK_EQUALS(p, "timelevel1")) { + assert(not timelevel1 and not all_timelevels); + timelevel1 = true; + } else if (CCTK_EQUALS(p, "timelevel2")) { + assert(not timelevel2 and not all_timelevels); + timelevel2 = true; + } else if (CCTK_EQUALS(p, "all_timelevels")) { + // TODO: look at schedule group instead + assert(not timelevel0 and not timelevel1 and not timelevel2 and + not all_timelevels); + all_timelevels = true; + } else { + CCTK_VWarn(CCTK_WARN_ABORT, __LINE__, __FILE__, CCTK_THORNSTRING, + "Unknown modifier '%s' in clause '%s'", p, clause1); + } + if (c == ')') break; + assert(c==';'); + p += len+1; + } + } + + free(clause); + } + + int clause_t::min_num_timelevels() const + { + if (timelevel2) return 3; + if (timelevel1) return 2; + return 1; + } + + bool clause_t::active_on_timelevel(int const tl) const + { + assert(tl>=0); + if (all_timelevels) return true; + if (timelevel0 and tl==0) return true; + if (timelevel1 and tl==1) return true; + if (timelevel2 and tl==2) return true; + bool const no_timelevel_clause = + not timelevel0 and not timelevel1 and not timelevel2; + if (tl==0 and no_timelevel_clause) return true; + return false; + } + + inline ostream& operator<< (ostream& os, const clause_t& a) { + a.output(os); + return os; + } + + void clause_t::output(ostream& os) const + { + char* const groupname = CCTK_GroupNameFromVarI(vars.at(0)); + os << groupname; + free(groupname); + os << "{"; + for (vector<int>::const_iterator ivi = vars.begin(); + ivi != vars.end(); + ++ivi) + { + if (ivi != vars.begin()) + os << ","; + char* const fullname = CCTK_FullName(*ivi); + os << fullname; + free(fullname); + } + os << "}("; + if (everywhere) os << "everywhere;"; + if (interior) os << "interior;"; + if (boundary) os << "boundary;"; + if (boundary_ghostzones) os << "boundary_ghostzones;"; + if (timelevel0) os << "timelevel0;"; + if (timelevel1) os << "timelevel1;"; + if (timelevel2) os << "timelevel2;"; + if (all_timelevels) os << "all_timelevels;"; + if (all_maps) os << "all_maps;"; + if (all_reflevels) os << "all_reflevels;"; + os << ")"; + } +}; diff --git a/Carpet/Requirements/src/clause.hh b/Carpet/Requirements/src/clause.hh new file mode 100644 index 000000000..66e06df74 --- /dev/null +++ b/Carpet/Requirements/src/clause.hh @@ -0,0 +1,37 @@ + +#include <cctk_Schedule.h> +#include <vector> + +using namespace std; + +namespace Requirements { + + // Represent scheduled functions and their dependencies + // This reflects exactly what was written in the schedule.ccl file + struct clause_t { + bool everywhere; // all grid points (everywhere) + bool interior; // all interior points + bool boundary; // all boundary points, excluding + // ghostzones + bool boundary_ghostzones; // all boundary ghost points + bool timelevel0, timelevel1, timelevel2; + bool all_timelevels; // all time levels + bool all_maps; // all maps (i.e. level mode) + bool all_reflevels; // all refinement levels (i.e. global mode) + vector<int> vars; + clause_t(): + everywhere(false), + interior(false), boundary(false), boundary_ghostzones(false), + timelevel0(false), timelevel1(false), timelevel2(false), + all_timelevels(false), all_maps(false), all_reflevels(false) + {} + void interpret_options(cFunctionData const* function_data); + void parse_clause(char const* clause); + int min_num_timelevels() const; + bool active_on_timelevel(int tl) const; + + // Input/Output helpers + void input (istream& is); + void output (ostream& os) const; + }; +}; diff --git a/Carpet/Requirements/src/make.code.defn b/Carpet/Requirements/src/make.code.defn index f940d5f63..4852f42f9 100644 --- a/Carpet/Requirements/src/make.code.defn +++ b/Carpet/Requirements/src/make.code.defn @@ -1,7 +1,7 @@ # Main make.code.defn file for thorn Requirements -*-Makefile-*- # Source files in this directory -SRCS = Requirements.cc +SRCS = Requirements.cc clause.cc # Subdirectories containing source files SUBDIRS = |