]> https://gitweb.dealii.org/ - dealii.git/commitdiff
fix expand_instantiation split logic 1880/head
authorTimo Heister <timo.heister@gmail.com>
Tue, 17 Nov 2015 21:33:14 +0000 (16:33 -0500)
committerTimo Heister <timo.heister@gmail.com>
Wed, 18 Nov 2015 22:40:24 +0000 (17:40 -0500)
We optionally split instantiations in the generated .inst files based on
two macros SPLIT_INSTANTIATIONS_COUNT and SPLIT_INSTANTIATIONS_INDEX.
Intel 14 generates an error with an invalid % 0 in the old solution,
which happens if _COUNT is undefined. Fix this by defining a macro at
the beginning of the .inst file.

cmake/scripts/expand_instantiations.cc

index bb099183bfe2c17ef86b28ce5628a7c69c887bcb..2e224bb298d9de568a77140e15100cec806e035f 100644 (file)
@@ -386,9 +386,9 @@ void substitute (const std::string &text,
           // between 0 and SPLIT_INSTANTIATIONS_COUNT-1 to get the instantiations of that
           // particular chunk.
           static unsigned int counter = 0;
-          std::cout << "#if !defined(SPLIT_INSTANTIATIONS_COUNT) || ("
+          std::cout << "#if (SPLIT_INSTANTIATIONS_CHECK("
                     << counter++
-                    << " % SPLIT_INSTANTIATIONS_COUNT == SPLIT_INSTANTIATIONS_INDEX)" << std::endl;
+                    << "))" << std::endl;
           std::cout << substitute_tokens (text, name, *expansion)
                     << std::endl;
           std::cout << "#endif" << std::endl;
@@ -506,5 +506,27 @@ int main (int argc, char **argv)
   for (int i=1; i<argc; ++i)
     read_expansion_lists (argv[i]);
 
+  // write header:
+  std::cout << "// This file is automatically generated from corresponding .inst.in, do not edit."
+            << std::endl << std::endl;
+
+  // Make sure SPLIT_INSTANTIATIONS_* is working correctly if the user doesn't
+  // use it. The defaults will not split the instantiations. This logic is
+  // somewhat tricky to get right for two reasons: 1. icc 14 will not allow an
+  // expressition like "#if !defined(B) || (A % B == C)" 2. we have .cc files
+  // where more than one .inst is included and splitting is only required in
+  // one of them. So we need to handle the case where _COUNT is undefined but
+  // _INDEX is defined, which might be needed later.
+  std::cout << "#ifdef SPLIT_INSTANTIATIONS_COUNT" << std::endl
+            << "  #define SPLIT_INSTANTIATIONS_CHECK(C) (((C) % SPLIT_INSTANTIATIONS_COUNT) == SPLIT_INSTANTIATIONS_INDEX)" << std::endl
+            << "#else" << std::endl
+            << "  #define SPLIT_INSTANTIATIONS_CHECK(C) (1)" << std::endl
+            << "#endif" << std::endl << std::endl;
+
   process_instantiations ();
+
+  // undefine the macro to avoid issues when more than one .inst file is
+  // included in a single .cc
+  std::cout << std::endl
+            << "#undef SPLIT_INSTANTIATIONS_CHECK" << std::endl;
 }

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.