From tarjeik at chemcon.no Tue Mar 4 10:30:55 2003 From: tarjeik at chemcon.no (Tarjei Knapstad) Date: 04 Mar 2003 11:30:55 +0100 Subject: [pooma-dev] KCC versus icc (and gcc) In-Reply-To: References: Message-ID: <1046773856.1270.51.camel@cc-intern01> On Wed, 2003-02-26 at 20:27, Richard Guenther wrote: > Hi! > > I remember problems with the inliner, i.e. it refused to inline > some of the expression template machinery. You might want to search > for an option letting you tune the inlining behavior or try profile > directed optimizations. With standard -O3 icc is not always faster > than gcc3.2.2 with -O3. > Just thought I'd add a bit to that. A while back me and some others constructed some code to try to measure the performance hit of dynamic_cast with the following code (needs the boost libraries): ========== BEGIN CODE ================ #include #include using namespace std; const int num=10000000; class TestBase { public: virtual ~TestBase() {} virtual void f() {} void f2() {} }; class Test1 : public TestBase { public: virtual ~Test1() {} virtual void f() {} void f2() {} }; // Ensure that it doesn't optimise away the reading of it in the loops volatile TestBase* testBasePtr = new Test1(); int main() { boost::timer t1; for(unsigned int i = 0; i != num; ++i) { Test1* test1 = const_cast(dynamic_cast(testBasePtr)); if (test1) { test1 -> f2(); } } cout << "Elapsed t1 " << t1.elapsed() << " " << endl; boost::timer t2; for(unsigned int i = 0; i != num; ++i) { Test1* test1 = const_cast(static_cast(testBasePtr)); if (test1) { test1 -> f2(); } } cout << "Elapsed t2 " << t2.elapsed() << " " << endl; return 0; } =========== END CODE ========== We tried running this on both gcc: Elapsed t1 0.52 Elapsed t2 0.01 and Intel 7: Elapsed t1 4.03 Elapsed t2 0.12 with optimizations turned on and the results are quite staggering. Similar differences are found when testing boost.lexical_cast on the different compilers. There are quite a lot of advanced compiler optimizations in the Intel compiler though, which I haven't had too much time to play around with (I'm using gcc and have only played around with icc). I would also be interested in your findings if you can make icc generate code that is more in the vicinity of Kcc's performance. Regards, -- Tarjei From rguenth at tat.physik.uni-tuebingen.de Fri Mar 7 21:14:58 2003 From: rguenth at tat.physik.uni-tuebingen.de (Richard Guenther) Date: Fri, 7 Mar 2003 22:14:58 +0100 (CET) Subject: gcc and inlining Message-ID: [sorry - my local mailing is broken currently, so just ignore duplicates, if you get some] Hi! GCC is not very smart at inlining, and with not tuning -finline-limit you get (due to top-down inlining) trivial methods like FillLocStorageImpl stuff and even ~Loc<1> not inlined which hurts performance a lot. GCC as of version 3.2 (I think) has the ability to mark functions as "always inline". This unfortunately cannot be turned on by sth like #define inline __attibute__((always_inline)), but needs to be manually done. Candidates would be all Domain related stuff and possibly Mesh and Engine stuff as well (yes - I get non-inlined Engine::read()s, too...). Seems like a mess to me (note: intel icpc isnt any better here). I hope we can sneak something like the -fobey-inline patch from Matt Austern (see http://gcc.gnu.org/ml/gcc/2003-02/msg01666.html for discussion, havent found the actual patch, Matt?) into gcc 3.3/3.4... Mark? Any other bright ideas? Thanks, Richard. -- Richard Guenther WWW: http://www.tat.physik.uni-tuebingen.de/~rguenth/ From austern at apple.com Fri Mar 7 21:19:03 2003 From: austern at apple.com (Matt Austern) Date: Fri, 7 Mar 2003 13:19:03 -0800 Subject: In-Reply-To: Message-ID: <6BBC623A-50E2-11D7-B9FB-000393B2ABA2@apple.com> On Friday, March 7, 2003, at 01:12 PM, Richard Guenther wrote: > Hi! > > GCC is not very smart at inlining, and with not tuning -finline-limit > you > get (due to top-down inlining) trivial methods like FillLocStorageImpl > stuff and even ~Loc<1> not inlined which hurts performance a lot. GCC > as > of version 3.2 (I think) has the ability to mark functions as "always > inline". This unfortunately cannot be turned on by sth like #define > inline > __attibute__((always_inline)), but needs to be manually done. > Candidates > would be all Domain related stuff and possibly Mesh and Engine stuff as > well (yes - I get non-inlined Engine::read()s, too...). > > Seems like a mess to me (note: intel icpc isnt any better here). I hope > we can sneak something like the -fobey-inline patch from Matt Austern > (see http://gcc.gnu.org/ml/gcc/2003-02/msg01666.html for discussion, > havent found the actual patch, Matt?) into gcc 3.3/3.4... Mark? The reason you haven't found the patch is that I didn't submit it. Stuart Hastings (also from Apple) submitted it. So far it's neither been approved nor rejected. --Matt From rguenth at tat.physik.uni-tuebingen.de Fri Mar 7 21:19:59 2003 From: rguenth at tat.physik.uni-tuebingen.de (Richard Guenther) Date: Fri, 7 Mar 2003 22:19:59 +0100 (CET) Subject: In-Reply-To: <6BBC623A-50E2-11D7-B9FB-000393B2ABA2@apple.com> Message-ID: On Fri, 7 Mar 2003, Matt Austern wrote: > On Friday, March 7, 2003, at 01:12 PM, Richard Guenther wrote: > > > Hi! > > > > GCC is not very smart at inlining, and with not tuning -finline-limit > > you > > get (due to top-down inlining) trivial methods like FillLocStorageImpl > > stuff and even ~Loc<1> not inlined which hurts performance a lot. GCC > > as > > of version 3.2 (I think) has the ability to mark functions as "always > > inline". This unfortunately cannot be turned on by sth like #define > > inline > > __attibute__((always_inline)), but needs to be manually done. > > Candidates > > would be all Domain related stuff and possibly Mesh and Engine stuff as > > well (yes - I get non-inlined Engine::read()s, too...). > > > > Seems like a mess to me (note: intel icpc isnt any better here). I hope > > we can sneak something like the -fobey-inline patch from Matt Austern > > (see http://gcc.gnu.org/ml/gcc/2003-02/msg01666.html for discussion, > > havent found the actual patch, Matt?) into gcc 3.3/3.4... Mark? > > The reason you haven't found the patch is that I didn't submit it. > Stuart Hastings (also from Apple) submitted it. So far it's neither > been approved nor rejected. Ok, found it - its in http://gcc.gnu.org/ml/gcc-patches/2003-02/msg02386.html I'll try to apply it to 3.3 branch and report benchmark numbers if I succeed. Richard. -- Richard Guenther WWW: http://www.tat.physik.uni-tuebingen.de/~rguenth/ From rguenth at tat.physik.uni-tuebingen.de Wed Mar 12 21:54:38 2003 From: rguenth at tat.physik.uni-tuebingen.de (Richard Guenther) Date: Wed, 12 Mar 2003 22:54:38 +0100 (CET) Subject: [PATCH] Re: Two New Array Failures In-Reply-To: <3E6F97B9.8000800@codesourcery.com> Message-ID: Hi! The attached patch canonicalizes Engine::domain() const to return a const reference to its domain. It can do so by adding a domain_m member to the expression engine (pls review this part carefully, as in some of the constructors we might do things more optimally if I had understood what they actually do...). (We might do something similar to the Engine::layout() const methods, though this would affect many more engines to be added a layout_m member) Testing is still in progress, but the concept sounds reasonable? Thanks, Richard. -- Richard Guenther WWW: http://www.tat.physik.uni-tuebingen.de/~rguenth/ ===== DynamicEngine.h 1.1 vs edited ===== --- 1.1/r2/src/Engine/DynamicEngine.h Mon May 13 17:47:32 2002 +++ edited/DynamicEngine.h Wed Mar 12 22:49:39 2003 @@ -509,7 +509,7 @@ // Return the domain: - const Domain_t &domain() const { return domain_m; } + inline const Domain_t &domain() const { return domain_m; } // Return a DomainLayout built from our domain ===== ExpressionEngine.h 1.1 vs edited ===== --- 1.1/r2/src/Engine/ExpressionEngine.h Mon May 13 17:47:32 2002 +++ edited/ExpressionEngine.h Wed Mar 12 22:49:05 2003 @@ -499,12 +499,14 @@ //--------------------------------------------------------------------------- // Expression constructor. Just stick the expression in local storage. - inline Engine(const Expr &expr) : expr_m(expr) { } + inline Engine(const Expr &expr) : expr_m(expr), + domain_m(forEach(expr_m, DomainFunctorTag(), DomainFunctorTag())) { } //--------------------------------------------------------------------------- // Copy constructor. - inline Engine(const Engine_t &engine) : expr_m(engine.expression()) { } + inline Engine(const Engine_t &engine) : expr_m(engine.expression()), + domain_m(engine.domain()) { } //--------------------------------------------------------------------------- // Subsetting Constructor. We build this expression engine, in place, from @@ -517,13 +519,15 @@ template inline Engine(const Engine > &e, const Initializer &i) - : expr_m(e.expression(), i) + : expr_m(e.expression(), i), + domain_m(forEach(expr_m, DomainFunctorTag(), DomainFunctorTag())) { } template inline Engine(const Engine > &e, const I1 &i1, const I2 &i2) - : expr_m(e.expression(), i1, i2) + : expr_m(e.expression(), i1, i2), + domain_m(forEach(expr_m, DomainFunctorTag(), DomainFunctorTag())) { } //--------------------------------------------------------------------------- @@ -531,7 +535,9 @@ template explicit inline Engine(const Engine > &e) - : expr_m(e.expression()) { } + : expr_m(e.expression()), + domain_m(forEach(expr_m, DomainFunctorTag(), DomainFunctorTag())) + { } //--------------------------------------------------------------------------- // Accessor functions that return the expression. @@ -600,12 +606,13 @@ // combine the results based on the DomainFunctorTag. The DomainFunctorTag // combiners are above. - Domain_t domain() const + inline const Domain_t& domain() const { - return forEach(expr_m, DomainFunctorTag(), DomainFunctorTag()); + return domain_m; } - //--------------------------------------------------------------------------- // Return a layout. + //--------------------------------------------------------------------------- + // Return a layout. inline Layout_t layout() const { return Layout_t(domain()); } @@ -638,6 +645,10 @@ // The expression is stored here. Expr expr_m; + + // The domain of the expression. + + Domain_t domain_m; }; ===== IndexFunctionEngine.h 1.1 vs edited ===== --- 1.1/r2/src/Engine/IndexFunctionEngine.h Mon May 13 17:47:32 2002 +++ edited/IndexFunctionEngine.h Wed Mar 12 22:48:44 2003 @@ -228,7 +228,7 @@ //--------------------------------------------------------------------------- // Return/set the domain. Also, return the base domain. - const Domain_t &domain() const { return domain_m; } + inline const Domain_t &domain() const { return domain_m; } void setDomain(const Domain_t &dom) { domain_m = dom; } //--------------------------------------------------------------------------- ===== IndirectionEngine.h 1.1 vs edited ===== --- 1.1/r2/src/Engine/IndirectionEngine.h Mon May 13 17:47:32 2002 +++ edited/IndirectionEngine.h Wed Mar 12 21:38:21 2003 @@ -246,7 +246,7 @@ //--------------------------------------------------------------------------- - inline Domain_t domain() const + inline const Domain_t& domain() const { return array2_m.domain(); } ===== Stencil.h 1.5 vs edited ===== --- 1.5/r2/src/Engine/Stencil.h Fri Jan 24 10:35:52 2003 +++ edited/Stencil.h Wed Mar 12 21:40:46 2003 @@ -400,7 +401,7 @@ // Return the output domain. //============================================================ - inline Domain_t domain() const { return domain_m; } + inline const Domain_t& domain() const { return domain_m; } //============================================================ // Return the first output index value for the specified direction ===== UserFunction.h 1.1 vs edited ===== --- 1.1/r2/src/Engine/UserFunction.h Mon May 13 17:47:32 2002 +++ edited/UserFunction.h Wed Mar 12 22:48:05 2003 @@ -241,7 +241,7 @@ // Return the domain. //--------------------------------------------------------------------------- - Domain_t domain() const { return expression_m.domain(); } + inline const Domain_t& domain() const { return expression_m.domain(); } //--------------------------------------------------------------------------- // Return first index in the specified direction. ===== ViewEngine.h 1.5 vs edited ===== --- 1.5/r2/src/Engine/ViewEngine.h Fri Jan 24 10:35:52 2003 +++ edited/ViewEngine.h Wed Mar 12 22:47:55 2003 @@ -263,7 +263,7 @@ //--------------------------------------------------------------------------- // Return the domain. - const Domain_t &domain() const { return indexer_m.domain(); } + inline const Domain_t &domain() const { return indexer_m.domain(); } //--------------------------------------------------------------------------- // Return the first value for the specified direction (always zero since this From rguenth at tat.physik.uni-tuebingen.de Wed Mar 12 23:06:10 2003 From: rguenth at tat.physik.uni-tuebingen.de (Richard Guenther) Date: Thu, 13 Mar 2003 00:06:10 +0100 (CET) Subject: [pooma-dev] [PATCH] Re: Two New Array Failures In-Reply-To: Message-ID: On Wed, 12 Mar 2003, Richard Guenther wrote: > Hi! > > The attached patch canonicalizes Engine::domain() const to return a > const reference to its domain. It can do so by adding a domain_m > member to the expression engine (pls review this part carefully, as > in some of the constructors we might do things more optimally if I > had understood what they actually do...). > > (We might do something similar to the Engine::layout() const methods, > though this would affect many more engines to be added a layout_m member) > > Testing is still in progress, but the concept sounds reasonable? Build and testing completed with no regressions in Engine, Array and Field on ppc-linux with gcc 3.2.3 Ok to apply? Thanks, Richard. From jcrotinger at proximation.com Thu Mar 13 07:28:08 2003 From: jcrotinger at proximation.com (James Crotinger) Date: Thu, 13 Mar 2003 00:28:08 -0700 Subject: [pooma-dev] [PATCH] Re: Two New Array Failures Message-ID: I wouldn't apply this without careful performance testing on a large-ish problem using KCC (or some other compiler that really inlines everything that it is told to inline and optimizes the hell out of the results). This seems like a reasonable thing to do, but I worry about adding additional code to the construction of expressions since they are constructed recursively and it is expected that a lot of stuff that goes on in their usage will be inlined away. Back in the day we ran into a number of cases where it was easy to push the optimizer over the edge and lose a lot of performance with KCC and SGI CC (the only two compilers that, as far as I know, have approached hand-coded loop speed for Pooma Array code, which is THE goal.) This is most important in ExpressionEngines built out of Brick-engines - i.e. the iterates that ultimately are created and evaluated in evaluating a multipatch expression. If the loops over these expression engines don't completely inline, and basically end up looking like what you'd write by hand, you're hosed, from a performance perspective. Unless things have changed dramatically, gcc 3 is not at the level of performance to make this assessment. (Jeffrey, do you agree?) Jim ------------------------------------------------------------------------ James A. Crotinger email: jimc at proximation.com NumeriX, LLC phone: (505) 424-4477 x104 2960 Rodeo Park Dr. W. Santa Fe, NM 87505 -----Original Message----- From: Richard Guenther [mailto:rguenth at tat.physik.uni-tuebingen.de] Sent: Wednesday, March 12, 2003 4:06 PM To: Jeffrey Oldham Cc: pooma-dev at pooma.codesourcery.com Subject: Re: [pooma-dev] [PATCH] Re: Two New Array Failures On Wed, 12 Mar 2003, Richard Guenther wrote: > Hi! > > The attached patch canonicalizes Engine::domain() const to return a > const reference to its domain. It can do so by adding a domain_m > member to the expression engine (pls review this part carefully, as > in some of the constructors we might do things more optimally if I > had understood what they actually do...). > > (We might do something similar to the Engine::layout() const methods, > though this would affect many more engines to be added a layout_m member) > > Testing is still in progress, but the concept sounds reasonable? Build and testing completed with no regressions in Engine, Array and Field on ppc-linux with gcc 3.2.3 Ok to apply? Thanks, Richard. -------------- next part -------------- An HTML attachment was scrubbed... URL: From rguenth at tat.physik.uni-tuebingen.de Thu Mar 13 08:52:11 2003 From: rguenth at tat.physik.uni-tuebingen.de (Richard Guenther) Date: Thu, 13 Mar 2003 09:52:11 +0100 (CET) Subject: [pooma-dev] [PATCH] Re: Two New Array Failures In-Reply-To: Message-ID: On Thu, 13 Mar 2003, James Crotinger wrote: > I wouldn't apply this without careful performance testing on a large-ish > problem using KCC (or some other compiler that really inlines everything > that it is told to inline and optimizes the hell out of the results). This > seems like a reasonable thing to do, but I worry about adding additional > code to the construction of expressions since they are constructed > recursively and it is expected that a lot of stuff that goes on in their > usage will be inlined away. Be aware that I only added a member to the expression _engine_ - this one isnt constructed recursively, but only one time per expression (if I'm right). Also the only other way to fix some of the problems I'm seeing is to make all Engine::domain() return copies of their domain and fix up all potential callers to be aware of this. But yes, some performance regression tests seem useful, though I dont have KCC available and SGI CC in maybe too old version, as this doesnt pass the regression tests we already have. I have some small code of performance test that checks the same term with expression templates, a stencil and scalarcode, I'll improve that and look how to easily turn that into some automatic testing. Richard. > Back in the day we ran into a number of cases > where it was easy to push the optimizer over the edge and lose a lot of > performance with KCC and SGI CC (the only two compilers that, as far as I > know, have approached hand-coded loop speed for Pooma Array code, which is > THE goal.) This is most important in ExpressionEngines built out of > Brick-engines - i.e. the iterates that ultimately are created and evaluated > in evaluating a multipatch expression. If the loops over these expression > engines don't completely inline, and basically end up looking like what > you'd write by hand, you're hosed, from a performance perspective. Unless > things have changed dramatically, gcc 3 is not at the level of performance > to make this assessment. (Jeffrey, do you agree?) > > Jim > > ------------------------------------------------------------------------ > James A. Crotinger email: jimc at proximation.com > NumeriX, LLC phone: (505) 424-4477 x104 > 2960 Rodeo Park Dr. W. > Santa Fe, NM 87505 -- Richard Guenther WWW: http://www.tat.physik.uni-tuebingen.de/~rguenth/ From rguenth at tat.physik.uni-tuebingen.de Thu Mar 13 10:15:12 2003 From: rguenth at tat.physik.uni-tuebingen.de (Richard Guenther) Date: Thu, 13 Mar 2003 11:15:12 +0100 (CET) Subject: [pooma-dev] KCC versus icc In-Reply-To: <5.1.0.14.2.20030227150732.00a9dbc0@popout.llnl.gov> Message-ID: On Thu, 27 Feb 2003, Paul A. Renard wrote: > Richard (and Jeffrey); > > I've tried various combinations of -O2, -ip, and -ipo.??? Both -ip options make > the loop represented by the data-parallel expression run slower.? I also tried > profile-directed optimization, and that did indeed make a very-slight? > improvement (on the order of a percent), but icc is still producing code for > that particular loop that is 3.5X-4X slower.? The compiler seems to be inlining > quite a bit.? In fact, all the constructors and destructors look like they are > inlined.? KCC doesn't seem to inline the constructors/destructors for this > case.? Both cases eventually call the evaluator, and at that point I get lost > in the machine code. I finally got to look what options I used to get at least some performance out of icc. The key was to bump the insn number for always inlined small functions artificially high, i.e. I used something along icpc -O2 -unroll -xM -tpp6 -ip -Qoption,c,-ip_ninl_min_stats=1000 This way I get the same performance as gcc 3.3 when using --param max-inline-slope=1000000 (icpc is slightly faster for in-cache operation - but who has data that fits into cache...) Hope this helps. Richard. -- Richard Guenther WWW: http://www.tat.physik.uni-tuebingen.de/~rguenth/ From rguenth at tat.physik.uni-tuebingen.de Fri Mar 14 22:27:18 2003 From: rguenth at tat.physik.uni-tuebingen.de (Richard Guenther) Date: Fri, 14 Mar 2003 23:27:18 +0100 (CET) Subject: [PATCH] Kill pre-instantiation Message-ID: Hi! The following patch kills pre-instantiation and thereby cuts some of the build time and libpooma.a size to 2/3 (on ppc). Instantiation into the library should be done carefully by projects using pooma, we certainly shouldnt instantiate for dims 1-n unconditionally. Tested by building lib and some tests. Ok? (File removals omitted from patch, but in summary) Richard. # This is a BitKeeper generated patch for the following project: # Project Name: pooma/cheetah repository tracking CVS/tarball # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.44 -> 1.46 # r2/configure 1.7 -> 1.8 # r2/src/Engine/BrickEngine.1.inst.cpp 1.1 -> (deleted) # r2/src/Engine/BrickBase5.cmpl.cpp 1.1 -> (deleted) # r2/src/Engine/BrickBase6.cmpl.cpp 1.1 -> (deleted) # r2/src/Engine/BrickEngine.3.inst.cpp 1.1 -> (deleted) # r2/src/Engine/BrickBase3.cmpl.cpp 1.1 -> (deleted) # r2/src/Engine/BrickBase4.cmpl.cpp 1.1 -> (deleted) # r2/src/Layout/UniformGridLayout.inst.cpp 1.1 -> (deleted) # r2/src/Engine/BrickBase2.cmpl.cpp 1.1 -> (deleted) # r2/src/Engine/BrickEngine.5.inst.cpp 1.1 -> (deleted) # r2/src/Engine/BrickBase7.cmpl.cpp 1.1 -> (deleted) # r2/src/subdir.mk 1.1 -> 1.2 # r2/src/Engine/objfile.mk 1.1 -> (deleted) # r2/src/Engine/BrickBase1.cmpl.cpp 1.1 -> (deleted) # r2/src/Engine/BrickEngine.4.inst.cpp 1.1 -> (deleted) # r2/src/Engine/BrickEngine.2.inst.cpp 1.1 -> (deleted) # r2/src/Engine/BrickEngine.7.inst.cpp 1.1 -> (deleted) # r2/src/Engine/BrickBase.h 1.2 -> 1.3 # r2/src/FileTemplates/FileTemplate.inst.cpp 1.1 -> (deleted) # r2/src/Engine/include.mk 1.1 -> (deleted) # r2/src/Engine/BrickEngine.6.inst.cpp 1.1 -> (deleted) # r2/src/Layout/objfile.mk 1.1 -> 1.3 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 03/03/14 richard at goofy.(none) 1.45 # drop pre-instantiation support # -------------------------------------------- # 03/03/14 richard at goofy.(none) 1.46 # more pre-instantiation removal # -------------------------------------------- # diff -Nru a/r2/configure b/r2/configure --- a/r2/configure Fri Mar 14 23:24:52 2003 +++ b/r2/configure Fri Mar 14 23:24:52 2003 @@ -194,7 +194,6 @@ $noonepernm = "--nooneper"; $schednm = "--sched"; $boundsnm = "--bounds"; -$preinstnm = "--preinst"; $printdbgnm = "--printdebug"; $finternm = "--with-fortran"; $nofinternm = "--without-fortran"; @@ -236,7 +235,6 @@ [$sharednm, "", "create a shared library."], [$finternm, "", "include fortran support libraries."], [$nofinternm, "", "do not include the fortran libraries."], - [$preinstnm, "", "build preinstantiations of several classes."], [$serialnm, "", "configure to run serially, no parallelism."], [$threadsnm, "", "include threads capability, if available."], [$cheetahnm, "", "enable use of CHEETAH communications package."], @@ -925,19 +923,6 @@ # ########################################################################### -### figure out if we should do preinstantiation -sub setpreinstantiate -{ - - if (scalar @{$arghash{$preinstnm}} > 1) - { - $preinstantiate = 1; - $extensions .= "-preinst"; - } - print "Set preinstantiate = $preinstantiate\n" if $dbgprnt; - add_yesno_define("POOMA_PREINSTANTIATE", $preinstantiate); -} - ### figure out if verbose output from comp/link should be used sub setverbose @@ -1876,14 +1861,6 @@ print FSUITE "POOMA_LIBEXT = $libext\n"; print FSUITE "POOMA_LIBRARY = lib\$(POOMA_LIBNAME).\$(POOMA_LIBEXT)\n"; print FSUITE "\n"; - - # if we should do preinstantiation, set makefile variable - if ($preinstantiate) - { - print FSUITE "### preinstantiate several classes\n"; - print FSUITE "POOMA_PREINSTANTIATE = 1\n"; - print FSUITE "\n"; - } # if we are using PAWS, must add extra statements to suite file if ($paws or $pawsdev) diff -Nru a/r2/src/Engine/BrickBase.h b/r2/src/Engine/BrickBase.h --- a/r2/src/Engine/BrickBase.h Fri Mar 14 23:24:52 2003 +++ b/r2/src/Engine/BrickBase.h Fri Mar 14 23:24:52 2003 @@ -758,8 +758,9 @@ /////////////////////////////////////////////////////////////////////////////// -// We explicitly instantiate everything, so there is no include -// of BrickBase.cpp here! +// Include .cpp file to get out-of-line functions. + +#include "Engine/BrickBase.cpp" #endif // POOMA_ENGINE_BRICKBASE_H diff -Nru a/r2/src/Layout/objfile.mk b/r2/src/Layout/objfile.mk --- a/r2/src/Layout/objfile.mk Fri Mar 14 23:24:52 2003 +++ b/r2/src/Layout/objfile.mk Fri Mar 14 23:24:52 2003 @@ -31,18 +31,11 @@ # Object file list. # This list is user-editable. -# Be sure that $(UNIQUE)_OBJS is set, even if set to empty. -ifdef POOMA_PREINSTANTIATE $(UNIQUE)_OBJS := \ - $(ODIR)/UniformGridLayout.inst.o \ $(ODIR)/DynamicLayout.cmpl.o \ $(ODIR)/GlobalIDDataBase.cmpl.o -else -$(UNIQUE)_OBJS := \ - $(ODIR)/DynamicLayout.cmpl.o \ - $(ODIR)/GlobalIDDataBase.cmpl.o -endif + LOCAL_OBJS += $($(UNIQUE)_OBJS) # Set rules for the ODIR directory diff -Nru a/r2/src/subdir.mk b/r2/src/subdir.mk --- a/r2/src/subdir.mk Fri Mar 14 23:24:52 2003 +++ b/r2/src/subdir.mk Fri Mar 14 23:24:52 2003 @@ -41,10 +41,6 @@ include $(THISDIR)/$(NEXTDIR)/include.mk THISDIR :=$(firstword $(DIR_LIST)) -NEXTDIR := Engine -include $(THISDIR)/$(NEXTDIR)/include.mk -THISDIR :=$(firstword $(DIR_LIST)) - NEXTDIR := IO include $(THISDIR)/$(NEXTDIR)/include.mk THISDIR :=$(firstword $(DIR_LIST)) From rguenth at tat.physik.uni-tuebingen.de Fri Mar 14 22:30:58 2003 From: rguenth at tat.physik.uni-tuebingen.de (Richard Guenther) Date: Fri, 14 Mar 2003 23:30:58 +0100 (CET) Subject: [PATCH] Add const char* specialization to Inform::operator<< Message-ID: Hi! The following patch removes lots of Inform::operator<<(.., char[N]) instances from binaries by adding a specialization for const char*. Ok? Richard. diff -Nru a/r2/src/Utilities/Inform.h b/r2/src/Utilities/Inform.h --- a/r2/src/Utilities/Inform.h Fri Mar 14 23:28:50 2003 +++ b/r2/src/Utilities/Inform.h Fri Mar 14 23:28:50 2003 @@ -483,12 +483,22 @@ //----------------------------------------------------------------------------- +// specialized function for sending C strings to Inform object +//----------------------------------------------------------------------------- + +inline Inform &operator<<(Inform &o, const char *s) +{ + o.stream() << s; + return o; +} + +//----------------------------------------------------------------------------- // specialized function for sending strings to Inform object //----------------------------------------------------------------------------- inline Inform &operator<<(Inform &o, const std::string &s) { - o << s.c_str(); + o.stream() << s.c_str(); return o; } From jcrotinger at proximation.com Sat Mar 15 20:49:45 2003 From: jcrotinger at proximation.com (James Crotinger) Date: Sat, 15 Mar 2003 13:49:45 -0700 Subject: [pooma-dev] [PATCH] Kill pre-instantiation Message-ID: I don't know what the state-of-the-art is for template instantiations on the various platforms where POOMA is now used, but if memory serves, KCC and SGI CC were greatly helped by pre-instantiating this stuff. This is a pain for POOMA developers (i.e. they suffered longer rebuild times), but for POOMA users it made a big difference in how long it took to "link" their codes (which include all the pre-link cycles, which are particularly painful with optimization enabled). So I certainly wouldn't nuke this capability. Perhaps allowing the configuration to turn it off or limit it to lower dimensionality would be useful. Jim ------------------------------------------------------------------------ James A. Crotinger email: jimc at numerix.com NumeriX, LLC phone: (505) 424-4477 x104 2960 Rodeo Park Dr. W. Santa Fe, NM 87505 -----Original Message----- From: Richard Guenther [mailto:rguenth at tat.physik.uni-tuebingen.de] Sent: Friday, March 14, 2003 3:27 PM To: pooma-dev at pooma.codesourcery.com Cc: Jeffrey D. Oldham Subject: [pooma-dev] [PATCH] Kill pre-instantiation Hi! The following patch kills pre-instantiation and thereby cuts some of the build time and libpooma.a size to 2/3 (on ppc). Instantiation into the library should be done carefully by projects using pooma, we certainly shouldnt instantiate for dims 1-n unconditionally. Tested by building lib and some tests. Ok? (File removals omitted from patch, but in summary) Richard. # This is a BitKeeper generated patch for the following project: # Project Name: pooma/cheetah repository tracking CVS/tarball # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.44 -> 1.46 # r2/configure 1.7 -> 1.8 # r2/src/Engine/BrickEngine.1.inst.cpp 1.1 -> (deleted) # r2/src/Engine/BrickBase5.cmpl.cpp 1.1 -> (deleted) # r2/src/Engine/BrickBase6.cmpl.cpp 1.1 -> (deleted) # r2/src/Engine/BrickEngine.3.inst.cpp 1.1 -> (deleted) # r2/src/Engine/BrickBase3.cmpl.cpp 1.1 -> (deleted) # r2/src/Engine/BrickBase4.cmpl.cpp 1.1 -> (deleted) # r2/src/Layout/UniformGridLayout.inst.cpp 1.1 -> (deleted) # r2/src/Engine/BrickBase2.cmpl.cpp 1.1 -> (deleted) # r2/src/Engine/BrickEngine.5.inst.cpp 1.1 -> (deleted) # r2/src/Engine/BrickBase7.cmpl.cpp 1.1 -> (deleted) # r2/src/subdir.mk 1.1 -> 1.2 # r2/src/Engine/objfile.mk 1.1 -> (deleted) # r2/src/Engine/BrickBase1.cmpl.cpp 1.1 -> (deleted) # r2/src/Engine/BrickEngine.4.inst.cpp 1.1 -> (deleted) # r2/src/Engine/BrickEngine.2.inst.cpp 1.1 -> (deleted) # r2/src/Engine/BrickEngine.7.inst.cpp 1.1 -> (deleted) # r2/src/Engine/BrickBase.h 1.2 -> 1.3 # r2/src/FileTemplates/FileTemplate.inst.cpp 1.1 -> (deleted) # r2/src/Engine/include.mk 1.1 -> (deleted) # r2/src/Engine/BrickEngine.6.inst.cpp 1.1 -> (deleted) # r2/src/Layout/objfile.mk 1.1 -> 1.3 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 03/03/14 richard at goofy.(none) 1.45 # drop pre-instantiation support # -------------------------------------------- # 03/03/14 richard at goofy.(none) 1.46 # more pre-instantiation removal # -------------------------------------------- # diff -Nru a/r2/configure b/r2/configure --- a/r2/configure Fri Mar 14 23:24:52 2003 +++ b/r2/configure Fri Mar 14 23:24:52 2003 @@ -194,7 +194,6 @@ $noonepernm = "--nooneper"; $schednm = "--sched"; $boundsnm = "--bounds"; -$preinstnm = "--preinst"; $printdbgnm = "--printdebug"; $finternm = "--with-fortran"; $nofinternm = "--without-fortran"; @@ -236,7 +235,6 @@ [$sharednm, "", "create a shared library."], [$finternm, "", "include fortran support libraries."], [$nofinternm, "", "do not include the fortran libraries."], - [$preinstnm, "", "build preinstantiations of several classes."], [$serialnm, "", "configure to run serially, no parallelism."], [$threadsnm, "", "include threads capability, if available."], [$cheetahnm, "", "enable use of CHEETAH communications package."], @@ -925,19 +923,6 @@ # ########################################################################### -### figure out if we should do preinstantiation -sub setpreinstantiate -{ - - if (scalar @{$arghash{$preinstnm}} > 1) - { - $preinstantiate = 1; - $extensions .= "-preinst"; - } - print "Set preinstantiate = $preinstantiate\n" if $dbgprnt; - add_yesno_define("POOMA_PREINSTANTIATE", $preinstantiate); -} - ### figure out if verbose output from comp/link should be used sub setverbose @@ -1876,14 +1861,6 @@ print FSUITE "POOMA_LIBEXT = $libext\n"; print FSUITE "POOMA_LIBRARY = lib\$(POOMA_LIBNAME).\$(POOMA_LIBEXT)\n"; print FSUITE "\n"; - - # if we should do preinstantiation, set makefile variable - if ($preinstantiate) - { - print FSUITE "### preinstantiate several classes\n"; - print FSUITE "POOMA_PREINSTANTIATE = 1\n"; - print FSUITE "\n"; - } # if we are using PAWS, must add extra statements to suite file if ($paws or $pawsdev) diff -Nru a/r2/src/Engine/BrickBase.h b/r2/src/Engine/BrickBase.h --- a/r2/src/Engine/BrickBase.h Fri Mar 14 23:24:52 2003 +++ b/r2/src/Engine/BrickBase.h Fri Mar 14 23:24:52 2003 @@ -758,8 +758,9 @@ //////////////////////////////////////////////////////////////////////////// /// -// We explicitly instantiate everything, so there is no include -// of BrickBase.cpp here! +// Include .cpp file to get out-of-line functions. + +#include "Engine/BrickBase.cpp" #endif // POOMA_ENGINE_BRICKBASE_H diff -Nru a/r2/src/Layout/objfile.mk b/r2/src/Layout/objfile.mk --- a/r2/src/Layout/objfile.mk Fri Mar 14 23:24:52 2003 +++ b/r2/src/Layout/objfile.mk Fri Mar 14 23:24:52 2003 @@ -31,18 +31,11 @@ # Object file list. # This list is user-editable. -# Be sure that $(UNIQUE)_OBJS is set, even if set to empty. -ifdef POOMA_PREINSTANTIATE $(UNIQUE)_OBJS := \ - $(ODIR)/UniformGridLayout.inst.o \ $(ODIR)/DynamicLayout.cmpl.o \ $(ODIR)/GlobalIDDataBase.cmpl.o -else -$(UNIQUE)_OBJS := \ - $(ODIR)/DynamicLayout.cmpl.o \ - $(ODIR)/GlobalIDDataBase.cmpl.o -endif + LOCAL_OBJS += $($(UNIQUE)_OBJS) # Set rules for the ODIR directory diff -Nru a/r2/src/subdir.mk b/r2/src/subdir.mk --- a/r2/src/subdir.mk Fri Mar 14 23:24:52 2003 +++ b/r2/src/subdir.mk Fri Mar 14 23:24:52 2003 @@ -41,10 +41,6 @@ include $(THISDIR)/$(NEXTDIR)/include.mk THISDIR :=$(firstword $(DIR_LIST)) -NEXTDIR := Engine -include $(THISDIR)/$(NEXTDIR)/include.mk -THISDIR :=$(firstword $(DIR_LIST)) - NEXTDIR := IO include $(THISDIR)/$(NEXTDIR)/include.mk THISDIR :=$(firstword $(DIR_LIST)) -------------- next part -------------- An HTML attachment was scrubbed... URL: From rguenth at tat.physik.uni-tuebingen.de Mon Mar 17 10:03:11 2003 From: rguenth at tat.physik.uni-tuebingen.de (Richard Guenther) Date: Mon, 17 Mar 2003 11:03:11 +0100 (CET) Subject: [pooma-dev] [PATCH] Kill pre-instantiation In-Reply-To: Message-ID: On Sat, 15 Mar 2003, James Crotinger wrote: > I don't know what the state-of-the-art is for template instantiations on the > various platforms where POOMA is now used, but if memory serves, KCC and SGI > CC were greatly helped by pre-instantiating this stuff. This is a pain for > POOMA developers (i.e. they suffered longer rebuild times), but for POOMA > users it made a big difference in how long it took to "link" their codes > (which include all the pre-link cycles, which are particularly painful with > optimization enabled). So I certainly wouldn't nuke this capability. Perhaps > allowing the configuration to turn it off or limit it to lower > dimensionality would be useful. At least for gcc you do not prevent gcc from emitting duplicates of preinstantiated objects this way - they just get deleted at link time. For other compilers I know only the way IRIX CC does, which requires more installation effort to make it work (didnt check if the current install installs everything required). And I doubt preinstantiation will work with a shared library in the current setup at all (didnt check, too). The way I'd prefer doing preinstantiation is in the users application - just build an extra .o file with just preinstantiations, those which you actually need. I can cook something into README/INSTALL if you like. Richard. -- Richard Guenther WWW: http://www.tat.physik.uni-tuebingen.de/~rguenth/ From cantao at ime.unicamp.br Mon Mar 17 19:28:44 2003 From: cantao at ime.unicamp.br (Renato F. Cantao) Date: Mon, 17 Mar 2003 16:28:44 -0300 (BRT) Subject: License Message-ID: Hi! Some time ago there was some discussion on the list about the Pooma licensing. To be short: can I use Pooma in commercial, closed source projects? Thanks a lot guys! Cantao! ''' (o o) +--------------oOOO--(_)----------------------+ | Renato F. Cantao! | | Depto. de Matematica Aplicada | | IMECC - UNICAMP | | Sala 215 - Predio da Pos-graduacao - Lado B | +--------------------------OOOo---------------+ |__|__| || || ooO Ooo Linux User #207462 From rguenth at tat.physik.uni-tuebingen.de Tue Mar 18 08:33:22 2003 From: rguenth at tat.physik.uni-tuebingen.de (Richard Guenther) Date: Tue, 18 Mar 2003 09:33:22 +0100 (CET) Subject: [pooma-dev] License In-Reply-To: Message-ID: On Mon, 17 Mar 2003, Renato F. Cantao wrote: > Hi! > > Some time ago there was some discussion on the list about the Pooma > licensing. To be short: can I use Pooma in commercial, closed source > projects? Yes, I think so - the license is basically a BSD like. But you should ask a lawyer, as the wording is not exactly clear. Richard. -- Richard Guenther WWW: http://www.tat.physik.uni-tuebingen.de/~rguenth/ From jcrotinger at proximation.com Tue Mar 18 16:25:03 2003 From: jcrotinger at proximation.com (James Crotinger) Date: Tue, 18 Mar 2003 09:25:03 -0700 Subject: [pooma-dev] License Message-ID: Our intent was to make POOMA available for commercial use, with the usual provisos of retaining the copyright, giving credit, etc. Prior to 2.3, the license explicitly said "NONCOMMERCIAL" and we got the lab to amend that language for the 2.3 release. Of course, that doesn't mean you shouldn't have a lawyer look at it. Jim ------------------------------------------------------------------------ James A. Crotinger email: jimc at numerix.com NumeriX, LLC phone: (505) 424-4477 x104 2960 Rodeo Park Dr. W. Santa Fe, NM 87505 -----Original Message----- From: Richard Guenther [mailto:rguenth at tat.physik.uni-tuebingen.de] Sent: Tuesday, March 18, 2003 1:33 AM To: Renato F. Cantao Cc: pooma-dev at pooma.codesourcery.com Subject: Re: [pooma-dev] License On Mon, 17 Mar 2003, Renato F. Cantao wrote: > Hi! > > Some time ago there was some discussion on the list about the Pooma > licensing. To be short: can I use Pooma in commercial, closed source > projects? Yes, I think so - the license is basically a BSD like. But you should ask a lawyer, as the wording is not exactly clear. Richard. -- Richard Guenther WWW: http://www.tat.physik.uni-tuebingen.de/~rguenth/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From mark at codesourcery.com Tue Mar 18 22:02:20 2003 From: mark at codesourcery.com (Mark Mitchell) Date: 18 Mar 2003 14:02:20 -0800 Subject: [Fwd: Non-Uniform Mesh] Message-ID: <1048024941.22444.117.camel@doubledemon.codesourcery.com> -- Mark Mitchell CodeSourcery, LLC mark at codesourcery.com -------------- next part -------------- An embedded message was scrubbed... From: Timothy William Chevalier Subject: Non-Uniform Mesh Date: Tue, 18 Mar 2003 10:40:50 -0800 (PST) Size: 1161 URL: From rguenth at tat.physik.uni-tuebingen.de Tue Mar 18 22:12:06 2003 From: rguenth at tat.physik.uni-tuebingen.de (Richard Guenther) Date: Tue, 18 Mar 2003 23:12:06 +0100 (CET) Subject: [pooma-dev] [Fwd: Non-Uniform Mesh] In-Reply-To: <1048024941.22444.117.camel@doubledemon.codesourcery.com> Message-ID: On 18 Mar 2003, Mark Mitchell wrote: > Is there any support for the non-uniform mesh in pooma ver. 2.4? > It seems that the new version lacks the header RectilinearMesh.h and only > has support for the UniformRectilinearMesh as in version 2.3. > > Thank you, > > Tim I have this one in my local repository, but need to split away parts I may not give away. Richard. From rguenth at tat.physik.uni-tuebingen.de Wed Mar 19 09:21:46 2003 From: rguenth at tat.physik.uni-tuebingen.de (Richard Guenther) Date: Wed, 19 Mar 2003 10:21:46 +0100 (CET) Subject: [pooma-dev] [Fwd: Non-Uniform Mesh] In-Reply-To: Message-ID: On Tue, 18 Mar 2003, Richard Guenther wrote: > On 18 Mar 2003, Mark Mitchell wrote: > > > Is there any support for the non-uniform mesh in pooma ver. 2.4? > > It seems that the new version lacks the header RectilinearMesh.h and > only > > has support for the UniformRectilinearMesh as in version 2.3. > > > > Thank you, > > > > Tim > > I have this one in my local repository, but need to split away parts I > may not give away. Ok, here it is (my revision history says "first working version", but that was for a local pooma repository one year ago, so no guarrantees). Richard. -- Richard Guenther WWW: http://www.tat.physik.uni-tuebingen.de/~rguenth/ -------------- next part -------------- // -*- C++ -*- // ACL:license // ---------------------------------------------------------------------- // This software and ancillary information (herein called "SOFTWARE") // called POOMA (Parallel Object-Oriented Methods and Applications) is // made available under the terms described here. The SOFTWARE has been // approved for release with associated LA-CC Number LA-CC-98-65. // // Unless otherwise indicated, this SOFTWARE has been authored by an // employee or employees of the University of California, operator of the // Los Alamos National Laboratory under Contract No. W-7405-ENG-36 with // the U.S. Department of Energy. The U.S. Government has rights to use, // reproduce, and distribute this SOFTWARE. The public may copy, distribute, // prepare derivative works and publicly display this SOFTWARE without // charge, provided that this Notice and any statement of authorship are // reproduced on all copies. Neither the Government nor the University // makes any warranty, express or implied, or assumes any liability or // responsibility for the use of this SOFTWARE. // // If SOFTWARE is modified to produce derivative works, such modified // SOFTWARE should be clearly marked, so as not to confuse it with the // version available from LANL. // // For more information about POOMA, send e-mail to pooma at acl.lanl.gov, // or visit the POOMA web page at http://www.acl.lanl.gov/pooma/. // ---------------------------------------------------------------------- // ACL:license /** @file * @ingroup Mesh * @brief * A rectilinear mesh without uniform spacing between vertices. */ #ifndef POOMA_FIELD_MESH_RECTILINEARMESH_H #define POOMA_FIELD_MESH_RECTILINEARMESH_H //----------------------------------------------------------------------------- // Includes: //----------------------------------------------------------------------------- #include #include "Engine/ConstantFunctionEngine.h" // Used in functors #include "Engine/IndexFunctionEngine.h" // Used in functors #include "Layout/INode.h" // Used in ctors #include "Field/FieldEngine/FieldEnginePatch.h" // Used in ctors #include "Field/Mesh/NoMesh.h" // Base class #include "Field/FieldCentering.h" // Centering inline #include "Tiny/Vector.h" // Class member //----------------------------------------------------------------------------- /// Holds the data for a rectilinear mesh. That class has a ref-counted /// instance of this class. //----------------------------------------------------------------------------- template class RectilinearMeshData : public NoMeshData { public: //--------------------------------------------------------------------------- // Constructors. /// We provide a default constructor that creates the object with empty /// domains. To be useful, this object must be replaced by another /// version via assignment. RectilinearMeshData() { // This space intentionally left blank. } /// This constructor fully constructs the object. It uses the layout to /// compute domains and also initializes the origin and the spacings in each /// coordinate direction. The indices in the layout refer to VERTEX /// positions. template RectilinearMeshData( const Layout &layout, const Vector &origin, const Vector > &spacings) : NoMeshData(layout), origin_m(origin) //spacings_m(spacings) { for (int i=0; i I(layout.domain()[i]); positions_m(i).engine() = Engine<1, T, Brick>(I); positions_m(i)(0) = origin_m(i); // initialize from origin downward the ghost cells for (int j=-1; j>=I.min(); j--) positions_m(i)(j) = positions_m(i).read(j+1) - spacings_m(i).read(j); // initialize from origin upward for (int j=1; j<=I.max(); j++) positions_m(i)(j) = positions_m(i).read(j-1) + spacings_m(i).read(j-1); } } /// Constructor for constructing evenly spaced rectilinear meshes just /// like UniformRectilinearMesh does. template RectilinearMeshData( const Layout &layout, const Vector &origin, const Vector &spacings) : NoMeshData(layout), origin_m(origin) { // for each dimension we allocate engines for spacings & positions // and initialize them according to origin/spacings for (int i=0; i I(layout.domain()[i]); // allocate and assign spacings spacings_m(i).engine() = Engine<1, T, Brick>(I); spacings_m(i)(I) = spacings(i); // no Array.all() Pooma::blockAndEvaluate(); // allocate positions, assign origin positions_m(i).engine() = Engine<1, T, Brick>(I); positions_m(i)(0) = origin_m(i); // initialize from origin downward the ghost cells for (int j=-1; j>=I.min(); j--) positions_m(i)(j) = positions_m(i).read(j+1) - spacings_m(i).read(j); // initialize from origin upward for (int j=1; j<=I.max(); j++) positions_m(i)(j) = positions_m(i).read(j-1) + spacings_m(i).read(j-1); } } /// Copy constructor. RectilinearMeshData(const RectilinearMeshData &model) : NoMeshData(model), origin_m(model.origin_m) //spacings_m(model.spacings_m), //positions_m(model.positions_m) { for (int i=0; i &model, const Interval &d) : NoMeshData(d) { for (int i = 0; i < Dim; i++) { // FIXME: Wheeee ;) (we cant store a BrickView... // and still dont want to copy) spacings_m(i).engine() = Engine<1, T, Brick>(&model.spacings_m(i)(d[i])(0), d[i]); positions_m(i).engine() = Engine<1, T, Brick>(&model.positions_m(i)(d[i])(0), d[i]); origin_m(i) = positions_m(i)(d[i].min()); } } /// FieldEnginePatch view. We don't fiddle with the origin because we are not /// making the domain zero-based. /// /// The domain supplied by the FieldEnginePatch must refer to VERTEX /// positions. RectilinearMeshData(const RectilinearMeshData &model, const FieldEnginePatch &p) : NoMeshData(model, p), origin_m(model.origin_m), spacings_m(model.spacings_m), positions_m(model.spacings_m) { // FIXME: what does FieldEnginePatch do??? for (int i=0; i & operator=(const RectilinearMeshData &rhs) { if (this != &rhs) { NoMeshData::operator=(rhs); origin_m = rhs.origin_m; for (int i=0; i > &spacings() const { return spacings_m; } /// The mesh vertex positions. inline const Vector > &positions() const { return positions_m; } /// The mesh origin. inline const Vector &origin() const { return origin_m; } //@} private: /// Origin of mesh (coordinate vector of first vertex). Vector origin_m; /// Spacings between vertices. Vector > spacings_m; /// Vertex positions. Vector > positions_m; }; /// /// RectilinearMesh is a rectilinear mesh sometimes called a /// "cartesian product" or "tensor product" mesh. Each dimension has a /// spacing value between every pair of vertices along that dimension; /// these spacings can all be different. /// template class RectilinearMesh { public: //--------------------------------------------------------------------------- // Exported typedefs and enumerations. /// The type of mesh points. typedef Vector PointType_t; /// The type of vectors used to represent, for example, normals. typedef Vector VectorType_t; /// The type used to store spacings. typedef Vector > SpacingsType_t; /// The type T, used to represent, for example, volumes & areas, etc. typedef T T_t; /// The number of indices required to select a point in this mesh. enum { dimensions = Dim }; //--------------------------------------------------------------------------- // Constructors. /// We supply a default constructor, but it doesn't generate a useful mesh. /// This is accomplished through assignment. RectilinearMesh() : data_m(new RectilinearMeshData) { // This space intentionally left blank. } /// This constructor fully constructs the object. It uses the layout to /// compute domains and also initializes the origin and the spacings in each /// coordinate direction. /// /// The Layout supplied must refer to VERTEX positions. template inline RectilinearMesh(const Layout &layout, const PointType_t &origin, const Vector > &spacings) : data_m(new RectilinearMeshData(layout, origin, spacings)) { } /// Constructor compatible to UniformRectilinearMesh. template inline RectilinearMesh(const Layout &layout, const PointType_t &origin, const PointType_t &spacings) : data_m(new RectilinearMeshData(layout, origin, spacings)) { } template inline RectilinearMesh(const Layout &layout) : data_m(new RectilinearMeshData(layout, PointType_t(0), PointType_t(1))) { } /// Copy constructor. inline RectilinearMesh(const RectilinearMesh &model) : data_m(model.data_m) { } /// @name View constructors /// These are the only possible views of this /// mesh. Other views will make a NoMesh. //@{ /// Interval view. /// /// The Interval supplied must refer to VERTEX positions. inline RectilinearMesh(const RectilinearMesh &model, const Interval &d) : data_m(new RectilinearMeshData(*model.data_m, d)) { } /// INode view. /// /// The INode supplied must refer to VERTEX positions. inline RectilinearMesh(const RectilinearMesh &model, const INode &i) : data_m(new RectilinearMeshData(*model.data_m, i.domain())) { } /// FieldEnginePatch view. /// /// The FieldEnginePatch supplied must refer to VERTEX positions. inline RectilinearMesh(const RectilinearMesh &model, const FieldEnginePatch &p) : data_m(new RectilinearMeshData(*model.data_m, p)) { } //@} //--------------------------------------------------------------------------- /// Copy assignment operator. inline RectilinearMesh & operator=(const RectilinearMesh &rhs) { if (&rhs != this) { data_m = rhs.data_m; } return *this; } //--------------------------------------------------------------------------- /// Empty destructor is fine. The pointer to the data is ref-counted so its /// lifetime is correctly managed. ~RectilinearMesh() { } //--------------------------------------------------------------------------- /// @name Domain functions. //@{ /// The vertex domain, as the mesh was constructed with. inline const Interval &physicalVertexDomain() const { return data_m->physicalVertexDomain(); } /// Function that returns a domain adjusted to give the indices of the cells. inline const Interval &physicalCellDomain() const { return data_m->physicalCellDomain(); } /// The total vertex domain, including mesh guard vertices. inline const Interval &totalVertexDomain() const { return data_m->totalVertexDomain(); } /// The total cell domain, including mesh guard cells. inline const Interval &totalCellDomain() const { return data_m->totalCellDomain(); } //@} //--------------------------------------------------------------------------- /// @name General accessors. //@{ /// The mesh spacing. inline const Vector > &spacings() const { return data_m->spacings(); } /// The mesh positions. inline const Vector > &positions() const { return data_m->positions(); } /// The mesh origin. inline const Vector &origin() const { return data_m->origin(); } /// The cell containing a particular point. inline Loc cellContaining(const Vector &point) const { /// FIXME Loc loc((0, Pooma::NoInit())); // Avoid a g++ parse error. for (int i = 0; i < Dim; i++) { const T *start = &positions()(i)(0); const T *finish = start + physicalDomain()[i].length(); const T *p = std::lower_bound(start, finish, point(i)); #if POOMA_BOUNDS_CHECK PInsist(p != finish, "Rectilinear::cellContaining(): point is outside mesh."); #endif // The lower_bound function returns the first element that is not // less than the point we're searching for. int j = static_cast(std::distance(start, p)); if (*p == point(i)) loc[i] = j; else loc[i] = j-1; } return loc; } /// The lower-left vertex associated with a given cell location. inline Vector vertexPosition(const Loc &loc) const { Vector point; for (int i = 0; i < Dim; i++) point(i) = positions()(i)(loc[i]); return point; } //@} //--------------------------------------------------------------------------- /// Support for the positions() function. We need to provide a functor for /// use with IndexFunction-engine. We also need to export the /// PositionsEngineTag_t typedef and the positionsFunctor() member function, /// which computes the positions using the centering point positions. /// The indices passed in refer to cells. class PositionsFunctor { public: /// Need to be able to default construct since we fill in the details /// after the fact. // WARNING! For Arrays to be initialized (copy constructed, assigned, // etc.) correctly, even in the case of uninitialized targets // we need to copy the engines explicitly rather than rely // on the compiler generating correct copy constructors and // assignment operators. // FIXME! Technically we either can dump the copy constructor or the // assignment operator. PositionsFunctor() { } PositionsFunctor(const RectilinearMesh &m, const Centering &c) : centering_m(c.position(0)) { for (int i=0; i > positions_m; Vector > spacings_m; Centering::Position centering_m; }; typedef IndexFunction PositionsEngineTag_t; void initializePositions( Engine &e, const Centering &c) const { e.setFunctor(PositionsFunctor(*this, c)); } //--------------------------------------------------------------------------- /// Support for the outwardNormals() and coordinateNormals() functions. /// We also need to export the NormalsEngineTag_t typedef and the /// initializeNormals() member function, which sets the appropriate constant /// value (since the normals exactly align with the coordinate axes). /// The boolean value passed is true if we are asking for outward normals, /// as opposed to coordinate normals. The indices passed in refer to cells. typedef ConstantFunction NormalsEngineTag_t; void initializeNormals( Engine &e, const Centering &c, bool outward = true) const { // Check some pre-conditions. We need there to be a single centering // point and it must be face-centered. PAssert(c.size() == 1); PAssert(c.centeringType() == FaceType); // Generate the normals. The coordinate normals are computed from // 1 - orientation. Then, if we are on the near face, indicated by // position == 0.0, we need to multiply by -1.0 if we are doing // outward normals. VectorType_t normal; for (int i = 0; i < Dim; i++) { normal(i) = static_cast(1 - c.orientation(0)[i].first()); if (outward && c.position(0)(i) == 0.0) normal(i) *= static_cast(-1); } e.setConstant(normal); } /// General "volume" functor: works for edges, faces and cells. class GeneralVolumesFunctor { public: /// Need to be able to default construct since we fill in the details /// after the fact. GeneralVolumesFunctor() { } GeneralVolumesFunctor(const RectilinearMesh &m, const Centering &c) : orientation_m(c.orientation(0)) { for (int i=0; i(1); if (orientation_m[0].first() != 0) volume *= spacings_m(0).read(i0); if (orientation_m[1].first() != 0) volume *= spacings_m(1).read(i1); if (orientation_m[2].first() != 0) volume *= spacings_m(2).read(i2); return volume; } private: Vector > spacings_m; Centering::Orientation orientation_m; }; //--------------------------------------------------------------------------- /// Support for the cellVolumes() function. We also need to export the /// CellVolumesEngineTag_t typedef and the initializeCellVolumes() member /// function, which sets the appropriate constant value for the volume. /// The indices passed in refer to cells. typedef IndexFunction CellVolumesEngineTag_t; void initializeCellVolumes( Engine &e, const Centering &c) const { // Check some pre-conditions. We need there to be a single centering // point and it must be cell-centered. PAssert(c.size() == 1); PAssert(c.centeringType() == CellType); // Use the general functor to do the job. e.setFunctor(GeneralVolumesFunctor(*this, c)); } //--------------------------------------------------------------------------- /// Support for the faceAreas() function. We also need to export the /// FaceAreasEngineTag_t typedef and the initializeFaceAreas() member /// function, which sets the appropriate constant face area value. /// The indices passed in refer to cells. typedef IndexFunction FaceAreasEngineTag_t; void initializeFaceAreas( Engine &e, const Centering &c) const { // Check some pre-conditions. We need there to be a single centering // point and it must be face-centered. PAssert(c.size() == 1); PAssert(c.centeringType() == FaceType); // Use the general functor to do the job. e.setFunctor(GeneralVolumesFunctor(*this, c)); } //--------------------------------------------------------------------------- /// Support for the edgeLengths() function. We also need to export the /// EdgeLengthsEngineTag_t typedef and the initializeEdgeLengths() member /// function, which sets the appropriate constant edge length value. /// The indices passed in refer to cells. typedef IndexFunction EdgeLengthsEngineTag_t; void initializeEdgeLengths( Engine &e, const Centering &c) const { // Check some pre-conditions. We need there to be a single centering // point and it must be edge-centered. PAssert(c.size() == 1); PAssert(c.centeringType() == EdgeType); // Use the general functor to do the job. e.setFunctor(GeneralVolumesFunctor(*this, c)); } private: /// Our data, stored as a ref-counted pointer to simplify memory management. RefCountedPtr > data_m; }; #endif // POOMA_FIELD_MESH_RECTILINEARMESH_H // ACL:rcsinfo // ---------------------------------------------------------------------- // $RCSfile: RectilinearMesh.h,v $ $Author: oldham $ // $Revision: 1.4 $ $Date: 2001/12/11 20:43:30 $ // ---------------------------------------------------------------------- // ACL:rcsinfo