From oldham at codesourcery.com Thu Aug 2 22:51:39 2001 From: oldham at codesourcery.com (Jeffrey Oldham) Date: Thu, 2 Aug 2001 15:51:39 -0700 Subject: [newfield_revision] Nearest Neighbors, Reduction Functions Message-ID: <20010802155139.A22291@codesourcery.com> The attached patch revises FieldOffset, eliminating the Type template parameter and adding miscellaneous functionality such as operator<< and operator==. The eliminated Type parameter indicated whether the underlying field had one subfield or multiple subfields, which are accessed differently. Stephen, Scott, and I all repeatedly tripped over the template parameter, which propagated itself through much of the code changes. Instead, of a compile-time parameter, we use a run-time computation to decide how to access a field. The associated test program is also revised. More importantly, this patch also adds FieldOffsetList, nearestNeighbors(), NearestNeighbors, associated reduction functions, and associated test programs FieldReductions and NearestNeighbors. A FieldOffsetList is a list of FieldOffsets. Given input and output centerings, nearestNeighbors() returns a std::vector of FieldOffsetLists. Each FieldOffsetList specifies the locations of the input field values closest (using the Manhattan norm) to the corresponding output field value. Many of the Caramana hydrodynamics and Chevron kernel operations use nearest neighbors since physics operates locally. FieldReductions, taking an input field, a FieldOffsetList, and an output cell location, apply a reduction to the specified input cells. All these changes were added to the newfield_revision branch, which is being developed by Scott Haney, Jeffrey D. Oldham, and Stephen Smith. The branch code is not guaranteed to compile, be correct, or stable. 2001-08-02 Jeffrey D. Oldham * FieldCentering.cmpl.cpp (CanonicalCentering::CanonicalCentering): Fix continuity label for canonical discontinuous vertex centering. * Field.h: Include NearestNeighbors.h (View2<..., FieldOffset<...> >): New class merging previous FieldOffset<...,[01]> code. (View2<..., FieldOffset<...,1> >): Removed. (View2<..., FieldOffset<...,0> >): Removed. * FieldOffset.h: (FieldOffset<...>): New class merging previous FieldOffset<...,[01]> code. (FieldOffset<...,1>): Removed. (FieldOffset<...,0>): Removed. (FieldOffset::FieldOffset()): New function. (FieldOffset::setSubFieldNumber): Likewise. (FieldOffset::modifyCellOffset): Likewise. (operator<<(...,FieldOffset)): Likewise. (operator==(FieldOffset,...)): Likewise. (operator!=(FieldOffset,...)): Likewise. (FieldOffsetList): New class. (operator<<(...,FieldOffsetList)): New function. (accumulate): Likewise. (sum): Likewise. (average): Likewise. (minimum): Likewise. (maximum): Likewise. * NearestNeighbors.h (NearestNeighborClass): New class. (nearestNeighbors): New function. * objfile.mk ($(UNIQUE)_OBJS): Add FieldOffset.cmpl.o. * tests/FieldOffset.cpp: Removed second template parameter from all uses. * tests/FieldReductions.cpp: New testing file. * tests/NearestNeighbors.cpp: Likewise. * tests/makefile: Add support for FieldReductions and NearestNeighbors. Remove support for ScalarAdvection and ScalarAdvectionXB. Tested on sequential Linux using gcc3.0 by building Pooma library and NewField executables also tested using KCC by Stephen Smith Applied to newfield_revision development branch Approved by Stephen Smith Thanks, Jeffrey D. Oldham oldham at codesourcery.com -------------- next part -------------- Index: Field.h =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/Field.h,v retrieving revision 1.15.2.3 diff -c -p -r1.15.2.3 Field.h *** Field.h 2001/07/24 19:50:44 1.15.2.3 --- Field.h 2001/08/02 19:48:50 *************** *** 68,73 **** --- 68,74 ---- #include "NewField/FieldCreateLeaf.h" #include "NewField/FieldCentering.h" #include "NewField/FieldOffset.h" + #include "NewField/NearestNeighbors.h" #include "NewField/PrintField.h" *************** struct View1 and ! // FIXME: FieldOffset. //----------------------------------------------------------------------------- // AltView1 avoids an instantiation problem that arises when two --- 578,584 ---- }; ! // FIXME: Add specializations for FieldOffset. //----------------------------------------------------------------------------- // AltView1 avoids an instantiation problem that arises when two *************** struct View2, Loc > specialization for // indexing a field with a FieldOffset and a Loc. //----------------------------------------------------------------------------- template struct View2, ! FieldOffset, Loc > { // Convenience typedef for the thing we're taking a view of. --- 740,752 ---- //----------------------------------------------------------------------------- ! // View2, Loc > specialization for // indexing a field with a FieldOffset and a Loc. //----------------------------------------------------------------------------- template struct View2, ! FieldOffset, Loc > { // Convenience typedef for the thing we're taking a view of. *************** struct View2 &fo, const Loc &loc) { CTAssert(dimensions == Dim); - PAssert(f.numSubFields() > 0); #if POOMA_BOUNDS_CHECK ! PInsist(contains(f.totalDomain(), loc + fo.cellOffset()), ! "Field view bounds error."); ! #endif ! return f[fo.subFieldNumber()].engine()(loc + fo.cellOffset()); ! } ! ! inline static ! ReadType_t makeRead(const Subject_t &f, ! const FieldOffset &fo, ! const Loc &loc) ! { ! PAssert(f.numSubFields() > 0); ! ! #if POOMA_BOUNDS_CHECK ! PInsist(contains(f.totalDomain(), loc + fo.cellOffset()), ! "Field view bounds error."); #endif ! return f[fo.subFieldNumber()].engine().read(loc + fo.cellOffset()); ! } ! }; ! ! ! //----------------------------------------------------------------------------- ! // View2, Loc > specialization for ! // indexing a field with a FieldOffset and a Loc. ! //----------------------------------------------------------------------------- ! ! template ! struct View2, ! FieldOffset, ! Loc > ! { ! // Convenience typedef for the thing we're taking a view of. ! ! typedef Field Subject_t; ! ! // The field's dimension (i.e., the number of indices required to select a point). ! ! enum { dimensions = Subject_t::dimensions }; ! ! // The return types. ! ! typedef typename Subject_t::Element_t ReadType_t; ! typedef typename Subject_t::ElementRef_t Type_t; ! ! // The functions that do the indexing. ! ! inline static ! Type_t make(const Subject_t &f, ! const FieldOffset &fo, ! const Loc &loc) ! { ! CTAssert(dimensions == Dim); ! #if POOMA_BOUNDS_CHECK ! PInsist(contains(f.totalDomain(), loc + fo.cellOffset()), ! "Field view bounds error."); #endif ! return f.engine()(loc + fo.cellOffset()); } inline static ReadType_t makeRead(const Subject_t &f, ! const FieldOffset &fo, const Loc &loc) { #if POOMA_BOUNDS_CHECK ! PInsist(contains(f.totalDomain(), loc + fo.cellOffset()), ! "Field view bounds error."); #endif ! return f.engine().read(loc + fo.cellOffset()); } }; --- 766,813 ---- inline static Type_t make(const Subject_t &f, ! const FieldOffset &fo, const Loc &loc) { CTAssert(dimensions == Dim); + if (f.numSubFields() > 0) { #if POOMA_BOUNDS_CHECK ! PInsist(contains(f[fo.subFieldNumber()].totalDomain(), ! loc + fo.cellOffset()), ! "Field view bounds error."); #endif ! return f[fo.subFieldNumber()].engine()(loc + fo.cellOffset()); ! } ! else { #if POOMA_BOUNDS_CHECK ! PInsist(contains(f.totalDomain(), loc + fo.cellOffset()), ! "Field view bounds error."); ! return f.engine()(loc + fo.cellOffset()); #endif ! } } inline static ReadType_t makeRead(const Subject_t &f, ! const FieldOffset &fo, const Loc &loc) { + if (f.numSubFields() > 0) { #if POOMA_BOUNDS_CHECK ! PInsist(contains(f[fo.subFieldNumber()].totalDomain(), ! loc + fo.cellOffset()), ! "Field view bounds error."); ! #endif ! return f[fo.subFieldNumber()].engine().read(loc + fo.cellOffset()); ! } ! else { ! #if POOMA_BOUNDS_CHECK ! PInsist(contains(f.totalDomain(), loc + fo.cellOffset()), ! "Field view bounds error."); #endif ! return f.engine().read(loc + fo.cellOffset()); ! } } }; Index: FieldCentering.cmpl.cpp =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/Attic/FieldCentering.cmpl.cpp,v retrieving revision 1.1.2.4 diff -c -p -r1.1.2.4 FieldCentering.cmpl.cpp *** FieldCentering.cmpl.cpp 2001/07/17 23:16:10 1.1.2.4 --- FieldCentering.cmpl.cpp 2001/08/02 19:48:50 *************** CanonicalCentering::CanonicalCenter *** 285,290 **** --- 285,295 ---- centering.addValue(orientation, position); centering_table_m[VertexType][Continuous][AllDim%(1<(VertexType, Discontinuous); + orientation = 0; + position = 0.0; + centering.addValue(orientation, position); position(0) = 1.0; centering.addValue(orientation, position); if (Dim > 1) { position(1) = 1.0; centering.addValue(orientation, position); Index: FieldOffset.h =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/Attic/FieldOffset.h,v retrieving revision 1.1.2.1 diff -c -p -r1.1.2.1 FieldOffset.h *** FieldOffset.h 2001/07/24 19:50:44 1.1.2.1 --- FieldOffset.h 2001/08/02 19:48:51 *************** *** 29,34 **** --- 29,41 ---- //----------------------------------------------------------------------------- // Classes: // FieldOffset + // FieldOffsetList + // Functions: + // accumulate + // sum + // average + // minimum + // maximum //----------------------------------------------------------------------------- #ifndef POOMA_NEWFIELD_OFFSET_H *************** *** 39,44 **** --- 46,55 ---- // // FieldOffset // - specifies a relative cell offset and subfield number + // FieldOffsetList + // - is a sequence of FieldOffset's + // FieldOffsetList reductions + // - computations using the entries in a FieldOffsetList //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- *************** *** 46,73 **** //----------------------------------------------------------------------------- #include "Domain/Loc.h" //----------------------------------------------------------------------------- // Forward declarations: //----------------------------------------------------------------------------- ! template class FieldOffset; //----------------------------------------------------------------------------- ! // Full Description of FieldOffset: // // Given a field f, a Loc loc, and a field offset (offset,num), a // field value can be obtained. Since each value specified by the // field's centering is stored in a separate subfield, the notation ! // f[num](loc + offset) yields the value. // ! // Accessing values for fields with exactly one value per cell differs ! // from accessing fields with multiple subfields. If a field has ! // exactly one value per cell, use FieldOffset, which does not ! // store a subfield number. If a field has multiple subfields, use ! // FieldOffset, which stores a subfield number. // //----------------------------------------------------------------------------- --- 57,134 ---- //----------------------------------------------------------------------------- #include "Domain/Loc.h" + #include + #include + #include + #include + #include + //----------------------------------------------------------------------------- // Forward declarations: //----------------------------------------------------------------------------- ! template class FieldOffset; + template + class FieldOffsetList; + //----------------------------------------------------------------------------- ! // Full Description of FieldOffset: // // Given a field f, a Loc loc, and a field offset (offset,num), a // field value can be obtained. Since each value specified by the // field's centering is stored in a separate subfield, the notation ! // ! //----------------------------------------------------------------------------- ! ! ! //----------------------------------------------------------------------------- ! // Full Description of FieldOffsetList: ! // ! // A set of FieldOffset's can be stored in a FieldOffsetList. The ! // list has a fixed size. The following member operations are ! // supported: ! // size_type size() const - return the number of FieldOffset's. ! // const_reference operator[](size_type n) - return the nth ! // FieldOffset. ! // ! //----------------------------------------------------------------------------- ! ! ! //----------------------------------------------------------------------------- ! // Full Description of FieldOffsetList Reductions: ! // ! // FIXME: What do we do for data-parallel statements? ! // ! // Many computations using `FieldOffsetList's perform similar ! // computations. The provided reduction functions support these ! // computations. All take a field, a FieldOffsetList, and a Loc. The ! // Loc specifies a cell within the given field. Together with a ! // FieldOffsetList and a field, a field value is specified. The ! // reduction function combines all the specified field values ! // corresponding to `FieldOffset's in the list. The list must not be ! // empty. ! // ! // accumulate: Sequentially applies the given binary function to all ! // field offsets in the list. ! // sum: Adds the values indicated by the field offset list. ! // average: Averages the values indicated by the field offset ! // list. Note the division is computed using the element ! // type, e.g., integral or floating point division. ! // minimum: Returns the smallest of the indicated values. ! // maximum: Returns the largest of the indicated values. // ! //----------------------------------------------------------------------------- ! ! //----------------------------------------------------------------------------- ! // Full Description of findFieldOffsetList(): // + // Given an input centering and an output centering, + // findFieldOffsetList() returns a std::vector >. + // Each vector entry corresponds to one output value in the output centering. + // //----------------------------------------------------------------------------- *************** class FieldOffset; *** 76,89 **** //----------------------------------------------------------------------------- template ! class FieldOffset { public: //--------------------------------------------------------------------------- // User-callable constructors. These ctors are meant to be called by users. FieldOffset(const Loc &loc, const int subFieldNumber = 0) ! : cell_offset_m(loc), subfield_number_m (subFieldNumber) { #if POOMA_BOUNDS_CHECK PInsist(subfield_number_m >= 0, "Erroneous FieldOffset subfield number."); --- 137,150 ---- //----------------------------------------------------------------------------- template ! class FieldOffset { public: //--------------------------------------------------------------------------- // User-callable constructors. These ctors are meant to be called by users. FieldOffset(const Loc &loc, const int subFieldNumber = 0) ! : cell_offset_m(loc), subfield_number_m(subFieldNumber) { #if POOMA_BOUNDS_CHECK PInsist(subfield_number_m >= 0, "Erroneous FieldOffset subfield number."); *************** public: *** 92,97 **** --- 153,177 ---- } //--------------------------------------------------------------------------- + // Internal POOMA constructor. These operations are used internally + // by POOMA. They are not really meant to be called by users. + + FieldOffset() + : cell_offset_m(Loc()), subfield_number_m(0) + {} + + inline void setSubFieldNumber(int subFieldNumber) + { + subfield_number_m = subFieldNumber; + return; + } + + inline Loc &modifyCellOffset() + { + return cell_offset_m; + } + + //--------------------------------------------------------------------------- // Accessors. inline const Loc &cellOffset() const *************** private: *** 114,153 **** }; template ! class FieldOffset { public: ! //--------------------------------------------------------------------------- ! // User-callable constructors. These ctors are meant to be called by users. ! FieldOffset(const Loc &loc, const int subFieldNumber = 0) ! : cell_offset_m(loc), subfield_number_m (-1) ! { } //--------------------------------------------------------------------------- ! // Accessors. ! inline const Loc &cellOffset() const ! { ! return cell_offset_m; ! } private: ! // The cell offset. ! Loc cell_offset_m; ! // The subfield number, if appropriate. ! int subfield_number_m; }; #endif // POOMA_NEWFIELD_OFFSET_H // ACL:rcsinfo // ---------------------------------------------------------------------- ! // $RCSfile: FieldOffset.h,v $ $Author: oldham $ ! // $Revision: 1.1.2.1 $ $Date: 2001/07/24 19:50:44 $ // ---------------------------------------------------------------------- // ACL:rcsinfo --- 194,438 ---- }; + //----------------------------------------------------------------------------- + // Overload the << operator to print a FieldOffset to a stream. + //----------------------------------------------------------------------------- + + template + std::ostream &operator<<(std::ostream &o, + const FieldOffset &fieldOffset) + { + return o << "FieldOffset: (" << fieldOffset.cellOffset() + << ", " << fieldOffset.subFieldNumber() << ")"; + } + + //----------------------------------------------------------------------------- + // Define equality and inequality operators for FieldOffsets/ + //----------------------------------------------------------------------------- + + template + inline bool + operator==(const FieldOffset &fieldOffset1, + const FieldOffset &fieldOffset2) + { + return + fieldOffset1.cellOffset() == fieldOffset2.cellOffset() && + fieldOffset1.subFieldNumber() == fieldOffset2.subFieldNumber(); + } + + template + inline bool + operator!=(const FieldOffset &fieldOffset1, + const FieldOffset &fieldOffset2) + { + return !(fieldOffset1 == fieldOffset2); + } + + + //----------------------------------------------------------------------------- + // FieldOffsetList. + //----------------------------------------------------------------------------- + template ! class FieldOffsetList ! { public: ! // Exported typedefs. ! ! typedef size_t size_type; ! typedef FieldOffset& reference; ! typedef const FieldOffset& const_reference; ! // Return the number of FieldOffset's. ! ! size_type size() const ! { ! return v_m.size(); ! } ! ! // Return a FieldOffset. ! ! const_reference operator[](const size_type n) const ! { ! #if POOMA_BOUNDS_CHECK ! PInsist(n < size(), "Erroneous FieldOffsetList index."); ! #endif ! return v_m[n]; ! } //--------------------------------------------------------------------------- ! // Internal POOMA operators. These operations are used internally ! // by POOMA. They are not really meant to be called by users. ! // Create an empty list. This is used for arrays or std::vectors. ! ! FieldOffsetList() {} ! ! // Create a list that can hold the specified number of entries. ! ! FieldOffsetList(const size_type sz) ! { ! #if POOMA_BOUNDS_CHECK ! PInsist(sz > 0, "Erroneous FieldOffsetList size."); ! #endif ! v_m.reserve(sz); ! } + // Copy a vector's entries to this FieldOffsetList. + + FieldOffsetList &operator=(const std::vector > &v) + { + v_m.resize(v.size()); + std::copy(v.begin(), v.end(), v_m.begin()); + return *this; + } + + // Permit adding the specified entry. + + reference operator[](const size_type n) + { + #if POOMA_BOUNDS_CHECK + PInsist(n < size(), "Erroneous FieldOffsetList index."); + #endif + return v_m[n]; + } + private: ! std::vector > v_m; ! }; ! //----------------------------------------------------------------------------- ! // Overload the << operator to print a FieldOffsetList to a stream. ! //----------------------------------------------------------------------------- ! ! template ! std::ostream &operator<<(std::ostream &o, ! const FieldOffsetList &fieldOffsetList) ! { ! o << "FieldOffsetList:\n"; ! for (int index = 0; index < fieldOffsetList.size(); ++index) ! o << fieldOffsetList[index] << std::endl; ! return o; ! } ! ! ! //----------------------------------------------------------------------------- ! // FieldOffsetList Reductions. ! //----------------------------------------------------------------------------- ! ! // Accumulate all the specified field locations using the supplied STL ! // binary function. Then, for each FieldOffset fo in the list, result ! // = binary_op(result, fv), where fv is the corresponding field value. ! ! // FIXME: Add data-parallel code. ! ! template ! inline ! typename Field::T_t ! accumulate(BinaryFunction binary_op, ! const Field& field, ! const FieldOffsetList &lst, ! const Loc &loc) ! { ! typedef typename Field::T_t T_t; ! typedef typename FieldOffsetList::size_type size_type; ! CTAssert((Field::dimensions == Dim)); ! ! const size_type lstLength = lst.size(); ! PInsist(lstLength > 0, "accumulate must be given a nonempty list."); ! T_t init = field(lst[0], loc); ! for (size_type i = 1; i < lstLength ; ++i) ! init = binary_op(init, field(lst[i], loc)); ! return init; ! } ! ! ! // Sum all the values at the field locations. ! ! template ! inline ! typename Field::T_t ! sum(const Field& field, ! const FieldOffsetList &lst, ! const Loc &loc) ! { ! typedef typename Field::T_t T_t; ! CTAssert((Field::dimensions == Dim)); ! return accumulate(std::plus(), field, lst, loc); ! } ! ! ! // Average all the values at the field locations. Note the return ! // value has the same type as the field types so integer division may ! // be used. ! ! template ! inline ! typename Field::T_t ! average(const Field& field, ! const FieldOffsetList &lst, ! const Loc &loc) ! { ! typedef typename Field::T_t T_t; ! CTAssert((Field::dimensions == Dim)); ! return sum(field, lst, loc) / lst.size(); ! } ! ! ! // Return the minimum value of the field locations. ! ! template ! struct fomin : public std::binary_function ! { ! T operator()(const T &op1, const T &op2) const { ! return std::min(op1, op2); ! } ! }; ! ! template ! inline ! typename Field::T_t ! minimum(const Field& field, ! const FieldOffsetList &lst, ! const Loc &loc) ! { ! typedef typename Field::T_t T_t; ! CTAssert((Field::dimensions == Dim)); ! return accumulate(fomin(), field, lst, loc); ! } ! ! ! // Return the maximum value of the field locations. ! ! template ! struct fomax : public std::binary_function ! { ! T operator()(const T &op1, const T &op2) const { ! return std::max(op1, op2); ! } }; + template + inline + typename Field::T_t + maximum(const Field& field, + const FieldOffsetList &lst, + const Loc &loc) + { + typedef typename Field::T_t T_t; + CTAssert((Field::dimensions == Dim)); + return accumulate(fomax(), field, lst, loc); + } + #endif // POOMA_NEWFIELD_OFFSET_H // ACL:rcsinfo // ---------------------------------------------------------------------- ! // $RCSfile: FieldCentering.h,v $ $Author: oldham $ ! // $Revision: 1.1.2.1 $ $Date: 2001/07/16 20:44:59 $ // ---------------------------------------------------------------------- // ACL:rcsinfo Index: NearestNeighbors.h =================================================================== RCS file: NearestNeighbors.h diff -N NearestNeighbors.h *** /dev/null Tue May 5 14:32:27 1998 --- NearestNeighbors.h Thu Aug 2 13:48:51 2001 *************** *** 0 **** --- 1,401 ---- + // -*- 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 + + //----------------------------------------------------------------------------- + // Function: + // nearestNeighbors + // Class: + // NearestNeighborClass + //----------------------------------------------------------------------------- + + #ifndef POOMA_NEWFIELD_NEAREST_NEIGHBORS_H + #define POOMA_NEWFIELD_NEAREST_NEIGHBORS_H + + //----------------------------------------------------------------------------- + // Overview: + // + // nearestNeighbors + // - yields FieldOffsetLists corresponding to the specified centerings + // NearestNeighborClass + // - the class performing the work + //----------------------------------------------------------------------------- + + //----------------------------------------------------------------------------- + // Includes: + //----------------------------------------------------------------------------- + + #include "Domain/Loc.h" + #include "NewField/FieldCentering.h" + #include + #include + #include + #include + #include + + + //----------------------------------------------------------------------------- + // Forward declarations: + //----------------------------------------------------------------------------- + + //----------------------------------------------------------------------------- + // Full Description of nearestNeighbors(): + // + // Given input and output centerings, this function computes the + // "first shell" of nearest neighbors for each output value. That is, + // for each output value, it computes the FieldOffsetList containing + // the input values that are closest, with respect to the Manhattan + // norm (l_1 norm). The FieldOffsetLists are stored in a std::vector + // in the same order as the output values occur in the output + // centering. + // + // If only values within the corresponding input cell are desired, + // specify a third parameter. + // + // + // Full Description of NearestNeighborClass: + // + // This class implements the work of nearestNeighbors(). + // + //----------------------------------------------------------------------------- + + //---------------------------------------------------------------------- + // NearestNeighborClass. + //---------------------------------------------------------------------- + + template + class NearestNeighborClass { + public: + + typedef FieldOffset FieldOffset_t; + typedef FieldOffsetList FieldOffsetList_t; + typedef std::vector FieldOffset_vt; + typedef std::vector Answer_t; + typedef Centering Center; + typedef Center::Positions Positions; + typedef Center::Position Position; + + // To compute the set of input values, we maintain a set of input + // values and their differences from the output value. In fact, we + // maintain the input value index and its difference. + + typedef std::pair MinimumPair; + typedef std::vector MinimumSet; + + + NearestNeighborClass(const Center &inputCentering, + const Center &outputCentering) + : inputCentering_m(inputCentering), + outputCentering_m(outputCentering) + { + PInsist(inputCentering_m.positions().size() > 0, + "The input centering must be non-empty."); + } + + inline + Answer_t operator()() + { + Answer_t answer; + answer.resize(outputCentering_m.size()); + Positions inputPositions = inputCentering_m.positions(); + Positions outputPositions = outputCentering_m.positions(); + Position positionDifference; + double minimumDistance; + + // Determine nearest neighbors for each output value. + + for (Answer_t::size_type outputIndex = 0; + outputIndex < outputCentering_m.size(); + ++outputIndex) + { + // Compute all input values in the first shell. + + MinimumSet minimumSet; // all input values in first shell + const Position outputValue = outputPositions[outputIndex]; + typename Positions::size_type inputIndex = 0; + + // Use the first input value to start computing the minimum. + + positionDifference = inputPositions[inputIndex] - outputValue; + minimumDistance = + (IntraCellOnly ? + manhattanDistance(positionDifference) : + manhattanDistance(positionDifference)); + minimumSet.push_back(std::make_pair(inputIndex, positionDifference)); + + // Compute the minimum over the rest of the input values. + + for (++inputIndex; + inputIndex < inputPositions.size(); + ++inputIndex) { + positionDifference = inputPositions[inputIndex] - outputValue; + const double distance = + (IntraCellOnly ? + manhattanDistance(positionDifference) : + manhattanDistance(positionDifference)); + if (distance < minimumDistance + epsilon) { + if (distance < minimumDistance) { + minimumSet.clear(); + minimumDistance = distance; + } + minimumSet.push_back(std::make_pair(inputIndex, + positionDifference)); + } + } + + + // Convert the minimum set to a set of FieldOffsets. + // minimumSet has all the minimum distance locations. + + FieldOffset_vt answerHolder; + if (IntraCellOnly) { + for (MinimumSet::size_type minIndex = 0; + minIndex < minimumSet.size(); + ++minIndex) + answerHolder.push_back(FieldOffset_t(Loc(0), + minimumSet[minIndex].first)); + } + else { + FieldOffset_vt partialAnswer; + for (MinimumSet::size_type minIndex = 0; + minIndex < minimumSet.size(); + ++minIndex) + { + // Compute the cell offsets, appending to the set of answers. + + partialAnswer = computeCellOffsets(minimumSet[minIndex].first, + minimumSet[minIndex].second); + answerHolder.insert(answerHolder.end(), + partialAnswer.begin(), partialAnswer.end()); + } + + // Remove all duplicates from the answer set. + + std::sort(answerHolder.begin(), answerHolder.end(), + CompareFieldOffset()); + answerHolder.erase(std::unique(answerHolder.begin(), + answerHolder.end(), + EqualFieldOffset()), + answerHolder.end()); + } + + // Store the answer. + + answer[outputIndex] = answerHolder; + } + + return answer; + } + + private: + + // Given a difference between two positions in logical coordinate + // space, return the Manhattan norm distance taking into account + // that input values are repeated in every grid cell. + + struct ManhattanGrid : public std::binary_function + { + double operator()(const double totalSoFar, double coordinate) const { + const double absCoordinate = std::abs(coordinate); + return totalSoFar + std::min(absCoordinate, 1-absCoordinate); + } + }; + + // Given a difference between two positions in logical coordinate + // space, return the Manhattan norm distance not taking into account + // that input values are repeated in every grid cell. + + struct Manhattan : public std::binary_function + { + double operator()(const double totalSoFar, double coordinate) const { + return totalSoFar + std::abs(coordinate); + } + }; + + template + inline static + double manhattanDistance(const Position &difference) + { + double answer; + for (int coordinate = Dim-1; coordinate >= 0; --coordinate) + answer = Distance()(answer, difference(coordinate)); + return answer; + } + + // Given an input value in the first shell and its position + // difference from the given output value, return a vector of + // FieldOffsets of input values in the first shell, taking into + // account the repetition of input values throughout the grid. This + // is non-trivial because + // 1) input values are replicated and multiple values may + // be the same distance away + // 2) the closest input location may be in a different cell + + inline static const FieldOffset_vt + computeCellOffsets(const int inputValueIndex, const Position &difference) + { + // Start with one empty tuple. + + FieldOffset_vt answer(1); + int numTuples = 1; + + // Store the cell offsets for input values. + + int cellOffsetCoordinates[2]; // For our problem, there can + // be at most two cell offsets for + // each dimension. + int numOffsets; // number of cell offsets in + // cellOffsetCoordinates + + for (int dimension = 0; dimension < Dim; ++dimension) { + numOffsets = + convertDifferenceToCellOffsets(difference(dimension), + cellOffsetCoordinates); + PInsist(numOffsets >= 1 && numOffsets <= 2, + "Incorrect number of cell offsets"); + + if (numOffsets == 2) + // Duplicate the tuples. + answer.insert(answer.end(), answer.begin(), answer.end()); + + for (int coc = 0; coc < numOffsets; ++coc) + for (int tuple = 0; tuple < numTuples; ++tuple) + answer[numTuples * coc + tuple].modifyCellOffset()[dimension] = + cellOffsetCoordinates[coc]; + + numTuples *= numOffsets; + } + + // Set the subField numbers. + + for (int i = numTuples-1; i >= 0; --i) + answer[i].setSubFieldNumber(inputValueIndex); + + return answer; + } + + // Given one coordinate of a difference between two coordinates, + // return the corresponding cell offset(s), either one or two. + + inline static + int convertDifferenceToCellOffsets(const double difference, + int cellOffsetCoordinate[]) + { + if (difference < -0.5 - epsilon) { + cellOffsetCoordinate[0] = +1; + return 1; + } + else if (std::abs(difference + 0.5) < epsilon) { + cellOffsetCoordinate[0] = +1; + cellOffsetCoordinate[1] = 0; + return 2; + } + else if (difference <= 0.5 - epsilon) { + cellOffsetCoordinate[0] = 0; + return 1; + } + else if (std::abs(difference - 0.5) < epsilon) { + cellOffsetCoordinate[0] = 0; + cellOffsetCoordinate[1] = -1; + return 2; + } + else if (difference < 1.0 + epsilon) { + cellOffsetCoordinate[0] = -1; + return 1; + } + else + PInsist(0, "Out of range difference"); + } + + // Specify a partial order for FieldOffsets to use when removing + // duplicates. + + struct CompareFieldOffset : + public std::binary_function { + bool operator()(const FieldOffset_t &op1, const FieldOffset_t &op2) { + return (op1.cellOffset() < op2.cellOffset()) || + (op1.cellOffset() == op2.cellOffset() && + op1.subFieldNumber() < op2.subFieldNumber()); + } + }; + + // Specify an equality operator for FieldOffsets to use when removing + // duplicates. + + struct EqualFieldOffset : + public std::binary_function { + bool operator()(const FieldOffset_t &op1, const FieldOffset_t &op2) { + return op1.cellOffset() == op2.cellOffset() && + op1.subFieldNumber() == op2.subFieldNumber(); + } + }; + + const Center &inputCentering_m; + const Center &outputCentering_m; + + // Use epsilon when comparing floating-point numbers, which cannot + // be represented precisely. + + static const double epsilon; + + }; + + + template + const double + NearestNeighborClass::epsilon = 1.0e-08; + + + //----------------------------------------------------------------------------- + // nearestNeighbors. + //----------------------------------------------------------------------------- + + template + std::vector > + nearestNeighbors(const Centering &inputCentering, + const Centering &outputCentering) + { + return NearestNeighborClass(inputCentering, outputCentering)(); + } + + template + std::vector > + nearestNeighbors(const Centering &inputCentering, + const Centering &outputCentering, + const bool) + { + return NearestNeighborClass(inputCentering, outputCentering)(); + } + + #endif // POOMA_NEWFIELD_NEAREST_NEIGHBORS_H + + // ACL:rcsinfo + // ---------------------------------------------------------------------- + // $RCSfile: NearestNeighbors.h,v $ $Author: oldham $ + // $Revision: 1.1.2.1 $ $Date: 2001/07/16 20:44:59 $ + // ---------------------------------------------------------------------- + // ACL:rcsinfo Index: tests/FieldOffset.cpp =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/tests/Attic/FieldOffset.cpp,v retrieving revision 1.1.2.1 diff -c -p -r1.1.2.1 FieldOffset.cpp *** tests/FieldOffset.cpp 2001/07/24 19:50:45 1.1.2.1 --- tests/FieldOffset.cpp 2001/08/02 19:48:51 *************** int main(int argc, char *argv[]) *** 56,115 **** // Test a field with subfields. tester.check("f[0](0,0)", ! f(FieldOffset(Loc(0), 0), Loc(0)), -1.0, 1.0e-8); tester.check("f[0](0,0)", ! f(FieldOffset(Loc(2,1), 0), Loc(-2,-1)), -1.0, 1.0e-8); tester.check("f[0](2,1)", ! f(FieldOffset(Loc(2,1), 0), Loc(0)), -1.0, 1.0e-8); tester.check("f[1](0,0)", ! f(FieldOffset(Loc(0), 1), Loc(0)), -2.0, 1.0e-8); tester.check("f[1](1,2)", ! f(FieldOffset(Loc(1,2), 1), Loc(0)), -2.0, 1.0e-8); ! f(FieldOffset(Loc(3,2), 0), Loc(-1,-1)) = 1.3; ! f(FieldOffset(Loc(3,2), 1), Loc(-1,-1)) = 10.3; tester.check("f[0](2,1)", ! f(FieldOffset(Loc(2,1), 0), Loc(0)), 1.3, 1.0e-08); tester.check("f[1](2,1)", ! f(FieldOffset(Loc(2,1), 1), Loc(0)), 10.3, 1.0e-08); tester.check("f[0].read(2,1)", ! f.read(FieldOffset(Loc(2,1), 0), Loc(0)), 1.3, 1.0e-08); tester.check("f[1].read(2,1)", ! f.read(FieldOffset(Loc(2,1), 1), Loc(0)), 10.3, 1.0e-08); // Test a field with no subfields. Field_t h(canonicalCentering(CellType, Continuous, AllDim), layout, Vector(0.0), Vector(1.0, 2.0)); ! h(FieldOffset(Loc(0,0)), Loc(0,0)) = 1.3; ! h(FieldOffset(Loc(0,0)), Loc(0,1)) = 2.3; ! h(FieldOffset(Loc(0,0)), Loc(1,0)) = 2.8; ! h(FieldOffset(Loc(1,0)), Loc(0,1)) = 3.3; tester.check("h(0,0)", ! h(FieldOffset(Loc(-1,-1)), Loc(1,1)), 1.3, 1.0e-08); tester.check("h(0,1)", ! h(FieldOffset(Loc(0,1)), Loc(0,0)), 2.3, 1.0e-08); tester.check("h(1,0)", ! h(FieldOffset(Loc(0,1)), Loc(1,-1)), 2.8, 1.0e-08); tester.check("h(1,1)", ! h(FieldOffset(Loc(0,0)), Loc(1,1)), 3.3, 1.0e-08); tester.check("h.read(1,0)", ! h.read(FieldOffset(Loc(0,1)), Loc(1,-1)), 2.8, 1.0e-08); tester.check("h.read(1,1)", ! h.read(FieldOffset(Loc(0,0)), Loc(1,1)), 3.3, 1.0e-08); int ret = tester.results("FieldOffset"); --- 56,115 ---- // Test a field with subfields. tester.check("f[0](0,0)", ! f(FieldOffset(Loc(0), 0), Loc(0)), -1.0, 1.0e-8); tester.check("f[0](0,0)", ! f(FieldOffset(Loc(2,1), 0), Loc(-2,-1)), -1.0, 1.0e-8); tester.check("f[0](2,1)", ! f(FieldOffset(Loc(2,1), 0), Loc(0)), -1.0, 1.0e-8); tester.check("f[1](0,0)", ! f(FieldOffset(Loc(0), 1), Loc(0)), -2.0, 1.0e-8); tester.check("f[1](1,2)", ! f(FieldOffset(Loc(1,2), 1), Loc(0)), -2.0, 1.0e-8); ! f(FieldOffset(Loc(3,2), 0), Loc(-1,-1)) = 1.3; ! f(FieldOffset(Loc(3,2), 1), Loc(-1,-1)) = 10.3; tester.check("f[0](2,1)", ! f(FieldOffset(Loc(2,1), 0), Loc(0)), 1.3, 1.0e-08); tester.check("f[1](2,1)", ! f(FieldOffset(Loc(2,1), 1), Loc(0)), 10.3, 1.0e-08); tester.check("f[0].read(2,1)", ! f.read(FieldOffset(Loc(2,1), 0), Loc(0)), 1.3, 1.0e-08); tester.check("f[1].read(2,1)", ! f.read(FieldOffset(Loc(2,1), 1), Loc(0)), 10.3, 1.0e-08); // Test a field with no subfields. Field_t h(canonicalCentering(CellType, Continuous, AllDim), layout, Vector(0.0), Vector(1.0, 2.0)); ! h(FieldOffset(Loc(0,0)), Loc(0,0)) = 1.3; ! h(FieldOffset(Loc(0,0)), Loc(0,1)) = 2.3; ! h(FieldOffset(Loc(0,0)), Loc(1,0)) = 2.8; ! h(FieldOffset(Loc(1,0)), Loc(0,1)) = 3.3; tester.check("h(0,0)", ! h(FieldOffset(Loc(-1,-1)), Loc(1,1)), 1.3, 1.0e-08); tester.check("h(0,1)", ! h(FieldOffset(Loc(0,1)), Loc(0,0)), 2.3, 1.0e-08); tester.check("h(1,0)", ! h(FieldOffset(Loc(0,1)), Loc(1,-1)), 2.8, 1.0e-08); tester.check("h(1,1)", ! h(FieldOffset(Loc(0,0)), Loc(1,1)), 3.3, 1.0e-08); tester.check("h.read(1,0)", ! h.read(FieldOffset(Loc(0,1)), Loc(1,-1)), 2.8, 1.0e-08); tester.check("h.read(1,1)", ! h.read(FieldOffset(Loc(0,0)), Loc(1,1)), 3.3, 1.0e-08); int ret = tester.results("FieldOffset"); Index: tests/FieldReductions.cpp =================================================================== RCS file: FieldReductions.cpp diff -N FieldReductions.cpp *** /dev/null Tue May 5 14:32:27 1998 --- FieldReductions.cpp Thu Aug 2 13:48:51 2001 *************** *** 0 **** --- 1,151 ---- + // -*- 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 + //----------------------------------------------------------------------------- + // Test field reductions. + //----------------------------------------------------------------------------- + + + #include "Pooma/NewFields.h" + #include "Utilities/Tester.h" + #include + + + // Check the sum, average, minimum, and maximum functions for a + // specified position. + + template + inline bool + checkFieldPosition(const Field &f, + const FieldOffsetList &fol, + const Loc &loc, + const T sumAnswer, const T avAnswer, + const T minAnswer, const T maxAnswer, + const double tolerance) + { + return + std::abs(sum(f, fol, loc) - sumAnswer) < tolerance && + std::abs(average(f, fol, loc) - avAnswer) < tolerance && + std::abs(minimum(f, fol, loc) - minAnswer) < tolerance && + std::abs(maximum(f, fol, loc) - maxAnswer) < tolerance; + } + + + int main(int argc, char *argv[]) + { + Pooma::initialize(argc, argv); + Pooma::Tester tester(argc, argv); + + const double eps = 1.0e-08; // checking tolerance + const int Dim = 2; + std::vector > nn; + std::vector > nn3; + + Centering<2> inputCenteringTwo, outputCenteringTwo; + Centering<3> inputCenteringThree, outputCenteringThree; + + Interval physicalVertexDomain(4, 4); + DomainLayout layout(physicalVertexDomain, GuardLayers(1)); + typedef Field, double, Brick> Field_t; + + + // Test 2D Discontinuous Vertex -> Continuous Vertex. + + inputCenteringTwo = canonicalCentering<2>(VertexType, Discontinuous, AllDim); + outputCenteringTwo = canonicalCentering<2>(VertexType, Continuous, AllDim); + nn = nearestNeighbors(inputCenteringTwo, outputCenteringTwo); + Field_t g(inputCenteringTwo, layout, + Vector(0.0), Vector(1.0, 2.0)); + + g.all() = 2.0; + g = -1.0; + g(FieldOffset(Loc(1,1), 0), Loc(0,0)) = 17.0; + tester.check("discontinuous vertex->continuous vertex", + checkFieldPosition(g, nn[0], Loc(1), + 14.0, 3.5, -1.0, 17.0, eps)); + + + // Test 2D Continuous Cell -> Continuous Cell. + + inputCenteringTwo = canonicalCentering<2>(CellType, Continuous, AllDim); + outputCenteringTwo = canonicalCentering<2>(CellType, Continuous, AllDim); + nn = nearestNeighbors(inputCenteringTwo, outputCenteringTwo); + Field_t f(inputCenteringTwo, layout, + Vector(0.0), Vector(1.0, 2.0)); + + f.all() = 2.0; + f = -1.0; + f(FieldOffset(Loc(1,1), 0), Loc(0,0)) = 17.0; + tester.check("cell->cell", + checkFieldPosition(f, nn[0], Loc(1,1), + 17.0, 17.0, 17.0, 17.0, eps)); + + + // Test 2D Discontinuous Face -> Continuous Edge. + + inputCenteringTwo = canonicalCentering<2>(FaceType, Discontinuous, AllDim); + outputCenteringTwo = canonicalCentering<2>(EdgeType, Continuous, AllDim); + nn = nearestNeighbors(inputCenteringTwo, outputCenteringTwo); + Field_t h(inputCenteringTwo, layout, + Vector(0.0), Vector(1.0, 2.0)); + + h.all() = 2.0; + h = -1.0; + h(FieldOffset(Loc(1), 0), Loc(0)) = 17.0; + tester.check("discontinuous face->edge", + checkFieldPosition(h, nn[0], Loc(1), + -2.0, -1.0, -1.0, -1.0, eps)); + + // Test 3D Discontinuous Vertex -> Continuous Cell. + + inputCenteringThree = canonicalCentering<3>(VertexType, Discontinuous, AllDim); + outputCenteringThree = canonicalCentering<3>(CellType, Continuous, AllDim); + nn3 = nearestNeighbors(inputCenteringThree, outputCenteringThree); + + Interval<3> physicalVertexDomain3(4, 4, 4); + DomainLayout<3> layout3(physicalVertexDomain3, GuardLayers<3>(1)); + Field, double, Brick> + G(inputCenteringThree, layout3, Vector<3>(0.0), Vector<3>(1.0, 2.0, 0.0)); + + G.all() = 2.0; + G = -1.0; + G(FieldOffset<3>(Loc<3>(1), 0), Loc<3>(0)) = 17.0; + tester.check("discontinuous vertex->cell", + checkFieldPosition(G, nn3[0], Loc<3>(1), + -46.0, -46.0/64.0, -1.0, 17.0, eps)); + + int ret = tester.results("FieldReductions"); + Pooma::finalize(); + return ret; + } + + // ACL:rcsinfo + // ---------------------------------------------------------------------- + // $RCSfile: FieldOffset.cpp,v $ $Author: oldham $ + // $Revision: 1.1.2.1 $ $Date: 2001/07/24 19:50:45 $ + // ---------------------------------------------------------------------- + // ACL:rcsinfo Index: tests/NearestNeighbors.cpp =================================================================== RCS file: NearestNeighbors.cpp diff -N NearestNeighbors.cpp *** /dev/null Tue May 5 14:32:27 1998 --- NearestNeighbors.cpp Thu Aug 2 13:48:52 2001 *************** *** 0 **** --- 1,325 ---- + // -*- 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 + //----------------------------------------------------------------------------- + // Test computing the set of nearest neighbors. + //----------------------------------------------------------------------------- + + #include "Pooma/NewFields.h" + #include "Utilities/Tester.h" + #include + #include + + + // Instead of checking all the nearest neighbor's FieldOffset values, + // we check "random" values. + + // Check if a FieldOffset is in the FieldOffsetList. + template + inline bool + checkForFieldOffset(const FieldOffsetList &lst, + const FieldOffset &offset) + { + for (FieldOffsetList::size_type index = 0; + index < lst.size(); + ++index) + if (lst[index] == offset) + return true; + return false; + } + + + // Check for a particular FieldOffset within a vector of FieldOffsetLists. + // The arguments should be: + // a tester object, + // a C-string describing the test(s), + // a vector of FieldOffsetLists, + // the vector's correct size, + // the index of the particular FieldOffsetList to check, + // the FieldOffsetList correct size, + // a FieldOffset that should be (or not be) present in the list, + // whether the FieldOffset should be present. + + template + inline bool + checkFieldOffset(Pooma::Tester &tester, + const char *testExplanation, + const std::vector > &nn, + const std::vector >::size_type nnSize, + const std::vector >::size_type listNum, + const FieldOffsetList::size_type listSize, + const FieldOffset &offset, + const bool offsetPresent = true) + { + PInsist(listNum >= 0 && listNum < nnSize, + "Incorrect std::vector index."); + + return + tester.check(testExplanation, nn.size() == nnSize) && + tester.check(testExplanation, nn[listNum].size() == listSize) && + tester.check(testExplanation, + checkForFieldOffset(nn[listNum], offset) == offsetPresent); + } + + + // Check that the distances are the same for all input values. + + // Compute the Manhattan distance of a difference between positions. + + template + inline double + manhattanDistance(const Vector &difference) + { + double answer; + for (int coordinate = Dim-1; coordinate >= 0; --coordinate) + answer += std::abs(difference(coordinate)); + return answer; + } + + // Compute the Manhattan distance between an input centering's value + // shifted by an FieldOffset and an output centering's value. + + template + inline double + manhattanDistance(const Centering &inputCentering, + const FieldOffset &offset, + const Centering &outputCentering, + const int outputIndex) + { + // Compute the actual input position. + Loc cellOffset = offset.cellOffset(); + Vector input = + inputCentering.positions()[offset.subFieldNumber()]; + for (int index = Dim-1; index >= 0; --index) + input(index) += cellOffset[index].first(); + + return manhattanDistance(outputCentering.positions()[outputIndex] - input); + } + + // Check that the distance between the input and output values are the + // same for all the input values. + + template + inline bool + sameDistances(const std::vector > &nn, + const Centering &inputCentering, + const Centering &outputCentering) + { + typedef std::vector >::size_type nn_size_type; + typedef FieldOffsetList::size_type fol_size_type; + PInsist(nn.size() == outputCentering.size(), + "Nearest neighbors and output centering must have the same length."); + + for (nn_size_type outputIndex = 0; outputIndex < nn.size(); ++outputIndex) + { + const double distance = + manhattanDistance(inputCentering, nn[outputIndex][0], + outputCentering, outputIndex); + for (fol_size_type inputIndex = 1; + inputIndex < nn[outputIndex].size(); + ++inputIndex) + if (std::abs(distance - + manhattanDistance(inputCentering, + nn[outputIndex][inputIndex], + outputCentering, outputIndex)) + > 1.0e-08) + return false; + } + + return true; + } + + + int main(int argc, char *argv[]) + { + Pooma::initialize(argc, argv); + Pooma::Tester tester(argc, argv); + + Centering<2> inputCenteringTwo, outputCenteringTwo; + Centering<3> inputCenteringThree, outputCenteringThree; + + // Test 2D Continuous Cell -> Continuous Cell. + + inputCenteringTwo = canonicalCentering<2>(CellType, Continuous, AllDim); + outputCenteringTwo = canonicalCentering<2>(CellType, Continuous, AllDim); + checkFieldOffset(tester, "cell->cell intracell", + nearestNeighbors(inputCenteringTwo, outputCenteringTwo, + true), + /* vector: */ 1, 0, + /* FieldOffsetList: */ 1, + FieldOffset<2>(Loc<2>(0))); + + checkFieldOffset(tester, "cell->cell intercell", + nearestNeighbors(inputCenteringTwo, + outputCenteringTwo), + /* vector: */ 1, 0, + /* FieldOffsetList: */ 1, + FieldOffset<2>(Loc<2>(0))); + + // Test 2D Continuous Vertex -> Continuous Cell. + + inputCenteringTwo = canonicalCentering<2>(VertexType, Continuous, AllDim); + outputCenteringTwo = canonicalCentering<2>(CellType, Continuous, AllDim); + checkFieldOffset(tester, "vertex->cell intracell", + nearestNeighbors(inputCenteringTwo, outputCenteringTwo, + true), + /* vector: */ 1, 0, + /* FieldOffsetList: */ 1, + FieldOffset<2>(Loc<2>(0))); + tester.check("vertex->cell intracell distances", + sameDistances(nearestNeighbors(inputCenteringTwo, + outputCenteringTwo, + true), + inputCenteringTwo, + outputCenteringTwo)); + + checkFieldOffset(tester, "vertex->cell intercell", + nearestNeighbors(inputCenteringTwo, + outputCenteringTwo), + /* vector: */ 1, 0, + /* FieldOffsetList: */ 4, + FieldOffset<2>(Loc<2>(0))); + checkFieldOffset(tester, "vertex->cell intercell", + nearestNeighbors(inputCenteringTwo, + outputCenteringTwo), + /* vector: */ 1, 0, + /* FieldOffsetList: */ 4, + FieldOffset<2>(Loc<2>(1,1))); + tester.check("vertex->cell intercell distances", + sameDistances(nearestNeighbors(inputCenteringTwo, + outputCenteringTwo), + inputCenteringTwo, + outputCenteringTwo)); + + + // Test 2D Discontinuous Vertex -> Continuous Cell. + + inputCenteringTwo = canonicalCentering<2>(VertexType, Discontinuous, AllDim); + outputCenteringTwo = canonicalCentering<2>(CellType, Continuous, AllDim); + checkFieldOffset(tester, "discontinuous vertex->cell intracell", + nearestNeighbors(inputCenteringTwo, outputCenteringTwo, + true), + /* vector: */ 1, 0, + /* FieldOffsetList: */ 4, + FieldOffset<2>(Loc<2>(0), 0)); + checkFieldOffset(tester, "discontinuous vertex->cell intracell", + nearestNeighbors(inputCenteringTwo, outputCenteringTwo, + true), + /* vector: */ 1, 0, + /* FieldOffsetList: */ 4, + FieldOffset<2>(Loc<2>(0), 3)); + tester.check("discontinuous vertex->cell intracell distances", + sameDistances(nearestNeighbors(inputCenteringTwo, + outputCenteringTwo, + true), + inputCenteringTwo, + outputCenteringTwo)); + + checkFieldOffset(tester, "discontinuous vertex->cell intercell", + nearestNeighbors(inputCenteringTwo, + outputCenteringTwo), + /* vector: */ 1, 0, + /* FieldOffsetList: */ 16, + FieldOffset<2>(Loc<2>(0), 0)); + checkFieldOffset(tester, "discontinuous vertex->cell intercell", + nearestNeighbors(inputCenteringTwo, + outputCenteringTwo), + /* vector: */ 1, 0, + /* FieldOffsetList: */ 16, + FieldOffset<2>(Loc<2>(0), 3)); + checkFieldOffset(tester, "discontinuous vertex->cell intercell", + nearestNeighbors(inputCenteringTwo, + outputCenteringTwo), + /* vector: */ 1, 0, + /* FieldOffsetList: */ 16, + FieldOffset<2>(Loc<2>(0), 3)); + checkFieldOffset(tester, "discontinuous vertex->cell intercell", + nearestNeighbors(inputCenteringTwo, + outputCenteringTwo), + /* vector: */ 1, 0, + /* FieldOffsetList: */ 16, + FieldOffset<2>(Loc<2>(-1,0), 3), false); + tester.check("discontinuous vertex->cell intercell distances", + sameDistances(nearestNeighbors(inputCenteringTwo, + outputCenteringTwo), + inputCenteringTwo, + outputCenteringTwo)); + + + // Test 3D Continuous Face -> Continuous Edge. + + inputCenteringThree = canonicalCentering<3>(FaceType, Continuous, AllDim); + outputCenteringThree = canonicalCentering<3>(EdgeType, Continuous, AllDim); + checkFieldOffset(tester, "face->edge intracell", + nearestNeighbors(inputCenteringThree, + outputCenteringThree, + true), + /* vector: */ 3, 1, + /* FieldOffsetList: */ 2, + FieldOffset<3>(Loc<3>(0), 2)); + tester.check("face->edge intracell distances", + sameDistances(nearestNeighbors(inputCenteringThree, + outputCenteringThree, + true), + inputCenteringThree, + outputCenteringThree)); + + checkFieldOffset(tester, "face->edge intercell", + nearestNeighbors(inputCenteringThree, + outputCenteringThree), + /* vector: */ 3, 1, + /* FieldOffsetList: */ 4, + FieldOffset<3>(Loc<3>(-1,0,0), 2)); + checkFieldOffset(tester, "face->edge intercell", + nearestNeighbors(inputCenteringThree, + outputCenteringThree), + /* vector: */ 3, 2, + /* FieldOffsetList: */ 4, + FieldOffset<3>(Loc<3>(-1,0,0), 1)); + checkFieldOffset(tester, "face->edge intercell", + nearestNeighbors(inputCenteringThree, + outputCenteringThree), + /* vector: */ 3, 2, + /* FieldOffsetList: */ 4, + FieldOffset<3>(Loc<3>(-1,-1,-1), 1), false); + tester.check("face->edge intercell distances", + sameDistances(nearestNeighbors(inputCenteringThree, + outputCenteringThree), + inputCenteringThree, + outputCenteringThree)); + + int ret = tester.results("NearestNeighbors"); + Pooma::finalize(); + return ret; + } + + // ACL:rcsinfo + // ---------------------------------------------------------------------- + // $RCSfile: FieldOffset.cpp,v $ $Author: oldham $ + // $Revision: 1.1.2.1 $ $Date: 2001/07/24 19:50:45 $ + // ---------------------------------------------------------------------- + // ACL:rcsinfo Index: tests/makefile =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/tests/makefile,v retrieving revision 1.11.2.3 diff -c -p -r1.11.2.3 makefile *** tests/makefile 2001/07/24 19:50:45 1.11.2.3 --- tests/makefile 2001/08/02 19:48:52 *************** field_tests:: $(ODIR)/BasicTest1 $(ODIR) *** 61,69 **** $(ODIR)/WhereTest $(ODIR)/VectorTest \ $(ODIR)/ScalarCode $(ODIR)/StencilTests \ $(ODIR)/ExpressionTest $(ODIR)/Centerings \ ! $(ODIR)/FieldOffset - ########################### .PHONY: BasicTest1 --- 61,69 ---- $(ODIR)/WhereTest $(ODIR)/VectorTest \ $(ODIR)/ScalarCode $(ODIR)/StencilTests \ $(ODIR)/ExpressionTest $(ODIR)/Centerings \ ! $(ODIR)/FieldOffset $(ODIR)/FieldReductions \ ! $(ODIR)/NearestNeighbors ########################### .PHONY: BasicTest1 *************** FieldOffset: $(ODIR)/FieldOffset *** 160,184 **** $(ODIR)/FieldOffset: $(ODIR)/FieldOffset.o $(LinkToSuite) ! .PHONY: FieldTour3 ! FieldTour3: $(ODIR)/FieldTour3 ! $(ODIR)/FieldTour3: $(ODIR)/FieldTour3.o $(LinkToSuite) ! .PHONY: ScalarAdvection ! ScalarAdvection: $(ODIR)/ScalarAdvection ! $(ODIR)/ScalarAdvection: $(ODIR)/ScalarAdvection.o $(LinkToSuite) ! .PHONY: ScalarAdvectionXB ! ScalarAdvectionXB: $(ODIR)/ScalarAdvectionXB ! $(ODIR)/ScalarAdvectionXB: $(ODIR)/ScalarAdvectionXB.o $(LinkToSuite) --- 160,184 ---- $(ODIR)/FieldOffset: $(ODIR)/FieldOffset.o $(LinkToSuite) ! .PHONY: FieldReductions ! FieldReductions: $(ODIR)/FieldReductions ! $(ODIR)/FieldReductions: $(ODIR)/FieldReductions.o $(LinkToSuite) ! .PHONY: FieldTour3 ! FieldTour3: $(ODIR)/FieldTour3 ! $(ODIR)/FieldTour3: $(ODIR)/FieldTour3.o $(LinkToSuite) ! .PHONY: NearestNeighbors ! NearestNeighbors: $(ODIR)/NearestNeighbors ! $(ODIR)/NearestNeighbors: $(ODIR)/NearestNeighbors.o $(LinkToSuite) From stephens at proximation.com Fri Aug 3 16:05:38 2001 From: stephens at proximation.com (Stephen Smith) Date: Fri, 3 Aug 2001 10:05:38 -0600 Subject: centerings patch Message-ID: The following patch is on the newfield_revision, where centerings are being added. The purpose of this patch is to switch the existing tests and stencil code to use the new centering object, and to fix the constructors in FieldEngine to correctly propagate the centering to the subfields. Stephen <<03.Aug.centering.patch>> -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: 03.Aug.centering.patch Type: application/octet-stream Size: 26616 bytes Desc: not available URL: From oldham at codesourcery.com Fri Aug 3 19:02:02 2001 From: oldham at codesourcery.com (Jeffrey Oldham) Date: Fri, 3 Aug 2001 12:02:02 -0700 Subject: [newfield_revision] Patch: Remove NewField/FieldInitializer.h Message-ID: <20010803120202.A14590@codesourcery.com> Stephen Smith recently incorporated the new centerings into the newfield_revision branch of the src/NewField directory. This patch removes the old centering implementation. 2001-08-03 Jeffrey D. Oldham * NewField/FieldInitializers.h: Remove this old centering implementation. * NewField/DiffOps/Div.UR.h: Remove inclusion of NewField/FieldInitializers.h. * NewField/DiffOps/Div.h: Likewise. * NewField/DiffOps/FieldStencil.h: Update comments to use new centering. * Pooma/NewFields.h: Remove inclusion of NewField/FieldInitializers.h. Tested on sequential Linux using gcc 3.0 by compiling Pooma library and NewField tests Approved by Scott Haney Branch newfield_revision Thanks, Jeffrey D. Oldham oldham at codesourcery.com -------------- next part -------------- Index: NewField/FieldInitializers.h =================================================================== RCS file: FieldInitializers.h diff -N FieldInitializers.h *** /tmp/cvsGkL82N Fri Aug 3 12:21:47 2001 --- /dev/null Tue May 5 14:32:27 1998 *************** *** 1,204 **** - // -*- 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 - - //----------------------------------------------------------------------------- - // Classes: - // Cell - // Vert - // Edge - // Face - // DistributeSubFields - // ReplicateSubFields - //----------------------------------------------------------------------------- - - #ifndef POOMA_NEWFIELD_FIELDINITIALIZERS_H - #define POOMA_NEWFIELD_FIELDINITIALIZERS_H - - //----------------------------------------------------------------------------- - // Overview: - // - // POOMA supports a hierarchy of multiple centering points per - // cell. The centering information, managed by the FieldEngineBase - // class, is initialized using a flexible set of functors. Below are some - // pre-defined functors that set up some common centerings along with some - // versions for building multi-material and multi-centered fields. - //----------------------------------------------------------------------------- - - //----------------------------------------------------------------------------- - // Includes: - //----------------------------------------------------------------------------- - - #include "Domain/Loc.h" - #include "Utilities/PAssert.h" - - #include - - //----------------------------------------------------------------------------- - // Forward declarations: - //----------------------------------------------------------------------------- - - /* None for now */ - - // ---------------------------------------------------------------------------- - // Full description: - // - // Initialization functors for the Field class: - // o Cell: cell-centered in every direction - // o Vert: vertex-centered in every direction - // o Edge cell-centered in specified direction, - // vertex-centered otherwise - // o Face: vertex-centered in specified direction, - // cell-centered otherwise - // o DistributeSubFields: distributes a centering along orientations - // corresponding to coordinate directions - // Example: AllEdge..edge-centered in every direction - // Example: AllFace..face-centered in every direction - // o ReplicateSubFields: replicates a centering N times - // Example: multi-material fields - // - // Usage Examples: - // - // Interval<3> I(10, 10, 10), J(5, 5, 5); - // FieldEngineBase<3, double, Brick> - // c1(Cell(), I), - // c2(Edge(1), I), - // c3(DistributeSubFields(), I), - // c4(ReplicateSubFields > - // (DistributeSubFields(), 5), I); - // - // Declares a cell-centering, an edge-centering aligned with the Y axis, an - // all-face centering, and a replicated all-face centering. - // ---------------------------------------------------------------------------- - - class Cell { - public: - - inline Cell() { } - - template - inline void initialize(Subject &s, const Initializer &init) const - { - Loc l(0); - s.initialize(l, init); - } - }; - - class Vert { - public: - - inline Vert() { } - - template - inline void initialize(Subject &s, const Initializer &init) const - { - Loc l(1); - s.initialize(l, init); - } - }; - - class Edge { - public: - - Edge(int orientation) : orientation_m(orientation) { } - - template - inline void initialize(Subject &s, const Initializer &init) const - { - Loc l(1); l[orientation_m] = Loc<1>(0); - s.initialize(l, init); - } - - private: - - int orientation_m; - }; - - class Face { - public: - - Face(int orientation) : orientation_m(orientation) { } - - template - inline void initialize(Subject &s, const Initializer &init) const - { - Loc l(0); l[orientation_m] = Loc<1>(1); - s.initialize(l, init); - } - - private: - - int orientation_m; - }; - - template - class DistributeSubFields { - public: - - DistributeSubFields() { } - - template - inline void initialize(Subject &s, const Initializer &init) const - { - s.addSubFields(Subject::dimensions); - for (int i = 0; i < Subject::dimensions; i++) - S(i).initialize(s.subField(i), init); - } - }; - - typedef DistributeSubFields AllEdge; - typedef DistributeSubFields AllFace; - - template - class ReplicateSubFields { - public: - - explicit ReplicateSubFields(int n) : n_m(n) { } - ReplicateSubFields(const S &c, int n) : subField_m(c), n_m(n) { } - - template - inline void initialize(Subject &s, const Initializer &init) const - { - s.addSubFields(n_m); - for (int i = 0; i < n_m; i++) - subField_m.initialize(s.subField(i), init); - } - - private: - - S subField_m; - int n_m; - }; - - #endif // POOMA_NEWFIELD_FIELDINITIALIZERS_H - - // ACL:rcsinfo - // ---------------------------------------------------------------------- - // $RCSfile: FieldInitializers.h,v $ $Author: oldham $ - // $Revision: 1.4 $ $Date: 2001/04/11 21:39:27 $ - // ---------------------------------------------------------------------- - // ACL:rcsinfo --- 0 ---- Index: NewField/DiffOps/Div.UR.h =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/DiffOps/Div.UR.h,v retrieving revision 1.5.2.1 diff -c -p -r1.5.2.1 Div.UR.h *** NewField/DiffOps/Div.UR.h 2001/08/03 16:07:13 1.5.2.1 --- NewField/DiffOps/Div.UR.h 2001/08/03 18:21:45 *************** *** 55,61 **** #include "Tiny/Vector.h" #include "NewField/DiffOps/FieldStencil.h" - #include "NewField/FieldInitializers.h" #include "NewField/FieldEngine/FieldEngine.UR.h" //----------------------------------------------------------------------------- --- 55,60 ---- Index: NewField/DiffOps/Div.h =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/DiffOps/Div.h,v retrieving revision 1.3.2.1 diff -c -p -r1.3.2.1 Div.h *** NewField/DiffOps/Div.h 2001/08/03 16:07:13 1.3.2.1 --- NewField/DiffOps/Div.h 2001/08/03 18:21:45 *************** *** 64,70 **** #include "NewField/Field.h" #include "NewField/FieldCentering.h" - #include "NewField/FieldInitializers.h" #include "NewField/DiffOps/FieldStencil.h" //----------------------------------------------------------------------------- --- 64,69 ---- Index: NewField/DiffOps/FieldStencil.h =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/DiffOps/FieldStencil.h,v retrieving revision 1.5.2.1 diff -c -p -r1.5.2.1 FieldStencil.h *** NewField/DiffOps/FieldStencil.h 2001/08/03 16:07:13 1.5.2.1 --- NewField/DiffOps/FieldStencil.h 2001/08/03 18:21:47 *************** struct FieldStencilSimple *** 466,487 **** // new number of guard layers. // // To create a stencil, users must create a class similar to the one below, ! // which computes a central difference divergence of a Vert-centered Field ! // and maps it to a Cell-centered Field: // // template // class Div { }; // ! // template ! // class Div, T1> >, ! // Vector > // { // public: // - // typedef Cell OutputCentering_t; // typedef T2 OutputElement_t; // // int lowerExtent(int) const // { // return 1; --- 466,489 ---- // new number of guard layers. // // To create a stencil, users must create a class similar to the one below, ! // which computes a central difference divergence of a vertex-centered Field ! // and maps it to a cell-centered Field: // // template // class Div { }; // ! // template ! // class DivVertToCell, UniformRectilinear > // { // public: // // typedef T2 OutputElement_t; // + // Centering outputCentering() const + // { + // return canonicalCentering(CellType, Continuous); + // } + // // int lowerExtent(int) const // { // return 1; Index: Pooma/NewFields.h =================================================================== RCS file: /home/pooma/Repository/r2/src/Pooma/NewFields.h,v retrieving revision 1.5 diff -c -p -r1.5 NewFields.h *** Pooma/NewFields.h 2001/03/01 15:48:12 1.5 --- Pooma/NewFields.h 2001/08/03 18:21:47 *************** *** 59,65 **** // Other stuff: - #include "NewField/FieldInitializers.h" #include "NewField/FieldReductions.h" #include "NewField/PrintField.h" #include "NewField/FieldOperatorSpecializations.h" --- 59,64 ---- From oldham at codesourcery.com Sat Aug 4 00:18:14 2001 From: oldham at codesourcery.com (Jeffrey Oldham) Date: Fri, 3 Aug 2001 17:18:14 -0700 Subject: [newfield_revision] Patch: Support Multimaterials Message-ID: <20010803171814.A26064@codesourcery.com> This patch finishes Stephen Smith's field revisions began today. Fields have two dimensions: materials and centering values. We add better support for determining the number of materials and centering values as well as initializing fields. The underlying implementation still makes differentiating a multimaterial field with one value per material from a unimaterial field with a centering with multiple values; this is on Scott's todo list. Also, we add some error checking for centerings. The newfield_revision branch is a development branch supporting collaboration between filesystem-separated collaborators. Compilation and correctness on the branch are not guaranteed at any time. 2001-08-03 Jeffrey D. Oldham and Stephen Smith * Field.h (Field::centering): Move definition. (Field::numMaterials): New function. * FieldCentering.h (Centering::operator[]): Add error checking. (Centering::size()): Likewise. * FieldEngine/FieldEngineBase.h: (FieldEngineBase::num_materials_m): New member. (FieldEngineBase::FieldEngineBase): Add num_materials_m initialization. (FieldEngineBase::initialize): Set centering_m and num_materials_m. (FieldEngineBase::addSubFields): Add error checking. (FieldEngineBase::centeringSize): New function. (FieldEngineBase::numMaterials): New function. Tested on KCC Linux and sequential gcc 3.0 Linux Approved by each other :) Applied by newfield_revision Thanks, Jeffrey D. Oldham oldham at codesourcery.com -------------- next part -------------- Index: Field.h =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/Field.h,v retrieving revision 1.15.2.5 diff -c -p -r1.15.2.5 Field.h *** Field.h 2001/08/03 16:07:12 1.15.2.5 --- Field.h 2001/08/04 00:11:42 *************** public: *** 1155,1165 **** --- 1155,1176 ---- return fieldEngine_m; } + // FIXME: This function is deprecated. inline int numSubFields() const { return fieldEngine_m.numSubFields(); } + const Centering ¢ering() + { + return fieldEngine().centering(); + } + + inline int numMaterials() const + { + return fieldEngine().numMaterials(); + } + inline const Domain_t physicalCellDomain() const { return fieldEngine_m.physicalCellDomain(); *************** public: *** 1194,1204 **** { return fieldEngine_m.physicalDomain(); } - - const Centering ¢ering() - { - return fieldEngine().centering(); - } //--------------------------------------------------------------------------- // Instruct the field to make its own copy of its data. --- 1205,1210 ---- Index: FieldCentering.h =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/Attic/FieldCentering.h,v retrieving revision 1.1.2.6 diff -c -p -r1.1.2.6 FieldCentering.h *** FieldCentering.h 2001/08/03 19:46:24 1.1.2.6 --- FieldCentering.h 2001/08/04 00:11:43 *************** *** 50,55 **** --- 50,56 ---- //----------------------------------------------------------------------------- #include "Tiny/Vector.h" + #include "Utilities/PAssert.h" #include //----------------------------------------------------------------------------- *************** public: *** 275,280 **** --- 276,283 ---- // Return a centering with one specified value. const Centering operator[](int iSubField) const { + PInsist(iSubField >= 0 && iSubField < size(), + "Illegal attempt to extract a non-existent centering."); return Centering(centering_type_m, discontinuous_m, Orientations(1, orientations_m[iSubField]), Positions(1, positions_m[iSubField])); *************** public: *** 316,321 **** --- 319,326 ---- inline int size() const { + PInsist(orientations_m.size() == positions_m.size(), + "In a centering, the number of orientations must match the number of positions."); return orientations_m.size(); } Index: FieldEngine/FieldEngineBase.h =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/FieldEngine/FieldEngineBase.h,v retrieving revision 1.13.2.2 diff -c -p -r1.13.2.2 FieldEngineBase.h *** FieldEngine/FieldEngineBase.h 2001/08/03 16:07:13 1.13.2.2 --- FieldEngine/FieldEngineBase.h 2001/08/04 00:11:43 *************** public: *** 148,154 **** FieldEngineBase() : physicalCellDomain_m(Pooma::NoInit()), ! guards_m(0) { } // ----------------------------------------------- --- 148,155 ---- FieldEngineBase() : physicalCellDomain_m(Pooma::NoInit()), ! guards_m(0), ! num_materials_m(0) { } // ----------------------------------------------- *************** public: *** 161,167 **** const FieldEngineBase &model) : physicalCellDomain_m(model.physicalCellDomain()), guards_m(model.guardLayers()), ! centering_m(centering) { if (centering.size() > 1) { --- 162,169 ---- const FieldEngineBase &model) : physicalCellDomain_m(model.physicalCellDomain()), guards_m(model.guardLayers()), ! centering_m(centering), ! num_materials_m(0) { if (centering.size() > 1) { *************** public: *** 188,201 **** const Layout_t &layout, int materials = 0) : physicalCellDomain_m(layout.domain()), guards_m(layout.externalGuards()), ! centering_m(centering) { shrinkInPlace(physicalCellDomain_m, guards_m); shrinkRightInPlace(physicalCellDomain_m, 1); ! if (materials > 0) { ! addSubFields(materials); ! for (int m = 0; m < materials; ++m) { if (centering.size() > 1) { --- 190,204 ---- const Layout_t &layout, int materials = 0) : physicalCellDomain_m(layout.domain()), guards_m(layout.externalGuards()), ! centering_m(centering), ! num_materials_m(materials) { shrinkInPlace(physicalCellDomain_m, guards_m); shrinkRightInPlace(physicalCellDomain_m, 1); ! if (num_materials_m > 0) { ! addSubFields(num_materials_m); ! for (int m = 0; m < num_materials_m; ++m) { if (centering.size() > 1) { *************** public: *** 242,261 **** : subFields_m(model.subFields_m), data_m(model.data_m), physicalCellDomain_m(model.physicalCellDomain_m), centering_m(model.centering_m), ! guards_m(model.guards_m) { } // Sub-field view constructor. This is when we want to construct a view of // one of the subFields in our top-level list. ! FieldEngineBase(const This_t &model, const int &iSubField) : subFields_m(model.subFields_m[iSubField].subFields_m), data_m(model.subFields_m[iSubField].data_m), physicalCellDomain_m(model.physicalCellDomain_m), centering_m(model.subFields_m[iSubField].centering_m), ! guards_m(model.guards_m) ! { } // View constructor. --- 245,269 ---- : subFields_m(model.subFields_m), data_m(model.data_m), physicalCellDomain_m(model.physicalCellDomain_m), + guards_m(model.guards_m), centering_m(model.centering_m), ! num_materials_m(model.num_materials_m) { } // Sub-field view constructor. This is when we want to construct a view of // one of the subFields in our top-level list. ! FieldEngineBase(const This_t &model, int iSubField) : subFields_m(model.subFields_m[iSubField].subFields_m), data_m(model.subFields_m[iSubField].data_m), physicalCellDomain_m(model.physicalCellDomain_m), + guards_m(model.guards_m), centering_m(model.subFields_m[iSubField].centering_m), ! num_materials_m(model.num_materials_m) ! { ! PInsist(iSubField >= 0 && iSubField < model.numSubFields(), ! "Illegal attempt to extract a non-existent subfield."); ! } // View constructor. *************** public: *** 294,308 **** subFields_m = model.subFields_m; data_m = model.data_m; physicalCellDomain_m = model.physicalCellDomain_m; - centering_m = model.centering_m; guards_m = model.guards_m; } template void initialize(This_t &s, ! const FieldEngineBase &model, const Domain_t &d) { int n = model.numSubFields(); if (n == 0) { s.physicalCellDomain_m = shrinkRight(d - d.firsts(), --- 302,319 ---- subFields_m = model.subFields_m; data_m = model.data_m; physicalCellDomain_m = model.physicalCellDomain_m; guards_m = model.guards_m; + centering_m = model.centering_m; + num_materials_m = model.num_materials_m; } template void initialize(This_t &s, ! const FieldEngineBase &model, ! const Domain_t &d) { int n = model.numSubFields(); + s.centering_m = model.centering(); if (n == 0) { s.physicalCellDomain_m = shrinkRight(d - d.firsts(), *************** public: *** 312,321 **** else { s.physicalCellDomain_m = d - d.firsts(); ! s.addSubFields(n); for (int i = 0; i < n; i++) initialize(s.subFields_m[i], model.subField(i), ! model.subField(i).translateDomain(d)); } } --- 323,333 ---- else { s.physicalCellDomain_m = d - d.firsts(); ! num_materials_m = model.numMaterials(); ! s.addSubFields(n); for (int i = 0; i < n; i++) initialize(s.subFields_m[i], model.subField(i), ! model.subField(i).translateDomain(d)); } } *************** public: *** 324,329 **** --- 336,342 ---- const FieldEngineBase &model, const INode &i) { int n = model.numSubFields(); + s.centering_m = model.centering(); if (n == 0) { s.physicalCellDomain_m = *************** public: *** 333,338 **** --- 346,352 ---- else { s.physicalCellDomain_m = i.domain() - i.domain().firsts(); + num_materials_m = model.numMaterials(); s.addSubFields(n); for (int j = 0; j < n; j++) initialize(s.subFields_m[j], model.subField(j), *************** public: *** 347,352 **** --- 361,367 ---- { typedef typename FieldEngineBase::Engine_t EngIn_t; int n = model.numSubFields(); + s.centering_m = model.centering(); if (n == 0) { s.physicalCellDomain_m = model.physicalCellDomain(); *************** public: *** 360,365 **** --- 375,381 ---- { s.physicalCellDomain_m = model.physicalCellDomain(); s.guards_m = model.guardLayers(); + num_materials_m = model.numMaterials(); s.addSubFields(n); for (int i = 0; i < n; i++) initialize(s.subFields_m[i], model.subField(i), ev); *************** public: *** 381,386 **** --- 397,403 ---- const ComponentWrapper &c) { int n = model.numSubFields(); + s.centering_m = model.centering(); if (n == 0) { s.physicalCellDomain_m = model.physicalCellDomain(); *************** public: *** 393,398 **** --- 410,416 ---- { s.physicalCellDomain_m = model.physicalCellDomain(); s.guards_m = model.guardLayers(); + num_materials_m = model.numMaterials(); s.addSubFields(n); for (int i = 0; i < n; i++) initialize(s.subFields_m[i], model.subField(i), c); *************** public: *** 405,416 **** --- 423,436 ---- int n = model.numSubFields(); s.physicalCellDomain_m = model.physicalCellDomain(); s.guards_m = model.guardLayers(); + s.centering_m = model.centering(); if (n == 0) { s.initialize(model.offsets(), model.engine()); } else { + num_materials_m = model.numMaterials(); s.addSubFields(n); for (int i = 0; i < n; i++) initialize(s.subFields_m[i], model.subField(i), d); *************** public: *** 424,429 **** --- 444,451 ---- void addSubFields(int n) { PAssert(subFields_m.size() == 0); + PAssert((numMaterials() == n) || + (numMaterials() == 0) && (centering_m.size() == n)); subFields_m.reserve(n); subFields_m.resize(n); *************** public: *** 431,437 **** { subFields_m[i].physicalCellDomain_m = physicalCellDomain_m; subFields_m[i].guards_m = guards_m; ! subFields_m[i].centering_m = centering_m[i]; } } --- 453,462 ---- { subFields_m[i].physicalCellDomain_m = physicalCellDomain_m; subFields_m[i].guards_m = guards_m; ! if (numMaterials() > 0) ! subFields_m[i].centering_m = centering_m; ! else ! subFields_m[i].centering_m = centering_m[i]; } } *************** public: *** 490,495 **** --- 515,529 ---- return guards_m; } + inline int centeringSize() const + { + return centering_m.size(); + } + + inline int numMaterials() const + { + return num_materials_m; + } //--------------------------------------------------------------------------- // Domain accessor functions. *************** private: *** 591,596 **** --- 625,631 ---- Domain_t physicalCellDomain_m; GuardLayers_t guards_m; Centering centering_m; + unsigned int num_materials_m; }; template From oldham at codesourcery.com Sat Aug 4 02:19:48 2001 From: oldham at codesourcery.com (Jeffrey Oldham) Date: Fri, 3 Aug 2001 19:19:48 -0700 Subject: [newfield_revision] Patch: StatigraphicFlow Message-ID: <20010803191948.A32228@codesourcery.com> I added the Lee et al statigraphic flow (Chevron) code in examples/NewField/StatigraphicFlow, newfield_revision branch. It probably will not compile until we finish the newfield_revision work. Approved by Stephen Smith Applied to newfield_revision Thanks, Jeffrey D. Oldham oldham at codesourcery.com From JimC at proximation.com Mon Aug 6 03:37:26 2001 From: JimC at proximation.com (James Crotinger) Date: Sun, 5 Aug 2001 21:37:26 -0600 Subject: timers and performance measurement under Linux Message-ID: How important is it that the timer used by the benchmark class measure CPU time? I'm not sure how we've even been using this class for parallel codes - in fact, I was thinking that back when we were just testing with threads, we were measuring wall-clock time. But the default implementation of Utilities/Clock.h uses the "clock()" call, which is supposed to measure "elapsed processor time", though I'm not completely sure what that means for a multithreaded program on a multi-processor. On the SGI we were using the high-performance timers, which I believe access the CPUs hardware performance registers, so I would think that that was CPU time as well. Anyway, the problem is that clock() only has 10 ms granularity under Linux and that's really crappy if you're trying to measure scaling with problem size. I've written a version that uses gettimeofday, which has a granularity of something like 15 microseconds under Linux (may depend on processor speed?), but this is definitely not a measure of CPU time. For serial programs this just means that you need to test on an unloaded machine to have the results make sense. For parallel programs, this means that you need to interpret the results differently. Anyway, I'm using this and it seems generally useful, so I'd like to check it in, but was wondering if the clock-time versus CPU-time measurement was a problem for anyone. I suppose we could put an accessor on Clock that would allow the user to find out what type of time was being presented, and Benchmark could examine this and calculate appropriately, if necessary. As a side comment, I'm using KCC on one of our 1 GHz PIII Linux boxes. ABCTest (which is doing a simple non-stencil calculation, so this is as fast as it gets) is only getting 45 MFlops for the C version, which is the fastest. This seems pretty pathetic. What have other Linux users seen on what types of boxes? Also, what is available on Linux for profiling? Is prof/gprof it? Does KAI sell anything commercial? Does the PIII have any hardware performance monitoring and is there access to it? Does VTune (under Windows) inline sufficiently well to do performance testing there (allegedly good profiling tools, so it might be OK for the serial stuff, but I don't know if it is capable of "inlining everything"). Jim -------------- next part -------------- An HTML attachment was scrubbed... URL: From JimC at proximation.com Mon Aug 6 16:45:50 2001 From: JimC at proximation.com (James Crotinger) Date: Mon, 6 Aug 2001 10:45:50 -0600 Subject: [pooma-dev] timers and performance measurement under Linux Message-ID: It looks to me like Benchmark is assuming wall-clock time - the MOps calculation is: opCount / time_per_iteration / 1.0e6 where time_per_iteration is basically the average over the iterations of (stop - start - overhead) where stop and start are measured with Clock::value(). If Clock::value() is returning total CPU time and we're running multi-threaded, then this isn't giving us what we want. If anything, the CPU time will go up with the number of threads. Of course, I don't know how clock() works with threads - if it is really returning the total CPU time for the process or what. If it were returning the CPU time for the calling thread, then the calculation is just plain wrong. If it is returning the total CPU time then the calculation needs to divide by the number of worker threads, or something like that - really it is also just plain wrong. The bottom line is that to measure parallel speedup we really want wall-clock time and so it seems that the place to be careful is if you're falling back on the default of clock() or using the SGI high-speed timers (I need to check the docs on these and see just what they really measure). At any rate, Stephen looked over my changes to use gettimeofday under Linux and said they look good, so I've committed my changes to src/Utilities/Clock.h along with correpsonding changes to the configure files. BTW, the Linux header files contain definitions of timespec and clock_gettime, but I couldn't figure out how to access them. Does anyone know? These give even higher resolution, or at least potentially do. But if I just include and , the compiler tells me timespec has not been defined. The headers check a macro __need_timespec and I tried defining this, but it didn't seem to have any effect. I ran into the same problem earlier when I tried to use nanosleep - it is in the header files, but it seems disabled by some configuration options. Jim -----Original Message----- From: James Crotinger [mailto:JimC at proximation.com] Sent: Sunday, August 05, 2001 9:37 PM To: 'pooma-dev at pooma.codesourcery.com' Subject: [pooma-dev] timers and performance measurement under Linux How important is it that the timer used by the benchmark class measure CPU time? I'm not sure how we've even been using this class for parallel codes - in fact, I was thinking that back when we were just testing with threads, we were measuring wall-clock time. But the default implementation of Utilities/Clock.h uses the "clock()" call, which is supposed to measure "elapsed processor time", though I'm not completely sure what that means for a multithreaded program on a multi-processor. On the SGI we were using the high-performance timers, which I believe access the CPUs hardware performance registers, so I would think that that was CPU time as well. Anyway, the problem is that clock() only has 10 ms granularity under Linux and that's really crappy if you're trying to measure scaling with problem size. I've written a version that uses gettimeofday, which has a granularity of something like 15 microseconds under Linux (may depend on processor speed?), but this is definitely not a measure of CPU time. For serial programs this just means that you need to test on an unloaded machine to have the results make sense. For parallel programs, this means that you need to interpret the results differently. Anyway, I'm using this and it seems generally useful, so I'd like to check it in, but was wondering if the clock-time versus CPU-time measurement was a problem for anyone. I suppose we could put an accessor on Clock that would allow the user to find out what type of time was being presented, and Benchmark could examine this and calculate appropriately, if necessary. As a side comment, I'm using KCC on one of our 1 GHz PIII Linux boxes. ABCTest (which is doing a simple non-stencil calculation, so this is as fast as it gets) is only getting 45 MFlops for the C version, which is the fastest. This seems pretty pathetic. What have other Linux users seen on what types of boxes? Also, what is available on Linux for profiling? Is prof/gprof it? Does KAI sell anything commercial? Does the PIII have any hardware performance monitoring and is there access to it? Does VTune (under Windows) inline sufficiently well to do performance testing there (allegedly good profiling tools, so it might be OK for the serial stuff, but I don't know if it is capable of "inlining everything"). Jim -------------- next part -------------- An HTML attachment was scrubbed... URL: From stephens at proximation.com Mon Aug 6 17:02:45 2001 From: stephens at proximation.com (Stephen Smith) Date: Mon, 6 Aug 2001 11:02:45 -0600 Subject: [newfield_revision] patch: FieldShiftEngine Message-ID: <<06Aug.field.shift.patch>> This patch combines two sets of changes: 1) FieldShiftEngine.h supports a shifted view of a field, to support the syntax f(fieldOffset, centering), which allows you translate between fields with different centerings. 2) I also incorporated changes sent by J. Oldham to clean up the tests in new field. (CrossBox.cpp changed to use new centerings, ExpressionTest.cpp fixed the name at the end, alphabetized makefile targets.) Tested with KCC under linux. Reviewed by Jeffery Oldham and myself. Stephen Smith -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: 06Aug.field.shift.patch Type: application/octet-stream Size: 36550 bytes Desc: not available URL: From cummings at linkline.com Mon Aug 6 18:20:56 2001 From: cummings at linkline.com (Julian C. Cummings) Date: Mon, 6 Aug 2001 11:20:56 -0700 Subject: [pooma-dev] timers and performance measurement under Linux In-Reply-To: Message-ID: timers and performance measurement under LinuxHi Jim, It's probably a good idea to have an option for choosing between CPU time and wallclock time as the benchmark measurement, since they each have their own purpose. Normally CPU time is interesting for measuring on-node performance and wallclock time is more useful for measuring parallel speedup. As for threads, I think you can only measure CPU time while a thread is active on a processor. Doing anything else doesn't really make sense. So with clock(), you would want to call clock() when a thread first begins to work (not before the thread is actually launched!) and then call clock() again when the thread is done working (but before the thread exits). If each thread does a tiny amount of work, the resolution issue you mentioned will be an issue. The clock() function has different resolutions on different architectures. But normally the variation in performance measurement from one run to the next is far greater than the timer resolution anyway. The gettimeofday() function is probably the best thing to use for wallclock time measurement. This is what we used in the old Timer class in Pooma r1. I haven't looked at your check-in yet, but hopefully you remembered to check for overflow in the microseconds counter and increment the seconds counter accordingly. Other than that, I remember that code as being pretty simple. As for your comments on the PIII performance, I think what you are seeing is correct. The out-of-cache performance is not very good. You will see closer to optimal performance only when the problem size is in-cache, and the caches are much smaller than what we were used to on the SGI boxes. With an optimized C code kernel, you should be able to see the cache effect and stronger flops numbers for small problem sizes. (But of course, it gets harder to measure accurately, too.) I'm not aware of any profiling tools from KAI, so I think prof/gprof is all there is, unless you know how to access Pentium hardware counters. Quite a while ago, I fooled around with the performance analysis tools that come with Intel VTune. They were not terribly helpful, other than telling me the obvious, that all the time was being spent in the kernel loop. The real problem is that the optimization and inlining of the compiler were poor enough that there was little to do to improve performance. I remember being surprised to find that Blitz code optimized much better under VTune than Pooma code. I think the reasons had to do with the amount of template complexity in Pooma versus Blitz. Maybe things are better under newer versions of VTune, but Allan didn't seem too impressed with the newest VTune when I asked him about it. In any case, I sort of thought that VTune was not an important target for Pooma and its customers, so I haven't pursued it further. Julian C. -----Original Message----- From: James Crotinger [mailto:JimC at proximation.com] Sent: Sunday, August 05, 2001 8:37 PM To: 'pooma-dev at pooma.codesourcery.com' Subject: [pooma-dev] timers and performance measurement under Linux How important is it that the timer used by the benchmark class measure CPU time? I'm not sure how we've even been using this class for parallel codes - in fact, I was thinking that back when we were just testing with threads, we were measuring wall-clock time. But the default implementation of Utilities/Clock.h uses the "clock()" call, which is supposed to measure "elapsed processor time", though I'm not completely sure what that means for a multithreaded program on a multi-processor. On the SGI we were using the high-performance timers, which I believe access the CPUs hardware performance registers, so I would think that that was CPU time as well. Anyway, the problem is that clock() only has 10 ms granularity under Linux and that's really crappy if you're trying to measure scaling with problem size. I've written a version that uses gettimeofday, which has a granularity of something like 15 microseconds under Linux (may depend on processor speed?), but this is definitely not a measure of CPU time. For serial programs this just means that you need to test on an unloaded machine to have the results make sense. For parallel programs, this means that you need to interpret the results differently. Anyway, I'm using this and it seems generally useful, so I'd like to check it in, but was wondering if the clock-time versus CPU-time measurement was a problem for anyone. I suppose we could put an accessor on Clock that would allow the user to find out what type of time was being presented, and Benchmark could examine this and calculate appropriately, if necessary. As a side comment, I'm using KCC on one of our 1 GHz PIII Linux boxes. ABCTest (which is doing a simple non-stencil calculation, so this is as fast as it gets) is only getting 45 MFlops for the C version, which is the fastest. This seems pretty pathetic. What have other Linux users seen on what types of boxes? Also, what is available on Linux for profiling? Is prof/gprof it? Does KAI sell anything commercial? Does the PIII have any hardware performance monitoring and is there access to it? Does VTune (under Windows) inline sufficiently well to do performance testing there (allegedly good profiling tools, so it might be OK for the serial stuff, but I don't know if it is capable of "inlining everything"). Jim -------------- next part -------------- An HTML attachment was scrubbed... URL: From JimC at proximation.com Mon Aug 6 18:47:36 2001 From: JimC at proximation.com (James Crotinger) Date: Mon, 6 Aug 2001 12:47:36 -0600 Subject: [pooma-dev] timers and performance measurement under Linux Message-ID: -----Original Message----- From: Julian C. Cummings [mailto:cummings at linkline.com] Sent: Monday, August 06, 2001 12:21 PM To: James Crotinger; pooma-dev at pooma.codesourcery.com Subject: RE: [pooma-dev] timers and performance measurement under Linux Julian: --------------------------------------------------- The gettimeofday() function is probably the best thing to use for wallclock time measurement. This is what we used in the old Timer class in Pooma r1. I haven't looked at your check-in yet, but hopefully you remembered to check for overflow in the microseconds counter and increment the seconds counter accordingly. Other than that, I remember that code as being pretty simple. ----------------------------------------------------------- I just did: return tv.tv_sec + 1.e-6 * tv.tv_usec; This mirrors what we are doing with clock_gettime. My interpretation of gettimeofday is that tv_usec should always be less than 1e6 - it is supposed to return the number of seconds and microseconds since 12:00 am Jan 1, 1970. I checked this under Linux - tv_usec resets to zero everytime tv_sec is increased. So I don't see a reason to put our own (% 1000000) after it, and indeed if it were over 1000000 I'm not even sure how I'd interpret tv_sec. Julian: --------------------------------------------------- As for your comments on the PIII performance, I think what you are seeing is correct. The out-of-cache performance is not very good. You will see closer to optimal performance only when the problem size is in-cache, and the caches are much smaller than what we were used to on the SGI boxes. With an optimized C code kernel, you should be able to see the cache effect and stronger flops numbers for small problem sizes. (But of course, it gets harder to measure accurately, too.) I'm not aware of any profiling tools from KAI, so I think prof/gprof is all there is, unless you know how to access Pentium hardware counters. ----------------------------------------------------------- Oh, this number is definitely memory bandwidth limited - there are three to four loads and two stores every trip through the loop, which does four flops (two multiplies and two adds). I get a peak C performance of about 390 MFlops for N = 60 or so. The peak POOMA II Brick performance is only 115 at a slightly higher N and then it drops off very rapidly to about 30. I tried gprof with "KCC -pg" generated code this morning, and gprof crashed after about 10 minutes of crunching on the output of a run. Has anyone else out there seen this? I'm going to try compiling with gcc, but I'm not sure it generates good enough code for me to trust the profile results to guide me to the right optimizations. Jim -------------- next part -------------- An HTML attachment was scrubbed... URL: From cummings at linkline.com Mon Aug 6 19:42:26 2001 From: cummings at linkline.com (Julian C. Cummings) Date: Mon, 6 Aug 2001 12:42:26 -0700 Subject: [pooma-dev] timers and performance measurement under Linux In-Reply-To: Message-ID: timers and performance measurement under LinuxJim, On the gettimeofday stuff: I may have been thinking of checking for overflow in the internal storage of elapsed time in our old Timer class. The Timer class had start() and stop() functions, so you had to accumulate the elapsed time between many starts and stops. In this case, you will certainly need to make adjustments as time is accumulated. If you are just returning the seconds and microseconds values from a single call to gettimeofday, I don't think there is any issue with overflows. Your performance results sound consistent with things I've seen in the past with KCC on linux. Pooma code seems to have a hard time reproducing the high peak in on-node performance due to the cache effect. I'm not sure why that is. I've never tried using gprof with KCC code, but it should work. I'd report it to KAI and see what they say. I would think it would be worth looking at profiling data from gcc code as well, just to make sure there is nothing crazy going on. Besides, I thought the performance gap had closed a fair bit between KCC and gcc in our last round of Pooma performance testing. Is there still a really huge difference with gcc 3.0? Julian C. -----Original Message----- From: James Crotinger [mailto:JimC at proximation.com] Sent: Monday, August 06, 2001 11:48 AM To: 'cummings at linkline.com'; James Crotinger; pooma-dev at pooma.codesourcery.com Subject: RE: [pooma-dev] timers and performance measurement under Linux -----Original Message----- From: Julian C. Cummings [mailto:cummings at linkline.com] Sent: Monday, August 06, 2001 12:21 PM To: James Crotinger; pooma-dev at pooma.codesourcery.com Subject: RE: [pooma-dev] timers and performance measurement under Linux Julian: --------------------------------------------------- The gettimeofday() function is probably the best thing to use for wallclock time measurement. This is what we used in the old Timer class in Pooma r1. I haven't looked at your check-in yet, but hopefully you remembered to check for overflow in the microseconds counter and increment the seconds counter accordingly. Other than that, I remember that code as being pretty simple. ----------------------------------------------------------- I just did: return tv.tv_sec + 1.e-6 * tv.tv_usec; This mirrors what we are doing with clock_gettime. My interpretation of gettimeofday is that tv_usec should always be less than 1e6 - it is supposed to return the number of seconds and microseconds since 12:00 am Jan 1, 1970. I checked this under Linux - tv_usec resets to zero everytime tv_sec is increased. So I don't see a reason to put our own (% 1000000) after it, and indeed if it were over 1000000 I'm not even sure how I'd interpret tv_sec. Julian: --------------------------------------------------- As for your comments on the PIII performance, I think what you are seeing is correct. The out-of-cache performance is not very good. You will see closer to optimal performance only when the problem size is in-cache, and the caches are much smaller than what we were used to on the SGI boxes. With an optimized C code kernel, you should be able to see the cache effect and stronger flops numbers for small problem sizes. (But of course, it gets harder to measure accurately, too.) I'm not aware of any profiling tools from KAI, so I think prof/gprof is all there is, unless you know how to access Pentium hardware counters. ----------------------------------------------------------- Oh, this number is definitely memory bandwidth limited - there are three to four loads and two stores every trip through the loop, which does four flops (two multiplies and two adds). I get a peak C performance of about 390 MFlops for N = 60 or so. The peak POOMA II Brick performance is only 115 at a slightly higher N and then it drops off very rapidly to about 30. I tried gprof with "KCC -pg" generated code this morning, and gprof crashed after about 10 minutes of crunching on the output of a run. Has anyone else out there seen this? I'm going to try compiling with gcc, but I'm not sure it generates good enough code for me to trust the profile results to guide me to the right optimizations. Jim From scotth at proximation.com Tue Aug 7 22:36:11 2001 From: scotth at proximation.com (Scott Haney) Date: Tue, 7 Aug 2001 16:36:11 -0600 Subject: Initial mesh implementation [newfield_revision] Message-ID: I just checked in UniformRectilinearMesh NoMesh into the newfield_revision branch. These were reviewed by Stephen and represent the first part of mesh functionality: constructors and accessors. Note that I have removed coordinate system from the mesh concept because it fundamentally has nothing to do with meshes, which simply map index locations -> coordinate locations. I'll bring coordinate system back into the system in the functors that will be used to compute positions, volumes, etc. Scott From scotth at proximation.com Wed Aug 8 15:13:39 2001 From: scotth at proximation.com (Scott Haney) Date: Wed, 8 Aug 2001 09:13:39 -0600 Subject: Patch - newfield_revision branch Message-ID: I forgot to check in some stuff yesterday when I made the mesh addition. Attached is the patch. Thanks Jeffrey for pointing this out. To summarize: (1) We are (sigh) still uneven in complete support for various concepts. In particular, not all of the layouts support innerDomain(), which is used to give the domain less the external guards. I added this to DomainLayout.h. (2) I forgot to comment out work in progress inside of UniformRectilinearMesh.h and GCC picked up a missing semi-colon inside a template. (3) There was a typo in a comment in MeshTest1.cpp. (4) Added MeshTest1 to the makefile in the NewField/tests directory (5) Added Mesh files to Pooma/NewFields.h. I'm just checking this in since it should have been done yesterday. Scott -------------- next part -------------- I forgot to check in some stuff yesterday when I made the mesh addition. Attached is the patch. Thanks Jeffrey for pointing this out. To summarize: (1) We are (sigh) still uneven in complete support for various concepts. In particular, not all of the layouts support innerDomain(), which is used to give the domain less the external guards. I added this to DomainLayout.h. (2) I forgot to comment out work in progress inside of UniformRectilinearMesh.h and GCC picked up a missing semi-colon inside a template. (3) There was a typo in a comment in MeshTest1.cpp. (4) Added MeshTest1 to the makefile in the NewField/tests directory (5) Added Mesh files to Pooma/NewFields.h. I'm just checking this in since it should have been done yesterday. Scott -------------- next part -------------- A non-text attachment was scrubbed... Name: 080801.1.patch Type: application/applefile Size: 74 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: 080801.1.patch Type: application/octet-stream Size: 4905 bytes Desc: not available URL: From oldham at codesourcery.com Wed Aug 8 23:35:08 2001 From: oldham at codesourcery.com (Jeffrey Oldham) Date: Wed, 8 Aug 2001 16:35:08 -0700 Subject: [newfield_revision Patch] Modify Doof2d Benchmark Message-ID: <20010808163508.A23396@codesourcery.com> Only one benchmark program uses Fields. This patch to the newfield_revision branch revises it to use the new NewField abstractions. 2001-08-08 Jeffrey D. Oldham * Doof2dInP2.h (Doof2dInP2NewField::initialize): Modify centering to use new abstraction. Tested on sequential Linux using gcc 3.0.1 by compiling Doof2d Approved by Stephen Smith Applied to newfield_revision branch Thanks, Jeffrey D. Oldham oldham at codesourcery.com -------------- next part -------------- Index: Doof2dInP2.h =================================================================== RCS file: /home/pooma/Repository/r2/benchmarks/Doof2d/Doof2dInP2.h,v retrieving revision 1.38 diff -c -p -r1.38 Doof2dInP2.h *** Doof2dInP2.h 2000/09/08 23:40:02 1.38 --- Doof2dInP2.h 2001/08/07 20:52:17 *************** public: *** 67,73 **** Interval<2> newDomain(N, N); DomainLayout<2> layout(newDomain); ! Vert vert; Vector<2> origin(0.0, 0.0); Vector<2> spacings(1.0, 1.0); --- 67,73 ---- Interval<2> newDomain(N, N); DomainLayout<2> layout(newDomain); ! Centering<2> vert = canonicalCentering<2>(VertexType, Continuous); Vector<2> origin(0.0, 0.0); Vector<2> spacings(1.0, 1.0); From oldham at codesourcery.com Fri Aug 10 17:40:14 2001 From: oldham at codesourcery.com (Jeffrey Oldham) Date: Fri, 10 Aug 2001 10:40:14 -0700 Subject: [newfield_revision Patch] Rename Reduction Function Names Message-ID: <20010810104014.A14105@codesourcery.com> This patch mixes two concepts: 1) Adding two comments explaining a) how to use data-parallel FieldOffsets b) an idea how to revise FieldOffsets 2) Renaming reduction functions so those using FieldOffsetLists and those reducing an entire subfield have the same name. 2001-08-10 Jeffrey D. Oldham * FieldOffset.h: Add a FIXME comment listing an idea for revising the FieldOffset. (av): New function renamed from average(). (min): New function renamed from minimum(). (max): New function renamed from maximum(). * tests/FieldOffset.cpp: Add a comment how to use data parallel statements. * tests/FieldReductions.cpp (checkFieldPosition): Revise functions names per FieldOffset.h change. Tested on sequential Linux using gcc 3.0.1 by compiling Pooma library and +NewField tests Approved by Stephen Smith Applied to newfield_revision branch Thanks, Jeffrey D. Oldham oldham at codesourcery.com -------------- next part -------------- Index: FieldOffset.h =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/Attic/FieldOffset.h,v retrieving revision 1.1.2.2 diff -c -p -r1.1.2.2 FieldOffset.h *** FieldOffset.h 2001/08/02 22:36:56 1.1.2.2 --- FieldOffset.h 2001/08/09 23:13:04 *************** *** 33,41 **** // Functions: // accumulate // sum ! // average ! // minimum ! // maximum //----------------------------------------------------------------------------- #ifndef POOMA_NEWFIELD_OFFSET_H --- 33,41 ---- // Functions: // accumulate // sum ! // av ! // min ! // max //----------------------------------------------------------------------------- #ifndef POOMA_NEWFIELD_OFFSET_H *************** *** 52,57 **** --- 52,63 ---- // - computations using the entries in a FieldOffsetList //----------------------------------------------------------------------------- + // FIXME: Perhaps we wish to store pointers to input and output + // FIXME: centerings in a FieldOffset. Storing the input centering + // FIXME: will permit assertion checking when a FieldOffset is used to + // FIXME: reference a field. The stored output centering is used in + // FIXME: data-parallel uses. + //----------------------------------------------------------------------------- // Includes: //----------------------------------------------------------------------------- *************** class FieldOffsetList; *** 114,124 **** // accumulate: Sequentially applies the given binary function to all // field offsets in the list. // sum: Adds the values indicated by the field offset list. ! // average: Averages the values indicated by the field offset // list. Note the division is computed using the element // type, e.g., integral or floating point division. ! // minimum: Returns the smallest of the indicated values. ! // maximum: Returns the largest of the indicated values. // //----------------------------------------------------------------------------- --- 120,130 ---- // accumulate: Sequentially applies the given binary function to all // field offsets in the list. // sum: Adds the values indicated by the field offset list. ! // av: Averages the values indicated by the field offset // list. Note the division is computed using the element // type, e.g., integral or floating point division. ! // min: Returns the smallest of the indicated values. ! // max: Returns the largest of the indicated values. // //----------------------------------------------------------------------------- *************** sum(const Field& f *** 372,380 **** template inline typename Field::T_t ! average(const Field& field, ! const FieldOffsetList &lst, ! const Loc &loc) { typedef typename Field::T_t T_t; CTAssert((Field::dimensions == Dim)); --- 378,386 ---- template inline typename Field::T_t ! av(const Field& field, ! const FieldOffsetList &lst, ! const Loc &loc) { typedef typename Field::T_t T_t; CTAssert((Field::dimensions == Dim)); *************** struct fomin : public std::binary_functi *** 395,403 **** template inline typename Field::T_t ! minimum(const Field& field, ! const FieldOffsetList &lst, ! const Loc &loc) { typedef typename Field::T_t T_t; CTAssert((Field::dimensions == Dim)); --- 401,409 ---- template inline typename Field::T_t ! min(const Field& field, ! const FieldOffsetList &lst, ! const Loc &loc) { typedef typename Field::T_t T_t; CTAssert((Field::dimensions == Dim)); *************** struct fomax : public std::binary_functi *** 418,426 **** template inline typename Field::T_t ! maximum(const Field& field, ! const FieldOffsetList &lst, ! const Loc &loc) { typedef typename Field::T_t T_t; CTAssert((Field::dimensions == Dim)); --- 424,432 ---- template inline typename Field::T_t ! max(const Field& field, ! const FieldOffsetList &lst, ! const Loc &loc) { typedef typename Field::T_t T_t; CTAssert((Field::dimensions == Dim)); Index: tests/FieldOffset.cpp =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/tests/Attic/FieldOffset.cpp,v retrieving revision 1.1.2.3 diff -c -p -r1.1.2.3 FieldOffset.cpp *** tests/FieldOffset.cpp 2001/08/06 17:02:50 1.1.2.3 --- tests/FieldOffset.cpp 2001/08/09 23:13:04 *************** int main(int argc, char *argv[]) *** 119,124 **** --- 119,131 ---- f[0] = iota(f[0].domain()).comp(1) * iota(f[0].domain()).comp(1); f[1] = iota(f[1].domain()).comp(0) * iota(f[1].domain()).comp(0); + // Test the data-parallel uses. + + // Example data-parallel use: + // result_field = f(FieldOffset, result_centering). The FieldOffset + // should specify a location in the field f. The second parameter + // specifies the desired output centering. + FieldOffset<2> lowerXEdge(Loc<2>(0, 0), 0), upperXEdge(Loc<2>(0, 1), 0); FieldOffset<2> leftYEdge(Loc<2>(0, 0), 1), rightYEdge(Loc<2>(1, 0), 1); Index: tests/FieldReductions.cpp =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/tests/Attic/FieldReductions.cpp,v retrieving revision 1.1.2.1 diff -c -p -r1.1.2.1 FieldReductions.cpp *** tests/FieldReductions.cpp 2001/08/02 22:36:56 1.1.2.1 --- tests/FieldReductions.cpp 2001/08/09 23:13:04 *************** checkFieldPosition(const Field I'm heading out for a family vacation. I'll be back in the office on 8/21. Jim -------------- next part -------------- An HTML attachment was scrubbed... URL: From oldham at codesourcery.com Sat Aug 11 15:08:23 2001 From: oldham at codesourcery.com (Jeffrey Oldham) Date: Sat, 11 Aug 2001 08:08:23 -0700 Subject: Chi FAQ Message-ID: <200108111508.IAA05417@oz.codesourcery.com> A Chi FAQ (https://wwwproxy0.lanl.gov/AUTO/http://icnn.lanl.gov/ldswg/icnn/data/LinkFiles/chi_doc101.htm) is available off the ASCI Blue Mountain Today status WWW page. I reached this page through a series of links starting at http://icnn.lanl.gov/ascitoday. Thanks, Jeffrey D. Oldham oldham at codesourcery.com From stephens at proximation.com Mon Aug 13 21:13:56 2001 From: stephens at proximation.com (Stephen Smith) Date: Mon, 13 Aug 2001 15:13:56 -0600 Subject: Gradient example patch Message-ID: This patch adds Gradient.cpp in NewField/tests as an example code that uses the nearest neighbor function. Also, some minor fixes in Field to get it working: Field.h - made centering() accessor const FieldCentering.h - added position(i) and orientation(i) NearestNeighbor.h - added inputPosition function to compute a position in logical coordinates from a field offset. FieldShiftEngine.h, FieldStencilEngine.h, FieldEngineBase.h - switched from Pooma::NoInit to use default engine constructors, since that's currently supported by all engines. Tested using KCC on Linux. Reviewed by Jeffrey Oldham. Stephen -------------- next part -------------- An HTML attachment was scrubbed... URL: From oldham at codesourcery.com Tue Aug 14 20:23:38 2001 From: oldham at codesourcery.com (Jeffrey Oldham) Date: Tue, 14 Aug 2001 13:23:38 -0700 Subject: [newfield_revision] Patch: Miscellaneous Changes Message-ID: <20010814132338.A2254@codesourcery.com> This patch, applied to the newfield_revision branch, does: 1) Revises some code to use orientation() and position(). 2) Changes some user code from the deprecated .numSubFields() to .numMaterials() and .centering(). 3) Ensures that numMaterials(), centering(), and num_materials_m are available from all field engines. 2001-08-14 Jeffrey D. Oldham * FieldCentering.h (Centering::orientation): New function. (Centering::position): New function. (operator<<(..., Centering)): Revise to use the two previous functions. * FieldReductions.h (sum): Revise assertion to use user Field code. (prod): Likewise. (min): Likewise. (max): Likewise. (all): Likewise. (any): Likewise. (bitOr): Likewise. (bitAnd): Likewise. * NearestNeighbors.h (inputPosition): New function. * DiffOps/FieldShiftEngine.h (Engine::Engine): Revise initializer. (Engine::Engine(NoInit)): Remove function. * DiffOps/FieldStencil.h (Engine::Engine): Revise initializer. (Engine::Engine(NoInit)): Remove function. * FieldEngine/FieldEngine.NoGeometry.h (FieldEngine): Derive from FieldEngineBase. (FieldEngine::numSubFields): Mark this function as deprecatd. * FieldEngine/FieldEngineBase.ExprEngine.h (FieldEngineBase::numSubFields): Likewise. (FieldEngineBase::centering): New function. (FieldEngineBase::centeringSize): New function. (FieldEngineBase::numMaterials): New function. * FieldEngine/FieldEngineBase.h (FieldEngineBase::FieldEngineBase): Revise to use Centering's orientation(). (FieldEngineBase::FieldEngineBase): Fix num_materials_m's initialization. (FieldEngineBase::initialize): Move num_materials_m initialization to occur for all field types. (FieldEngineBase::initialize): Likewise. Const'ify variable. (FieldEngineBase::initialize): Add num_materials_m initialization. (FieldEngineBase::initialize): Move num_materials_m initialization to occur for all field types. Const'ify variable. * (FieldEngineBase::numSubFields): Mark function as deprecated. (FieldEngineBase::centeringSize): Move nearer centering(). * Mesh/UniformRectilinearMesh.h (UniformRectilinearMesh::PositionsFunctor::PositionsFunctor): Revise to use Centering's position(). * Updater/ConstantFaceBC.h: Revise assertion to use user Field code. * Updater/PeriodicFaceBC.cpp: Likewise. * Updater/PosReflectFaceBC.cpp: Likewise. * tests/NearestNeighbors.cpp (manhattanDistance): Simplify to use inputPosition(). * tests/makefile: Alphabetize. Tested on sequential Linux using gcc 3.0.1 by compiling Pooma and NewField tests Approved by Stephen Smith Applied to newfield_revision branch Thanks, Jeffrey D. Oldham oldham at codesourcery.com -------------- next part -------------- ? 13Aug.14.4.patch ? LINUXgcc ? 14Aug.13.0.patch ? tests/LINUXgcc Index: FieldCentering.h =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/Attic/FieldCentering.h,v retrieving revision 1.1.2.8 diff -c -p -r1.1.2.8 FieldCentering.h *** FieldCentering.h 2001/08/13 21:14:30 1.1.2.8 --- FieldCentering.h 2001/08/14 19:58:26 *************** std::ostream &operator<<(std::ostream &o *** 483,490 **** << ",{"; for (int i = 0; i < centering.size();) { ! o << "[" << centering.orientations()[i] ! << "," << centering.positions()[i] << "]"; ++i; if (i < centering.size()) o << ","; --- 483,490 ---- << ",{"; for (int i = 0; i < centering.size();) { ! o << "[" << centering.orientation(i) ! << "," << centering.position(i) << "]"; ++i; if (i < centering.size()) o << ","; Index: FieldReductions.h =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/FieldReductions.h,v retrieving revision 1.3 diff -c -p -r1.3 FieldReductions.h *** FieldReductions.h 2001/04/27 23:37:33 1.3 --- FieldReductions.h 2001/08/14 19:58:26 *************** class Field; *** 64,72 **** template T sum(const Field &f) { ! // These versions only work with fields with no sub-fields. ! PAssert(f.numSubFields() == 0); // We need to notify the field that we are reducing that we are getting // ready to read. --- 64,72 ---- template T sum(const Field &f) { ! // These versions only work with fields with one value per cell. ! PAssert(f.numMaterials() <= 1 && f.centering().size() <= 1); // We need to notify the field that we are reducing that we are getting // ready to read. *************** T sum(const Field T prod(const Field &f) { ! // These versions only work with fields with no sub-fields. ! PAssert(f.numSubFields() == 0); // We need to notify the field that we are reducing that we are getting // ready to read. --- 83,91 ---- template T prod(const Field &f) { ! // These versions only work with fields with one value per cell. ! PAssert(f.numMaterials() <= 1 && f.centering().size() <= 1); // We need to notify the field that we are reducing that we are getting // ready to read. *************** T prod(const Field T min(const Field &f) { ! // These versions only work with fields with no sub-fields. ! PAssert(f.numSubFields() == 0); // We need to notify the field that we are reducing that we are getting // ready to read. --- 102,110 ---- template T min(const Field &f) { ! // These versions only work with fields with one value per cell. ! PAssert(f.numMaterials() <= 1 && f.centering().size() <= 1); // We need to notify the field that we are reducing that we are getting // ready to read. *************** T min(const Field T max(const Field &f) { ! // These versions only work with fields with no sub-fields. ! PAssert(f.numSubFields() == 0); // We need to notify the field that we are reducing that we are getting // ready to read. --- 121,129 ---- template T max(const Field &f) { ! // These versions only work with fields with one value per cell. ! PAssert(f.numMaterials() <= 1 && f.centering().size() <= 1); // We need to notify the field that we are reducing that we are getting // ready to read. *************** T max(const Field bool all(const Field &f) { ! // These versions only work with fields with no sub-fields. ! PAssert(f.numSubFields() == 0); // We need to notify the field that we are reducing that we are getting // ready to read. --- 140,148 ---- template bool all(const Field &f) { ! // These versions only work with fields with one value per cell. ! PAssert(f.numMaterials() <= 1 && f.centering().size() <= 1); // We need to notify the field that we are reducing that we are getting // ready to read. *************** bool all(const Field bool any(const Field &f) { ! // These versions only work with fields with no sub-fields. ! PAssert(f.numSubFields() == 0); // We need to notify the field that we are reducing that we are getting // ready to read. --- 159,167 ---- template bool any(const Field &f) { ! // These versions only work with fields with one value per cell. ! PAssert(f.numMaterials() <= 1 && f.centering().size() <= 1); // We need to notify the field that we are reducing that we are getting // ready to read. *************** bool any(const Field T bitOr(const Field &f) { ! // These versions only work with fields with no sub-fields. ! PAssert(f.numSubFields() == 0); // We need to notify the field that we are reducing that we are getting // ready to read. --- 178,186 ---- template T bitOr(const Field &f) { ! // These versions only work with fields with one value per cell. ! PAssert(f.numMaterials() <= 1 && f.centering().size() <= 1); // We need to notify the field that we are reducing that we are getting // ready to read. *************** T bitOr(const Field T bitAnd(const Field &f) { ! // These versions only work with fields with no sub-fields. ! PAssert(f.numSubFields() == 0); // We need to notify the field that we are reducing that we are getting // ready to read. --- 197,205 ---- template T bitAnd(const Field &f) { ! // These versions only work with fields with one value per cell. ! PAssert(f.numMaterials() <= 1 && f.centering().size() <= 1); // We need to notify the field that we are reducing that we are getting // ready to read. Index: NearestNeighbors.h =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/Attic/NearestNeighbors.h,v retrieving revision 1.1.2.2 diff -c -p -r1.1.2.2 NearestNeighbors.h *** NearestNeighbors.h 2001/08/13 21:14:30 1.1.2.2 --- NearestNeighbors.h 2001/08/14 19:58:26 *************** private: *** 327,334 **** cellOffsetCoordinate[0] = -1; return 1; } ! else PInsist(0, "Out of range difference"); } // Specify a partial order for FieldOffsets to use when removing --- 327,336 ---- cellOffsetCoordinate[0] = -1; return 1; } ! else { PInsist(0, "Out of range difference"); + return 0; // Keep the compiler quiet. + } } // Specify a partial order for FieldOffsets to use when removing Index: FieldEngine/FieldEngine.NoGeometry.h =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/FieldEngine/FieldEngine.NoGeometry.h,v retrieving revision 1.5 diff -c -p -r1.5 FieldEngine.NoGeometry.h *** FieldEngine/FieldEngine.NoGeometry.h 2001/05/14 21:11:24 1.5 --- FieldEngine/FieldEngine.NoGeometry.h 2001/08/14 19:58:26 *************** struct NoGeometry; *** 79,85 **** //----------------------------------------------------------------------------- template ! class FieldEngine, T, EngineTag> { public: --- 79,86 ---- //----------------------------------------------------------------------------- template ! class FieldEngine, T, EngineTag> : ! public FieldEngineBase { public: *************** public: *** 217,222 **** --- 218,224 ---- //--------------------------------------------------------------------------- // Accessors and modifiers. + // FIXME: This function is deprecated. inline int numSubFields() const { return 0; *************** public: *** 294,300 **** PAssert(iSubField == 0); return engine_m.domain(); } - //--------------------------------------------------------------------------- // Make a distinct copy of this fieldEngineBase. --- 296,301 ---- Index: FieldEngine/FieldEngineBase.ExprEngine.h =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/FieldEngine/FieldEngineBase.ExprEngine.h,v retrieving revision 1.12 diff -c -p -r1.12 FieldEngineBase.ExprEngine.h *** FieldEngine/FieldEngineBase.ExprEngine.h 2001/06/22 22:49:35 1.12 --- FieldEngine/FieldEngineBase.ExprEngine.h 2001/08/14 19:58:26 *************** public: *** 237,242 **** --- 237,243 ---- //--------------------------------------------------------------------------- // Accessors and modifiers. + // FIXME: This function is deprecated. inline int numSubFields() const { return referenceField().numSubFields(); *************** public: *** 289,294 **** --- 290,313 ---- Domain_t totalDomain(int iSubField) const { return referenceField_m.totalDomain(iSubField); + } + + //--------------------------------------------------------------------------- + // Centering accessors. + + const Centering ¢ering() const + { + return referenceField_m.centering(); + } + + inline int centeringSize() const + { + return referenceField_m.centering().size(); + } + + inline int numMaterials() const + { + return referenceField_m.numMaterials(); } Index: FieldEngine/FieldEngineBase.h =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/FieldEngine/FieldEngineBase.h,v retrieving revision 1.13.2.4 diff -c -p -r1.13.2.4 FieldEngineBase.h *** FieldEngine/FieldEngineBase.h 2001/08/13 21:14:31 1.13.2.4 --- FieldEngine/FieldEngineBase.h 2001/08/14 19:58:26 *************** public: *** 177,190 **** for (int c = 0; c < centering.size(); ++ c) { Loc offset(1); ! offset -= centering.orientations()[c]; subField(c).data_m = new Data_t(offset, Pooma::NoInit()); } } else { Loc offset(1); ! offset -= centering.orientations()[0]; data_m = new Data_t(offset, Pooma::NoInit()); } } --- 177,190 ---- for (int c = 0; c < centering.size(); ++ c) { Loc offset(1); ! offset -= centering.orientation(c); subField(c).data_m = new Data_t(offset, Pooma::NoInit()); } } else { Loc offset(1); ! offset -= centering.orientation(0); data_m = new Data_t(offset, Pooma::NoInit()); } } *************** public: *** 212,225 **** for (int c = 0; c < centering.size(); ++ c) { Loc offset(1); ! offset -= centering.orientations()[c]; subField(m).subField(c).data_m = new Data_t(offset, layout); } } else { Loc offset(1); ! offset -= centering.orientations()[0]; subField(m).data_m = new Data_t(offset, layout); } } --- 212,225 ---- for (int c = 0; c < centering.size(); ++ c) { Loc offset(1); ! offset -= centering.orientation(c); subField(m).subField(c).data_m = new Data_t(offset, layout); } } else { Loc offset(1); ! offset -= centering.orientation(0); subField(m).data_m = new Data_t(offset, layout); } } *************** public: *** 232,245 **** for (int c = 0; c < centering.size(); ++ c) { Loc offset(1); ! offset -= centering.orientations()[c]; subField(c).data_m = new Data_t(offset, layout); } } else { Loc offset(1); ! offset -= centering.orientations()[0]; data_m = new Data_t(offset, layout); } } --- 232,245 ---- for (int c = 0; c < centering.size(); ++ c) { Loc offset(1); ! offset -= centering.orientation(c); subField(c).data_m = new Data_t(offset, layout); } } else { Loc offset(1); ! offset -= centering.orientation(0); data_m = new Data_t(offset, layout); } } *************** public: *** 265,271 **** physicalCellDomain_m(model.physicalCellDomain_m), guards_m(model.guards_m), centering_m(model.subFields_m[iSubField].centering_m), ! num_materials_m(model.num_materials_m) { PInsist(iSubField >= 0 && iSubField < model.numSubFields(), "Illegal attempt to extract a non-existent subfield."); --- 265,271 ---- physicalCellDomain_m(model.physicalCellDomain_m), guards_m(model.guards_m), centering_m(model.subFields_m[iSubField].centering_m), ! num_materials_m(model.subFields_m[iSubField].num_materials_m) { PInsist(iSubField >= 0 && iSubField < model.numSubFields(), "Illegal attempt to extract a non-existent subfield."); *************** public: *** 320,325 **** --- 320,326 ---- { int n = model.numSubFields(); s.centering_m = model.centering(); + num_materials_m = model.numMaterials(); if (n == 0) { s.physicalCellDomain_m = shrinkRight(d - d.firsts(), *************** public: *** 329,335 **** else { s.physicalCellDomain_m = d - d.firsts(); - num_materials_m = model.numMaterials(); s.addSubFields(n); for (int i = 0; i < n; i++) initialize(s.subFields_m[i], model.subField(i), --- 330,335 ---- *************** public: *** 343,348 **** --- 343,349 ---- { int n = model.numSubFields(); s.centering_m = model.centering(); + num_materials_m = model.numMaterials(); if (n == 0) { s.physicalCellDomain_m = *************** public: *** 352,358 **** else { s.physicalCellDomain_m = i.domain() - i.domain().firsts(); - num_materials_m = model.numMaterials(); s.addSubFields(n); for (int j = 0; j < n; j++) initialize(s.subFields_m[j], model.subField(j), --- 353,358 ---- *************** public: *** 366,372 **** const EngineView &ev) { typedef typename FieldEngineBase::Engine_t EngIn_t; ! int n = model.numSubFields(); s.centering_m = model.centering(); if (n == 0) { --- 366,373 ---- const EngineView &ev) { typedef typename FieldEngineBase::Engine_t EngIn_t; ! const int n = model.numSubFields(); ! num_materials_m = model.numMaterials(); s.centering_m = model.centering(); if (n == 0) { *************** public: *** 381,387 **** { s.physicalCellDomain_m = model.physicalCellDomain(); s.guards_m = model.guardLayers(); - num_materials_m = model.numMaterials(); s.addSubFields(n); for (int i = 0; i < n; i++) initialize(s.subFields_m[i], model.subField(i), ev); --- 382,387 ---- *************** public: *** 393,398 **** --- 393,399 ---- const FieldEngineBase &model, const EnginePatch &p) { PAssert(model.numSubFields() == 0); + num_materials_m = model.numMaterials(); s.initialize(model.offsets(), engineFunctor(model.engine(), p)); s.physicalCellDomain_m = shrinkRight(data_m->engine().domain(), 1); } *************** public: *** 402,409 **** const FieldEngineBase &model, const ComponentWrapper &c) { ! int n = model.numSubFields(); s.centering_m = model.centering(); if (n == 0) { s.physicalCellDomain_m = model.physicalCellDomain(); --- 403,411 ---- const FieldEngineBase &model, const ComponentWrapper &c) { ! const int n = model.numSubFields(); s.centering_m = model.centering(); + num_materials_m = model.numMaterials(); if (n == 0) { s.physicalCellDomain_m = model.physicalCellDomain(); *************** public: *** 416,422 **** { s.physicalCellDomain_m = model.physicalCellDomain(); s.guards_m = model.guardLayers(); - num_materials_m = model.numMaterials(); s.addSubFields(n); for (int i = 0; i < n; i++) initialize(s.subFields_m[i], model.subField(i), c); --- 418,423 ---- *************** public: *** 426,432 **** void initialize(This_t &s, const This_t &model, const Pooma::Updaters::DontCopyUpdaters &d) { ! int n = model.numSubFields(); s.physicalCellDomain_m = model.physicalCellDomain(); s.guards_m = model.guardLayers(); s.centering_m = model.centering(); --- 427,434 ---- void initialize(This_t &s, const This_t &model, const Pooma::Updaters::DontCopyUpdaters &d) { ! const int n = model.numSubFields(); ! num_materials_m = model.numMaterials(); s.physicalCellDomain_m = model.physicalCellDomain(); s.guards_m = model.guardLayers(); s.centering_m = model.centering(); *************** public: *** 436,442 **** } else { - num_materials_m = model.numMaterials(); s.addSubFields(n); for (int i = 0; i < n; i++) initialize(s.subFields_m[i], model.subField(i), d); --- 438,443 ---- *************** public: *** 466,471 **** --- 467,473 ---- } } + // FIXME: This function is deprecated. inline int numSubFields() const { return subFields_m.size(); *************** public: *** 521,531 **** return guards_m; } - inline int centeringSize() const - { - return centering_m.size(); - } - inline int numMaterials() const { return num_materials_m; --- 523,528 ---- *************** public: *** 573,578 **** --- 570,580 ---- { return centering_m; } + + inline int centeringSize() const + { + return centering_m.size(); + } //--------------------------------------------------------------------------- // Make a distinct copy of this fieldEngineBase. Index: Mesh/UniformRectilinearMesh.h =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/Mesh/Attic/UniformRectilinearMesh.h,v retrieving revision 1.1.2.2 diff -c -p -r1.1.2.2 UniformRectilinearMesh.h *** Mesh/UniformRectilinearMesh.h 2001/08/08 15:17:19 1.1.2.2 --- Mesh/UniformRectilinearMesh.h 2001/08/14 19:58:26 *************** public: *** 289,295 **** { for (int i = 0; i < Dim; i++) origin_m(i) += spacings_m(i) * ! (c.positions()[0] - m.physicalCellDomain[i].first()); } PointType_t operator()(int i0) const --- 289,295 ---- { for (int i = 0; i < Dim; i++) origin_m(i) += spacings_m(i) * ! (c.position(0) - m.physicalCellDomain[i].first()); } PointType_t operator()(int i0) const Index: Updater/ConstantFaceBC.h =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/Updater/ConstantFaceBC.h,v retrieving revision 1.4 diff -c -p -r1.4 ConstantFaceBC.h *** Updater/ConstantFaceBC.h 2001/04/27 22:55:55 1.4 --- Updater/ConstantFaceBC.h 2001/08/14 19:58:26 *************** public: *** 155,163 **** : Base_t(s, bc), domain_m(Pooma::NoInit()) { ! // This only makes sense if the subject has no sub-fields. ! PAssert(subject().numSubFields() == 0); // Set up the domain. --- 155,163 ---- : Base_t(s, bc), domain_m(Pooma::NoInit()) { ! // These versions only work with fields with one value per cell. ! PAssert(subject().numMaterials() <= 1 && subject().centering().size() <= 1); // Set up the domain. Index: Updater/PeriodicFaceBC.cpp =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/Updater/PeriodicFaceBC.cpp,v retrieving revision 1.1 diff -c -p -r1.1 PeriodicFaceBC.cpp *** Updater/PeriodicFaceBC.cpp 2000/10/24 15:11:02 1.1 --- Updater/PeriodicFaceBC.cpp 2001/08/14 19:58:26 *************** Updater(const Subject_t &s, const Period *** 51,128 **** : Base_t(s, bc), domain_m(Pooma::NoInit()) { ! // This only makes sense if the subject has no sub-fields. ! PAssert(subject().numSubFields() == 0); ! // Set up the domain. ! domain_m = subject().totalDomain(); ! // Get the direction. ! int d = bc.face() / 2; ! int adjust; ! bool VertFace = subject().fieldEngine().offsets()[d] == 1; ! if (VertFace) { ! adjust = 1; ! } ! else { ! adjust = 0; ! } ! ! // Select the high or low face: ! ! if (bc.face() & 1) { ! ! // High face. ! ! // Get the number of guard layers in the upper direction. ! int nGuards = subject().fieldEngine().guardLayers().upper(d); ! ! // For Vert centering, because boundary is at last physical vertex, ! // which is identified with the first physical vertex, destination ! // domain is extended to includes last physical vertex: ! domain_m[d] = ! Interval<1>(domain_m[d].max() - (nGuards - 1 + adjust), ! domain_m[d].max()); ! ! // N.B.: only do this here on the High face; don't do it again down ! // below on the low face. This follows the convention of r1. ! ! // Source domain is just the destination domain offset by the ! // periodicity length (number of *cells*): ! srcDomain_m[d] = ! Interval<1>(domain_m[d].min() - ! (subject().physicalDomain()[d].length() - adjust), ! domain_m[d].max() - ! (subject().physicalDomain()[d].length() - adjust)); ! ! } else { ! ! // Low face. ! ! // Get the number of guard layers in the lower direction. ! int nGuards = subject().fieldEngine().guardLayers().lower(d); ! ! // For Vert centering, because boundary is at first physical vertex, ! // which ! // is identified with the last physical vertex, destination domain is ! // extended to includes first physical vertex. However, *don't* ! // include the first physical vertex here on the Low face; see notes ! // above regarding the High face (following r1 convention): ! domain_m[d] = ! Interval<1>( ! domain_m[d].min() + (nGuards - 1)); ! ! // Source domain is just the destination domain offset by the ! // periodicity length (number of *cells*): ! srcDomain_m[d] = ! Interval<1>(domain_m[d].min() + ! (subject().physicalDomain()[d].length() - adjust), ! domain_m[d].max() + ! (subject().physicalDomain()[d].length() - adjust)); ! } } --- 51,128 ---- : Base_t(s, bc), domain_m(Pooma::NoInit()) { ! // These versions only work with fields with one value per cell. ! PAssert(f.numMaterials() <= 1 && f.centering().size() <= 1); ! // Set up the domain. ! domain_m = subject().totalDomain(); ! // Get the direction. ! int d = bc.face() / 2; ! int adjust; ! bool VertFace = subject().fieldEngine().offsets()[d] == 1; ! if (VertFace) { ! adjust = 1; ! } ! else { ! adjust = 0; ! } ! ! // Select the high or low face: ! ! if (bc.face() & 1) { ! ! // High face. ! ! // Get the number of guard layers in the upper direction. ! int nGuards = subject().fieldEngine().guardLayers().upper(d); ! ! // For Vert centering, because boundary is at last physical vertex, ! // which is identified with the first physical vertex, destination ! // domain is extended to includes last physical vertex: ! domain_m[d] = ! Interval<1>(domain_m[d].max() - (nGuards - 1 + adjust), ! domain_m[d].max()); ! ! // N.B.: only do this here on the High face; don't do it again down ! // below on the low face. This follows the convention of r1. ! ! // Source domain is just the destination domain offset by the ! // periodicity length (number of *cells*): ! srcDomain_m[d] = ! Interval<1>(domain_m[d].min() - ! (subject().physicalDomain()[d].length() - adjust), ! domain_m[d].max() - ! (subject().physicalDomain()[d].length() - adjust)); ! ! } else { ! ! // Low face. ! ! // Get the number of guard layers in the lower direction. ! int nGuards = subject().fieldEngine().guardLayers().lower(d); ! ! // For Vert centering, because boundary is at first physical vertex, ! // which ! // is identified with the last physical vertex, destination domain is ! // extended to includes first physical vertex. However, *don't* ! // include the first physical vertex here on the Low face; see notes ! // above regarding the High face (following r1 convention): ! domain_m[d] = ! Interval<1>( ! domain_m[d].min() + (nGuards - 1)); ! ! // Source domain is just the destination domain offset by the ! // periodicity length (number of *cells*): ! srcDomain_m[d] = ! Interval<1>(domain_m[d].min() + ! (subject().physicalDomain()[d].length() - adjust), ! domain_m[d].max() + ! (subject().physicalDomain()[d].length() - adjust)); ! } } Index: Updater/PosReflectFaceBC.cpp =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/Updater/PosReflectFaceBC.cpp,v retrieving revision 1.1 diff -c -p -r1.1 PosReflectFaceBC.cpp *** Updater/PosReflectFaceBC.cpp 2000/10/24 15:11:02 1.1 --- Updater/PosReflectFaceBC.cpp 2001/08/14 19:58:26 *************** Updater(const Subject_t &s, const PosRef *** 42,123 **** : Base_t(s, bc), domain_m(Pooma::NoInit()) { ! // This only makes sense if the subject has no sub-fields. ! PAssert(subject().numSubFields() == 0); ! // Set up the domain. ! domain_m = subject().totalDomain(); ! // Note: a convertor from Interval Range would be handy ! // here: ! // srcRange is used to get data to copy from ! for (int dd = 0; dd < Subject_t::dimensions; ++dd) { ! srcRange_m[dd] = ! Range<1>(domain_m[dd].min(), domain_m[dd].max(), 1); ! } ! // range that needs to be zeroed when enforceZeroBoundary_m is true ! vertFaceDomain_m = subject().totalDomain(); ! // Get the direction. ! int d = bc.face() / 2; ! // The other directions span the subject's total domain. ! // Therefore, we just chop out the guard layers, taking care to ! // handle the case where we are enforcing a zero boundary ! // (appropriate only for vert-centering). ! int adjust; ! bool VertFace = subject().fieldEngine().offsets()[d] == 1; ! if (VertFace) { ! adjust = 1; ! } ! else { ! adjust = 0; ! } ! // Select the high or low face. ! if (bc.face() & 1) { ! // High face. ! // Get the number of guard layers in the upper direction. ! int nGuards = subject().fieldEngine().guardLayers().upper(d); ! if (bc.enforceZeroBoundary() && VertFace) { ! vertFaceDomain_m[d] ! = Interval<1>(subject().physicalDomain()[d].max(), ! subject().physicalDomain()[d].max()); ! } ! srcRange_m[d] = ! Range<1>(subject().physicalDomain()[d].max() - adjust, ! subject().physicalDomain()[d].max() - adjust - ! (nGuards - 1), ! -1); ! // Adjust the domain. ! domain_m[d] = Interval<1>(domain_m[d].max() - (nGuards - 1), ! domain_m[d].max()); ! } ! else { ! // Low face. ! // Get the number of guard layers in the lower direction. ! int nGuards = subject().fieldEngine().guardLayers().lower(d); ! // other directions span the subject's total domain. ! // Therefore, we ! // just chop out the guard layers, taking care to handle the case ! // where we are enforcing a zero boundary (appropriate only for ! // vert-centering). ! if (bc.enforceZeroBoundary() && VertFace) { ! vertFaceDomain_m[d] = ! Interval<1>(subject().physicalDomain()[d].min(), ! subject().physicalDomain()[d].min()); ! } ! // Adjust the domains. ! srcRange_m[d] = ! Range<1>(subject().physicalDomain()[d].min() + adjust + ! (nGuards - 1), ! subject().physicalDomain()[d].min() + adjust, -1); ! domain_m[d] = Interval<1>(domain_m[d].min(), ! domain_m[d].min() + (nGuards - 1)); ! } } //----------------------------------------------------------------------------- --- 42,123 ---- : Base_t(s, bc), domain_m(Pooma::NoInit()) { ! // These versions only work with fields with one value per cell. ! PAssert(subject().numMaterials() <= 1 && subject().centering().size() <= 1); ! // Set up the domain. ! domain_m = subject().totalDomain(); ! // Note: a convertor from Interval Range would be handy ! // here: ! // srcRange is used to get data to copy from ! for (int dd = 0; dd < Subject_t::dimensions; ++dd) { ! srcRange_m[dd] = ! Range<1>(domain_m[dd].min(), domain_m[dd].max(), 1); ! } ! // range that needs to be zeroed when enforceZeroBoundary_m is true ! vertFaceDomain_m = subject().totalDomain(); ! // Get the direction. ! int d = bc.face() / 2; ! // The other directions span the subject's total domain. ! // Therefore, we just chop out the guard layers, taking care to ! // handle the case where we are enforcing a zero boundary ! // (appropriate only for vert-centering). ! int adjust; ! bool VertFace = subject().fieldEngine().offsets()[d] == 1; ! if (VertFace) { ! adjust = 1; ! } ! else { ! adjust = 0; ! } ! // Select the high or low face. ! if (bc.face() & 1) { ! // High face. ! // Get the number of guard layers in the upper direction. ! int nGuards = subject().fieldEngine().guardLayers().upper(d); ! if (bc.enforceZeroBoundary() && VertFace) { ! vertFaceDomain_m[d] ! = Interval<1>(subject().physicalDomain()[d].max(), ! subject().physicalDomain()[d].max()); ! } ! srcRange_m[d] = ! Range<1>(subject().physicalDomain()[d].max() - adjust, ! subject().physicalDomain()[d].max() - adjust - ! (nGuards - 1), ! -1); ! // Adjust the domain. ! domain_m[d] = Interval<1>(domain_m[d].max() - (nGuards - 1), ! domain_m[d].max()); ! } ! else { ! // Low face. ! // Get the number of guard layers in the lower direction. ! int nGuards = subject().fieldEngine().guardLayers().lower(d); ! // other directions span the subject's total domain. ! // Therefore, we ! // just chop out the guard layers, taking care to handle the case ! // where we are enforcing a zero boundary (appropriate only for ! // vert-centering). ! if (bc.enforceZeroBoundary() && VertFace) { ! vertFaceDomain_m[d] = ! Interval<1>(subject().physicalDomain()[d].min(), ! subject().physicalDomain()[d].min()); ! } ! // Adjust the domains. ! srcRange_m[d] = ! Range<1>(subject().physicalDomain()[d].min() + adjust + ! (nGuards - 1), ! subject().physicalDomain()[d].min() + adjust, -1); ! domain_m[d] = Interval<1>(domain_m[d].min(), ! domain_m[d].min() + (nGuards - 1)); ! } } //----------------------------------------------------------------------------- Index: tests/NearestNeighbors.cpp =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/tests/Attic/NearestNeighbors.cpp,v retrieving revision 1.1.2.1 diff -c -p -r1.1.2.1 NearestNeighbors.cpp *** tests/NearestNeighbors.cpp 2001/08/02 22:36:56 1.1.2.1 --- tests/NearestNeighbors.cpp 2001/08/14 19:58:27 *************** checkFieldOffset(Pooma::Tester &tester, *** 75,81 **** const FieldOffset &offset, const bool offsetPresent = true) { ! PInsist(listNum >= 0 && listNum < nnSize, "Incorrect std::vector index."); return --- 75,81 ---- const FieldOffset &offset, const bool offsetPresent = true) { ! PInsist(listNum < nnSize, "Incorrect std::vector index."); return *************** manhattanDistance(const Centering & *** 111,123 **** const int outputIndex) { // Compute the actual input position. ! Loc cellOffset = offset.cellOffset(); ! Vector input = ! inputCentering.positions()[offset.subFieldNumber()]; ! for (int index = Dim-1; index >= 0; --index) ! input(index) += cellOffset[index].first(); ! ! return manhattanDistance(outputCentering.positions()[outputIndex] - input); } // Check that the distance between the input and output values are the --- 111,118 ---- const int outputIndex) { // Compute the actual input position. ! return manhattanDistance(outputCentering.position(outputIndex) - ! inputPosition(inputCentering, offset)); } // Check that the distance between the input and output values are the Index: tests/makefile =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/tests/makefile,v retrieving revision 1.11.2.7 diff -c -p -r1.11.2.7 makefile *** tests/makefile 2001/08/13 21:14:31 1.11.2.7 --- tests/makefile 2001/08/14 19:58:27 *************** run: run_tests *** 47,53 **** run_tests: tests $(ODIR)/BasicTest1 $(TSTOPTS) 1>BasicTest1.out 2>&1 $(ODIR)/BasicTest2 $(TSTOPTS) 1>BasicTest2.out 2>&1 - $(ODIR)/MeshTest1 $(TSTOPTS) 1>MeshTest1.out 2>&1 $(ODIR)/Centerings $(TSTOPTS) 1>Centerings.out 2>&1 $(ODIR)/ExpressionTest $(TSTOPTS) 1>ExpressionTest.out 2>&1 $(ODIR)/FieldOffset $(TSTOPTS) 1>FieldOffset.out 2>&1 --- 47,52 ---- *************** run_tests: tests *** 55,72 **** $(ODIR)/FieldTour1 $(TSTOPTS) 1>FieldTour1.out 2>&1 $(ODIR)/FieldTour2 $(TSTOPTS) 1>FieldTour2.out 2>&1 $(ODIR)/FieldTour3 $(TSTOPTS) 1>FieldTour3.out 2>&1 $(ODIR)/NearestNeighbors $(TSTOPTS) 1>NearestNeighbors.out 2>&1 $(ODIR)/ScalarCode $(TSTOPTS) 1>ScalarCode.out 2>&1 $(ODIR)/StencilTests $(TSTOPTS) 1>StencilTests.out 2>&1 $(ODIR)/VectorTest $(TSTOPTS) 1>VectorTest.out 2>&1 $(ODIR)/WhereTest $(TSTOPTS) 1>WhereTest.out 2>&1 ! field_tests:: $(ODIR)/BasicTest1 $(ODIR)/BasicTest2 $(ODIR)/MeshTest1 \ $(ODIR)/Centerings $(ODIR)/ExpressionTest \ $(ODIR)/FieldOffset $(ODIR)/FieldReductions \ $(ODIR)/FieldTour1 $(ODIR)/FieldTour2 \ ! $(ODIR)/FieldTour3 \ ! $(ODIR)/NearestNeighbors \ $(ODIR)/ScalarCode $(ODIR)/StencilTests \ $(ODIR)/VectorTest $(ODIR)/WhereTest --- 54,73 ---- $(ODIR)/FieldTour1 $(TSTOPTS) 1>FieldTour1.out 2>&1 $(ODIR)/FieldTour2 $(TSTOPTS) 1>FieldTour2.out 2>&1 $(ODIR)/FieldTour3 $(TSTOPTS) 1>FieldTour3.out 2>&1 + $(ODIR)/Gradient $(TSTOPTS) 1>Gradient.out 2>&1 + $(ODIR)/MeshTest1 $(TSTOPTS) 1>MeshTest1.out 2>&1 $(ODIR)/NearestNeighbors $(TSTOPTS) 1>NearestNeighbors.out 2>&1 $(ODIR)/ScalarCode $(TSTOPTS) 1>ScalarCode.out 2>&1 $(ODIR)/StencilTests $(TSTOPTS) 1>StencilTests.out 2>&1 $(ODIR)/VectorTest $(TSTOPTS) 1>VectorTest.out 2>&1 $(ODIR)/WhereTest $(TSTOPTS) 1>WhereTest.out 2>&1 ! field_tests:: $(ODIR)/BasicTest1 $(ODIR)/BasicTest2 \ $(ODIR)/Centerings $(ODIR)/ExpressionTest \ $(ODIR)/FieldOffset $(ODIR)/FieldReductions \ $(ODIR)/FieldTour1 $(ODIR)/FieldTour2 \ ! $(ODIR)/FieldTour3 $(ODIR)/Gradient\ ! $(ODIR)/MeshTest1 $(ODIR)/NearestNeighbors \ $(ODIR)/ScalarCode $(ODIR)/StencilTests \ $(ODIR)/VectorTest $(ODIR)/WhereTest From oldham at codesourcery.com Wed Aug 15 03:42:46 2001 From: oldham at codesourcery.com (Jeffrey Oldham) Date: Tue, 14 Aug 2001 20:42:46 -0700 Subject: Speeding Pooma Code on a Branch? Message-ID: <200108150342.UAA32255@oz.codesourcery.com> Soon some Pooma developers will turn to reducing Pooma's running time. Should we modify the code on a separate branch, e.g., the running_time branch, so that the Blanca people's use of the mainline is not affected? Hopefully next week, the newfield_revision branch will be merged into whichever branch we choose. Thanks, Jeffrey D. Oldham oldham at codesourcery.com From oldham at codesourcery.com Wed Aug 15 03:46:44 2001 From: oldham at codesourcery.com (Jeffrey Oldham) Date: Tue, 14 Aug 2001 20:46:44 -0700 Subject: Plan for Reducing Pooma's Running Time Message-ID: <200108150346.UAA32266@oz.codesourcery.com> We soon will have several geographically disparate people working on reducing Pooma's running time. Having a task list would be useful to ensure we reach our goal of producing fast code. First, I outline a strategy and then a list of tasks. Goal: Make Pooma code run faster than corresponding ForTran or C code. Measurements: Measurement is our most important task. We should revise Pooma code only if it, in practice, reduces running time. To permit comparisons between executions of different programs, we can compute the abstraction ratio for using data-parallel or Pooma2 abstractions. The abstraction ratio is the ratio of a program's running time to the corresponding C program's running time. We want this ratio to be at most one. We need to resolve timing granularity problems and which time measurements to make, e.g., wall-clock or CPU time. Infrastructure: We should establish daily builds and benchmark runs to check that running times do not increase while we try to reduce running times. Running times on both Irix and Linux is desirable. We'll use QMTest to perform the testing. Question: Should we post these reports on a daily basis? We should use KCC. Some preliminary performance indicates that KCC's and gcc's performances differ. Tools to profile the code include Linux's gprof (instructions available in info pages and http://sources.redhat.com/binutils/docs-2.10/gprof.html) and Irix's ssrun(1) and prof(1). Question: Are there other profiling tools? Work: Scott Haney suggests first speeding Array execution since (New)Fields use Arrays. A good initial step would be checking that the KCC optimizer produces code similar to C code without Pooma abstraction overheads. First, we can compare C-style arrays with Brick Array engines on uniprocessor machines. Then, we work with multipatch Array engines, trying to reduce the overhead of having multiple patches. Trying various patch sizes on a uniprocessor machine will demonstrate the overhead of having multipatches. We'll defer threaded and multi-processor execution to later. Stephen will soon post a list of Array benchmarks, what they test, and what they do not test. We can write additional programs to fill any deficiencies in our testing. Each individual researcher can speed a benchmark's execution. Work on the NewField should be delayed until Stephen Smith and I merge our work into the mainline. Currently, there is one benchmark program benchmarks/Doof2d that use NewField.h. We also will have the Lee et al. statigraphic flow code. Are these sufficient for testing? If not, should we write more test cases? Will we want to finish the Caramana et al. hydrodynamics program? Question: Who besides Jeffrey has access to a multi-processor computer with more than a handful of processors? Question: Do we need to check for memory leaks? Bluemountain has purify, which should reveal leaks. Perhaps we can modify the QMTest scripts to ease checking. Procedure for Modifying Pooma Code: Even though we'll probably work on a separate development branch, we need to ensure that the Pooma code compiles at all times to permit multiple programmers to work on the same code. Before committing a code change, 1. Make sure the Pooma library compiles with the change. Also check that associated executables still run. 2. Obtain patch approval from at least one other person. 3. Commit the patch. 4. Send email to pooma-dev at pooma.codesourcery.com, listing a. the changes and an explanation, b. the test platform, and c. the patch approver. To Do List: o Complete this list. o Add this list in the Pooma CVS tree for easy sharing and modification. o Describe the existing benchmarks. Stephen o Determine what execution tasks are not covered by existing code. Stephen o Determine interesting benchmarks using Arrays. Stephen recommends starting with benchmarks/Doof2dUMP. Gaby? o Establish nightly Pooma builds for Linux and Irix, producing summary reports. Jeffrey o Ensure Pooma compiles with the threads package. Jim? Thanks, Jeffrey D. Oldham oldham at codesourcery.com From oldham at codesourcery.com Wed Aug 15 18:10:02 2001 From: oldham at codesourcery.com (Jeffrey Oldham) Date: Wed, 15 Aug 2001 11:10:02 -0700 Subject: [newfield_revision Patch] Revise nearestNeighbors Message-ID: <20010815111002.B9560@codesourcery.com> The statigraphic flow code demonstrated the need to generalize nearest neighbor computations. These changes permit computing nearest neighbors given a centering, i.e., all values in one cell; a FieldOffset, i.e., one value; and a FieldOffsetList, i.e., a set of values. Applied to newfield_revision branch. 2001-08-15 Jeffrey D. Oldham * FieldOffset.h (FieldOffsetList::FieldOffsetList): Add constructor converting from a std::vector to a FieldOffsetList. * NearestNeighbors.h (NearestNeighborClass::NearestNeighborClass): Changed to an empty constructor. (NearestNeighborClass::operator()()): Removed. (NearestNeighborClass::operator()(Centering,Centering)): New function. (NearestNeighborClass::operator()(Centering,FieldOffset,Centering)): New function. (NearestNeighborClass::operator()(Centering,FieldOffsetList,Centering)): New function. (NearestNeighborClass::nearestNeighbors): New function formed from previous operator()(). (manhattanDistance): Initialize variable. (NearestNeighborClass): Remove centering data members. (nearestNeighbors(Centering,Centering)): Revise to use operator()(Centering,Centering). (nearestNeighbors(Centering,Centering,bool)): Revise to use operator()(Centering,Centering). (nearestNeighbors(Centering,FieldOffsetList,Centering)): New function. (nearestNeighbors(Centering,FieldOffsetList,Centering,bool)): New function. (nearestNeighbors(Centering,FieldOffset,Centering)): New function. (nearestNeighbors(Centering,FieldOffset,Centering,bool)): New function. * tests/NearestNeighbors.cpp (main): Revise to test new functions. Applied to newfield_revision branch Approved by Stephen Smith Tested on sequential Linux using gcc 3.0.1 by compiling Pooma library and NewField tests Thanks, Jeffrey D. Oldham oldham at codesourcery.com -------------- next part -------------- ? LINUXgcc ? include.mk ? FieldCentering.h.patch ? 09Aug.16.2.ChangeLog ? 13Aug.11.8.patch ? replicate.patch.save ? 09Aug.16.2.patch ? differences-2001Aug14 ? 13Aug.11.8.ChangeLog ? 14Aug.14.9.patch ? 13Aug.14.4.patch ? 13Aug.14.4.ChangeLog ? replicate.patch.14Aug.14.8 ? 14Aug.14.9.ChangeLog ? 14Aug.15.0.patch ? tests/LINUXgcc ? tests/BasicTest1.out ? tests/BasicTest2.out ? tests/FieldReductions2.cpp ? tests/NearestNeighbors3.cpp ? tests/Gradient.out ? tests/Centerings.out ? tests/ExpressionTest.out ? tests/FieldOffset.out ? tests/FieldReductions.out ? tests/FieldTour1.out ? tests/FieldTour2.out ? tests/FieldTour3.out ? tests/MeshTest1.out ? tests/NearestNeighbors.out ? tests/ScalarCode.out ? tests/StencilTests.out ? tests/VectorTest.out ? tests/Gradient.cpp ? tests/WhereTest.out ? tests/Gradient.cpp.13Aug.13.2.patch ? tests/Gradient.cpp.patch ? tests/Gradient.cpp.ChangeLog Index: FieldOffset.h =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/Attic/FieldOffset.h,v retrieving revision 1.1.2.3 diff -c -p -r1.1.2.3 FieldOffset.h *** FieldOffset.h 2001/08/10 17:40:52 1.1.2.3 --- FieldOffset.h 2001/08/14 22:06:18 *************** public: *** 285,290 **** --- 285,297 ---- v_m.reserve(sz); } + // Construct from a vector. + + FieldOffsetList(const std::vector > &v) { + v_m.resize(v.size()); + std::copy(v.begin(), v.end(), v_m.begin()); + } + // Copy a vector's entries to this FieldOffsetList. FieldOffsetList &operator=(const std::vector > &v) Index: NearestNeighbors.h =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/Attic/NearestNeighbors.h,v retrieving revision 1.1.2.3 diff -c -p -r1.1.2.3 NearestNeighbors.h *** NearestNeighbors.h 2001/08/14 20:24:17 1.1.2.3 --- NearestNeighbors.h 2001/08/14 22:06:18 *************** *** 40,46 **** // Overview: // // nearestNeighbors ! // - yields FieldOffsetLists corresponding to the specified centerings // NearestNeighborClass // - the class performing the work //----------------------------------------------------------------------------- --- 40,46 ---- // Overview: // // nearestNeighbors ! // - yields FieldOffsets corresponding to the given parameters // NearestNeighborClass // - the class performing the work //----------------------------------------------------------------------------- *************** public: *** 107,218 **** typedef std::vector MinimumSet; ! NearestNeighborClass(const Center &inputCentering, ! const Center &outputCentering) ! : inputCentering_m(inputCentering), ! outputCentering_m(outputCentering) { ! PInsist(inputCentering_m.positions().size() > 0, "The input centering must be non-empty."); - } - inline - Answer_t operator()() - { Answer_t answer; ! answer.resize(outputCentering_m.size()); ! Positions inputPositions = inputCentering_m.positions(); ! Positions outputPositions = outputCentering_m.positions(); ! Position positionDifference; ! double minimumDistance; // Determine nearest neighbors for each output value. for (Answer_t::size_type outputIndex = 0; ! outputIndex < outputCentering_m.size(); ! ++outputIndex) ! { ! // Compute all input values in the first shell. ! ! MinimumSet minimumSet; // all input values in first shell ! const Position outputValue = outputPositions[outputIndex]; ! typename Positions::size_type inputIndex = 0; ! ! // Use the first input value to start computing the minimum. ! ! positionDifference = inputPositions[inputIndex] - outputValue; ! minimumDistance = ! (IntraCellOnly ? ! manhattanDistance(positionDifference) : ! manhattanDistance(positionDifference)); ! minimumSet.push_back(std::make_pair(inputIndex, positionDifference)); ! ! // Compute the minimum over the rest of the input values. ! ! for (++inputIndex; ! inputIndex < inputPositions.size(); ! ++inputIndex) { ! positionDifference = inputPositions[inputIndex] - outputValue; ! const double distance = ! (IntraCellOnly ? ! manhattanDistance(positionDifference) : ! manhattanDistance(positionDifference)); ! if (distance < minimumDistance + epsilon) { ! if (distance < minimumDistance) { ! minimumSet.clear(); ! minimumDistance = distance; ! } ! minimumSet.push_back(std::make_pair(inputIndex, ! positionDifference)); ! } ! } ! // Convert the minimum set to a set of FieldOffsets. ! // minimumSet has all the minimum distance locations. ! FieldOffset_vt answerHolder; ! if (IntraCellOnly) { ! for (MinimumSet::size_type minIndex = 0; ! minIndex < minimumSet.size(); ! ++minIndex) ! answerHolder.push_back(FieldOffset_t(Loc(0), ! minimumSet[minIndex].first)); ! } ! else { ! FieldOffset_vt partialAnswer; ! for (MinimumSet::size_type minIndex = 0; ! minIndex < minimumSet.size(); ! ++minIndex) ! { ! // Compute the cell offsets, appending to the set of answers. ! ! partialAnswer = computeCellOffsets(minimumSet[minIndex].first, ! minimumSet[minIndex].second); ! answerHolder.insert(answerHolder.end(), ! partialAnswer.begin(), partialAnswer.end()); ! } ! ! // Remove all duplicates from the answer set. ! ! std::sort(answerHolder.begin(), answerHolder.end(), ! CompareFieldOffset()); ! answerHolder.erase(std::unique(answerHolder.begin(), ! answerHolder.end(), ! EqualFieldOffset()), ! answerHolder.end()); ! } ! // Store the answer. ! answer[outputIndex] = answerHolder; ! } ! return answer; } private: // Given a difference between two positions in logical coordinate // space, return the Manhattan norm distance taking into account // that input values are repeated in every grid cell. --- 107,277 ---- typedef std::vector MinimumSet; ! // The constructor performs no work. The function operators do all ! // the work. ! ! NearestNeighborClass() {} ! ! ! // Return nearest neighbors for all value in an output centering. ! ! inline Answer_t ! operator()(const Center &inputCentering, const Center &outputCentering) { ! PInsist(inputCentering.size() > 0, "The input centering must be non-empty."); Answer_t answer; ! answer.resize(outputCentering.size()); ! const Positions inputPositions = inputCentering.positions(); ! const Positions outputPositions = outputCentering.positions(); // Determine nearest neighbors for each output value. for (Answer_t::size_type outputIndex = 0; ! outputIndex < outputCentering.size(); ! ++outputIndex) { ! answer[outputIndex] = nearestNeighbors(inputPositions, ! outputPositions[outputIndex]); ! std::cout << answer[outputIndex] << std::endl; // TMP ! } ! return answer; ! } ! // Return the nearest neighbors for one output position, specified ! // by a FieldOffset. ! inline FieldOffsetList_t ! operator()(const Center &inputCentering, ! const FieldOffset_t &fieldOffset, ! const Center &outputCentering) ! { ! PInsist(inputCentering.size() > 0, ! "The input centering must be non-empty."); ! PInsist(fieldOffset.subFieldNumber() < outputCentering.size(), ! "The field offset must correspond to the output centering."); ! return nearestNeighbors(inputCentering.positions(), ! outputCentering.position(fieldOffset.subFieldNumber())); ! } ! ! // Return the nearest neighbors for multiple output positions, specified ! // by a FieldOffsetList. ! ! inline FieldOffsetList_t ! operator()(const Center &inputCentering, ! const FieldOffsetList_t &fieldOffsetList, ! const Center &outputCentering) ! { ! PInsist(inputCentering.size() > 0, ! "The input centering must be non-empty."); ! ! Answer_t answer; ! answer.resize(fieldOffsetList.size()); ! const Positions inputPositions = inputCentering.positions(); ! ! // Determine nearest neighbors for each field offset. ! ! for (FieldOffsetList_t::size_type folIndex = 0; ! folIndex < outputCentering.size(); ! ++folIndex) { ! PInsist(fieldOffsetList[folIndex].subFieldNumber() < outputCentering.size(), ! "The field offset must correspond to the output centering."); ! answer[folIndex] = ! nearestNeighbors(inputPositions, ! outputCentering.position(fieldOffsetList[folIndex].subFieldNumber())); ! } ! return answer; } + private: + // Given an input centering and a position in logical + // coordinate space, return a FieldOffsetList of the nearest + // neighbors according to Manhattan distance. + + inline FieldOffsetList_t + nearestNeighbors(const Positions &inputPositions, + const Position outputValue) + { + + // Compute all input values in the first shell. + + MinimumSet minimumSet; // all input values in first shell + typename Positions::size_type inputIndex = 0; + + // Use the first input value to start computing the minimum. + + Position positionDifference = inputPositions[inputIndex] - outputValue; + double minimumDistance = + (IntraCellOnly ? + manhattanDistance(positionDifference) : + manhattanDistance(positionDifference)); + minimumSet.push_back(std::make_pair(inputIndex, positionDifference)); + + // Compute the minimum over the rest of the input values. + + for (++inputIndex; + inputIndex < inputPositions.size(); + ++inputIndex) { + positionDifference = inputPositions[inputIndex] - outputValue; + const double distance = + (IntraCellOnly ? + manhattanDistance(positionDifference) : + manhattanDistance(positionDifference)); + if (distance < minimumDistance + epsilon) { + if (distance < minimumDistance) { + minimumSet.clear(); + minimumDistance = distance; + } + minimumSet.push_back(std::make_pair(inputIndex, + positionDifference)); + } + } + + + // Convert the minimum set to a set of FieldOffsets. + // minimumSet has all the minimum distance locations. + + FieldOffset_vt answerHolder; + if (IntraCellOnly) { + for (MinimumSet::size_type minIndex = 0; + minIndex < minimumSet.size(); + ++minIndex) + answerHolder.push_back(FieldOffset_t(Loc(0), + minimumSet[minIndex].first)); + } + else { + FieldOffset_vt partialAnswer; + for (MinimumSet::size_type minIndex = 0; + minIndex < minimumSet.size(); + ++minIndex) + { + // Compute the cell offsets, appending to the set of answers. + + partialAnswer = computeCellOffsets(minimumSet[minIndex].first, + minimumSet[minIndex].second); + answerHolder.insert(answerHolder.end(), + partialAnswer.begin(), partialAnswer.end()); + } + + // Remove all duplicates from the answer set. + + std::sort(answerHolder.begin(), answerHolder.end(), + CompareFieldOffset()); + answerHolder.erase(std::unique(answerHolder.begin(), + answerHolder.end(), + EqualFieldOffset()), + answerHolder.end()); + } + + return answerHolder; + } + // Given a difference between two positions in logical coordinate // space, return the Manhattan norm distance taking into account // that input values are repeated in every grid cell. *************** private: *** 240,246 **** inline static double manhattanDistance(const Position &difference) { ! double answer; for (int coordinate = Dim-1; coordinate >= 0; --coordinate) answer = Distance()(answer, difference(coordinate)); return answer; --- 299,305 ---- inline static double manhattanDistance(const Position &difference) { ! double answer = 0.0;; for (int coordinate = Dim-1; coordinate >= 0; --coordinate) answer = Distance()(answer, difference(coordinate)); return answer; *************** private: *** 356,364 **** } }; - const Center &inputCentering_m; - const Center &outputCentering_m; - // Use epsilon when comparing floating-point numbers, which cannot // be represented precisely. --- 415,420 ---- *************** std::vector > *** 381,387 **** nearestNeighbors(const Centering &inputCentering, const Centering &outputCentering) { ! return NearestNeighborClass(inputCentering, outputCentering)(); } template --- 437,443 ---- nearestNeighbors(const Centering &inputCentering, const Centering &outputCentering) { ! return NearestNeighborClass()(inputCentering, outputCentering); } template *************** nearestNeighbors(const Centering &i *** 390,398 **** const Centering &outputCentering, const bool) { ! return NearestNeighborClass(inputCentering, outputCentering)(); } //----------------------------------------------------------------------------- // inputPosition(inputCentering, fieldOffset) --- 446,494 ---- const Centering &outputCentering, const bool) { ! return NearestNeighborClass()(inputCentering, outputCentering); } + template + std::vector > + nearestNeighbors(const Centering &inputCentering, + const FieldOffsetList &fOL, + const Centering &outputCentering) + { + return NearestNeighborClass()(inputCentering, fOL, outputCentering); + } + + template + std::vector > + nearestNeighbors(const Centering &inputCentering, + const FieldOffsetList &fOL, + const Centering &outputCentering, + const bool) + { + return NearestNeighborClass() + (inputCentering, fOL, outputCentering); + } + + template + FieldOffsetList + nearestNeighbors(const Centering &inputCentering, + const FieldOffset &fieldOffset, + const Centering &outputCentering) + { + return NearestNeighborClass() + (inputCentering, fieldOffset, outputCentering); + } + + template + FieldOffsetList + nearestNeighbors(const Centering &inputCentering, + const FieldOffset &fieldOffset, + const Centering &outputCentering, + const bool) + { + return NearestNeighborClass() + (inputCentering, fieldOffset, outputCentering); + } //----------------------------------------------------------------------------- // inputPosition(inputCentering, fieldOffset) Index: tests/NearestNeighbors.cpp =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/tests/Attic/NearestNeighbors.cpp,v retrieving revision 1.1.2.2 diff -c -p -r1.1.2.2 NearestNeighbors.cpp *** tests/NearestNeighbors.cpp 2001/08/14 20:24:18 1.1.2.2 --- tests/NearestNeighbors.cpp 2001/08/14 22:06:20 *************** int main(int argc, char *argv[]) *** 156,161 **** --- 156,162 ---- Centering<2> inputCenteringTwo, outputCenteringTwo; Centering<3> inputCenteringThree, outputCenteringThree; + FieldOffsetList<2> fieldOffsetListTwo; // Test 2D Continuous Cell -> Continuous Cell. *************** int main(int argc, char *argv[]) *** 210,215 **** --- 211,231 ---- inputCenteringTwo, outputCenteringTwo)); + fieldOffsetListTwo = + nearestNeighbors(inputCenteringTwo, + FieldOffset<2>(Loc<2>(0,0)), outputCenteringTwo); + tester.check("vertex->cell intercell", + fieldOffsetListTwo.size() == 4 && + checkForFieldOffset(fieldOffsetListTwo, + FieldOffset<2>(Loc<2>(0,0)))); + + fieldOffsetListTwo = + nearestNeighbors(inputCenteringTwo, + FieldOffset<2>(Loc<2>(0,0)), outputCenteringTwo, true); + tester.check("vertex->cell intracell", + fieldOffsetListTwo.size() == 1 && + checkForFieldOffset(fieldOffsetListTwo, + FieldOffset<2>(Loc<2>(0,0)))); // Test 2D Discontinuous Vertex -> Continuous Cell. From oldham at codesourcery.com Wed Aug 15 18:28:37 2001 From: oldham at codesourcery.com (Jeffrey Oldham) Date: Wed, 15 Aug 2001 11:28:37 -0700 Subject: [newfield_revision Patch] Remove temporary error checking Message-ID: <20010815112837.A9834@codesourcery.com> I removed a debugging statement in NearestNeighbors.h. 2001-08-15 Jeffrey D. Oldham * NearestNeighbors.h (NearestNeighborClass::operator()(Center,Center)): Remove temporary debugging statement. Applied to newfield_revision branch Approved by no one Not Tested. Thanks, Jeffrey D. Oldham oldham at codesourcery.com -------------- next part -------------- Index: NearestNeighbors.h =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/Attic/NearestNeighbors.h,v retrieving revision 1.1.2.4 diff -c -p -r1.1.2.4 NearestNeighbors.h *** NearestNeighbors.h 2001/08/15 18:09:45 1.1.2.4 --- NearestNeighbors.h 2001/08/15 18:25:51 *************** public: *** 130,140 **** for (Answer_t::size_type outputIndex = 0; outputIndex < outputCentering.size(); ! ++outputIndex) { answer[outputIndex] = nearestNeighbors(inputPositions, outputPositions[outputIndex]); - std::cout << answer[outputIndex] << std::endl; // TMP - } return answer; } --- 130,138 ---- for (Answer_t::size_type outputIndex = 0; outputIndex < outputCentering.size(); ! ++outputIndex) answer[outputIndex] = nearestNeighbors(inputPositions, outputPositions[outputIndex]); return answer; } From mark at codesourcery.com Wed Aug 15 18:36:05 2001 From: mark at codesourcery.com (Mark Mitchell) Date: Wed, 15 Aug 2001 11:36:05 -0700 Subject: Speeding Pooma Code on a Branch? In-Reply-To: <200108150342.UAA32255@oz.codesourcery.com> Message-ID: <590120000.997900565@warlock.codesourcery.com> --On Tuesday, August 14, 2001 08:42:46 PM -0700 Jeffrey Oldham wrote: > > Soon some Pooma developers will turn to reducing Pooma's > running time. Should we modify the code on a separate branch, e.g., > the running_time branch, so that the Blanca people's use of the > mainline is not affected? I don't think that is necesary. You probably won't be changing interfaces drastically, or at least we hope not. But, if other people feel differently, I certainly won't object. -- Mark Mitchell mark at codesourcery.com CodeSourcery, LLC http://www.codesourcery.com From oldham at codesourcery.com Wed Aug 15 23:15:14 2001 From: oldham at codesourcery.com (Jeffrey Oldham) Date: Wed, 15 Aug 2001 16:15:14 -0700 Subject: [newfield_revision Patch] FieldOffset.cpp: New Test Message-ID: <20010815161514.B20199@codesourcery.com> This is Stephen Smith's patch to the FieldOffset test program demonstrating to a skeptical me that one can assign to a field shifted by a FieldOffset. 2001-08-15 Stephen Smith * FieldOffset.cpp (main): Add assignment to shifted field. Tested on sequential Linux using gcc 3.0.1 by compiling and running Approved by Jeffreyy D. Oldham Applied to newfield_revision branch Thanks, Jeffrey D. Oldham oldham at codesourcery.com -------------- next part -------------- Index: FieldOffset.cpp =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/tests/Attic/FieldOffset.cpp,v retrieving revision 1.1.2.4 diff -c -p -r1.1.2.4 FieldOffset.cpp *** FieldOffset.cpp 2001/08/10 17:40:53 1.1.2.4 --- FieldOffset.cpp 2001/08/15 22:08:28 *************** int main(int argc, char *argv[]) *** 139,144 **** --- 139,152 ---- tester.out() << "f" << std::endl << f << std::endl; tester.out() << "fS" << std::endl << fS << std::endl; + f(upperXEdge, cell) = fS; + + // FIXME: Direct assignment to elements should probably work. + // The following line fails. + // f(upperXEdge, cell)(1, 1) = 4.5; + + tester.out() << "f" << std::endl << f << std::endl; + int ret = tester.results("FieldOffset"); Pooma::finalize(); return ret; From oldham at codesourcery.com Thu Aug 16 00:38:29 2001 From: oldham at codesourcery.com (Jeffrey Oldham) Date: Wed, 15 Aug 2001 17:38:29 -0700 Subject: [newfield_revision Patch] Add typename to NearestNeighbors.* Message-ID: <20010815173829.A24319@codesourcery.com> KCC 4.?0? needed these five typename's to compile. 2001-08-15 Jeffrey D. Oldham * NearestNeighbors.h (NearestNeighborClass): Add two typename's. * tests/NearestNeighbors.cpp (checkFieldOffset): Add three typename's. Applied to newfield_revision branch Approved by ???you??? Tested on sequential Linux using gcc 3.0.1 by compiling Pooma library and +NewField tests Thanks, Jeffrey D. Oldham oldham at codesourcery.com -------------- next part -------------- Index: NearestNeighbors.h =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/Attic/NearestNeighbors.h,v retrieving revision 1.1.2.5 diff -c -p -r1.1.2.5 NearestNeighbors.h *** NearestNeighbors.h 2001/08/15 18:28:13 1.1.2.5 --- NearestNeighbors.h 2001/08/15 23:29:30 *************** public: *** 96,103 **** typedef std::vector FieldOffset_vt; typedef std::vector Answer_t; typedef Centering Center; ! typedef Center::Positions Positions; ! typedef Center::Position Position; // To compute the set of input values, we maintain a set of input // values and their differences from the output value. In fact, we --- 96,103 ---- typedef std::vector FieldOffset_vt; typedef std::vector Answer_t; typedef Centering Center; ! typedef typename Center::Positions Positions; ! typedef typename Center::Position Position; // To compute the set of input values, we maintain a set of input // values and their differences from the output value. In fact, we Index: tests/NearestNeighbors.cpp =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/tests/Attic/NearestNeighbors.cpp,v retrieving revision 1.1.2.3 diff -c -p -r1.1.2.3 NearestNeighbors.cpp *** tests/NearestNeighbors.cpp 2001/08/15 18:09:46 1.1.2.3 --- tests/NearestNeighbors.cpp 2001/08/15 23:29:30 *************** inline bool *** 69,77 **** checkFieldOffset(Pooma::Tester &tester, const char *testExplanation, const std::vector > &nn, ! const std::vector >::size_type nnSize, ! const std::vector >::size_type listNum, ! const FieldOffsetList::size_type listSize, const FieldOffset &offset, const bool offsetPresent = true) { --- 69,77 ---- checkFieldOffset(Pooma::Tester &tester, const char *testExplanation, const std::vector > &nn, ! const typename std::vector >::size_type nnSize, ! const typename std::vector >::size_type listNum, ! const typename FieldOffsetList::size_type listSize, const FieldOffset &offset, const bool offsetPresent = true) { From oldham at codesourcery.com Thu Aug 16 18:26:02 2001 From: oldham at codesourcery.com (Jeffrey Oldham) Date: Thu, 16 Aug 2001 11:26:02 -0700 Subject: [newfield_revision Patch] Support Field Replication Message-ID: <20010816112602.A15850@codesourcery.com> Specifying one field's values by copying values in another field is a frequent operation supported by this patch. To support it, we implement the resulting field as an engine based on the input field rather than performing the computation when replicate() is called. 2001-08-16 Jeffrey D. Oldham * FieldOffset.h: Remove unnecessary header files. (replicate): New function. * DiffOps/FieldShiftEngine.h (FieldShiftSimple::make): Revise parameters. Move error checking from View2. (FieldShiftSimple::make(Expression, vector, Centering>)): New function analogous to above make() but supporting a vector of FieldOffsetList's. (View2): Fix initial comment. (View2::make): Move error checking to FieldShiftSimple::make. (View2::makeRead): Likewise. (View2,Centering>): New class supporting a vector of FieldOffsetList's. * tests/makefile (run_tests): Add Replicate. (field_tests): Likewise. Add PHONY Replicate rule. * tests/Replicate.cpp: New file to test replicate(). Applied to newfield_revision branch Approved by Stephen Smith Tested on sequential Linux using gcc 3.0.1 by compiling Pooma library and NewField tests Thanks, Jeffrey D. Oldham oldham at codesourcery.com -------------- next part -------------- Index: FieldOffset.h =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/Attic/FieldOffset.h,v retrieving revision 1.1.2.4 diff -c -p -r1.1.2.4 FieldOffset.h *** FieldOffset.h 2001/08/15 18:09:45 1.1.2.4 --- FieldOffset.h 2001/08/16 17:18:00 *************** *** 65,73 **** #include "Domain/Loc.h" #include #include - #include - #include - #include //----------------------------------------------------------------------------- --- 65,70 ---- *************** class FieldOffsetList; *** 129,134 **** --- 126,145 ---- //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- + // Full Description of replicate: + // + // Copy field values to the specified locations. The first field + // parameter specifies the field supplying the values to replicate. + // The second std::vector parameter specifies, for + // each value in the returned field, which input field value to use. + // The vector's length must match the number of values in each output + // field's cell. For example, the output field's first value is + // copied from the location specified by the vector's first list. The + // third parameter indicates the returned field's centering. + // + //----------------------------------------------------------------------------- + + //----------------------------------------------------------------------------- // Full Description of findFieldOffsetList(): // // Given an input centering and an output centering, *************** max(const Field& f *** 438,443 **** --- 449,483 ---- typedef typename Field::T_t T_t; CTAssert((Field::dimensions == Dim)); return accumulate(fomax(), field, lst, loc); + } + + + //----------------------------------------------------------------------------- + // replicate. + //----------------------------------------------------------------------------- + + template + inline + typename + View2, std::vector >, + Centering >::Type_t + replicate(const Field& field, + const std::vector > &vec, + const Centering ¢ering) + { + CTAssert((Field::dimensions == Dim)); + typedef typename std::vector >::size_type vsize_type; + PInsist(vec.size() > 0, "Cannot replicate no values."); + PInsist(vec.size() == centering.size(), + "Vector and output centering sizes must match."); + + std::vector > vecFO(vec.size()); + for (vsize_type i = 0; i < vec.size(); ++i) { + PInsist(vec[i].size() == 1, "Can replicate only one value."); + vecFO[i] = vec[i][0]; + } + + return field(vecFO, centering); } Index: DiffOps/FieldShiftEngine.h =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/DiffOps/Attic/FieldShiftEngine.h,v retrieving revision 1.1.2.2 diff -c -p -r1.1.2.2 FieldShiftEngine.h *** DiffOps/FieldShiftEngine.h 2001/08/13 21:14:30 1.1.2.2 --- DiffOps/FieldShiftEngine.h 2001/08/16 18:07:48 *************** struct FieldShiftSimple *** 372,378 **** typedef Engine SEngine_t; static inline ! Type_t make(const Expression &f, const Loc &offset, const Centering ¢ering) { // This should be h(centering, f.mesh(), f.layout()) --- 372,379 ---- typedef Engine SEngine_t; static inline ! Type_t make(const Expression &f, ! const FieldOffset &s1, const Centering ¢ering) { // This should be h(centering, f.mesh(), f.layout()) *************** struct FieldShiftSimple *** 382,400 **** // Could change this to loop over centerings. ! GuardLayers og(f.fieldEngine().guardLayers()); for (int d = 0; d < outputDim; d++) ! { ! og.lower(d) += offset[d].first(); ! og.upper(d) -= offset[d].first(); ! } // need to set domain??? h.fieldEngine().guardLayers() = og; ! h.fieldEngine().engine() = SEngine_t(f.engine(), offset, f.domain()); return h; } }; //----------------------------------------------------------------------------- --- 383,488 ---- // Could change this to loop over centerings. ! # if POOMA_BOUNDS_CHECK ! if (f.numSubFields() > 0) ! { ! PInsist((s1.subFieldNumber() < f.numSubFields()) && ! (s1.subFieldNumber() >= 0), ! "subField bounds error"); ! PInsist(contains(f[s1.subFieldNumber()].totalDomain(), ! f[s1.subFieldNumber()].domain() + s1.cellOffset()), ! "Field operator()(FieldOffset) bounds error"); ! } ! else ! { ! PInsist(s1.subFieldNumber() == 0, ! "subField bounds error"); ! PInsist(contains(f.totalDomain(), f.domain() + s1.cellOffset()), ! "Field operator()(FieldOffset) bounds error"); ! } ! # endif ! ! Expression fld = ! (f.numSubFields() > 0) ? f[s1.subFieldNumber()] : f; ! const Loc &offset = s1.cellOffset(); ! ! GuardLayers og(fld.fieldEngine().guardLayers()); for (int d = 0; d < outputDim; d++) ! { ! og.lower(d) += offset[d].first(); ! og.upper(d) -= offset[d].first(); ! } // need to set domain??? h.fieldEngine().guardLayers() = og; ! h.fieldEngine().engine() = SEngine_t(fld.engine(), offset, fld.domain()); ! ! return h; ! } ! ! static inline ! Type_t make(const Expression &f, ! const std::vector > &vs1, ! const Centering ¢ering) ! { ! typedef std::vector >::size_type size_type; ! ! // This should be h(centering, f.mesh(), f.layout()) ! // (Ideally centering would come out of offset.) ! ! Type_t h(f, centering); ! ! // Could change this to loop over centerings. ! ! PInsist(vs1.size() == centering.size(), ! "The FieldOffset vector's length must match the centering's size."); ! ! // This code should simplify when unified access to fields with ! // one or more subfields is possible. + for (size_type s1Index = 0; s1Index < vs1.size(); ++s1Index) { + const FieldOffset s1 = vs1[s1Index]; + Type_t hField = (h.numSubFields() > 0) ? h[s1Index] : h; + + # if POOMA_BOUNDS_CHECK + if (f.numSubFields() > 0) + { + PInsist((s1.subFieldNumber() < f.numSubFields()) && + (s1.subFieldNumber() >= 0), + "subField bounds error"); + PInsist(contains(f[s1.subFieldNumber()].totalDomain(), + f[s1.subFieldNumber()].domain() + s1.cellOffset()), + "Field operator()(FieldOffset) bounds error"); + } + else + { + PInsist(s1.subFieldNumber() == 0, + "subField bounds error"); + PInsist(contains(f.totalDomain(), f.domain() + s1.cellOffset()), + "Field operator()(FieldOffset) bounds error"); + } + # endif + + Expression fld = + (f.numSubFields() > 0) ? f[s1.subFieldNumber()] : f; + const Loc &offset = s1.cellOffset(); + + GuardLayers og(fld.fieldEngine().guardLayers()); + for (int d = 0; d < outputDim; d++) + { + og.lower(d) += offset[d].first(); + og.upper(d) -= offset[d].first(); + } + + // need to set domain??? + hField.fieldEngine().guardLayers() = og; + hField.fieldEngine().engine() = + SEngine_t(fld.engine(), offset, fld.domain()); + } + return h; } + }; //----------------------------------------------------------------------------- *************** struct LeafFunctor specialization for indexing a field with a ! // FieldOffset. //----------------------------------------------------------------------------- template ! struct View2, FieldOffset, Centering > { // Convenience typedef for the thing we're taking a view of. --- 685,697 ---- }; //----------------------------------------------------------------------------- ! // View2 specialization for indexing a ! // field with a FieldOffset. //----------------------------------------------------------------------------- template ! struct View2, FieldOffset, ! Centering > { // Convenience typedef for the thing we're taking a view of. *************** struct View2 &c) { CTAssert(Dim == Subject_t::dimensions); ! ! if (f.numSubFields() > 0) ! { ! # if POOMA_BOUNDS_CHECK ! PInsist((s1.subFieldNumber() < f.numSubFields()) && ! (s1.subFieldNumber() >= 0), ! "subField bounds error"); ! PInsist(contains(f[s1.subFieldNumber()].totalDomain(), ! f[s1.subFieldNumber()].domain() + s1.cellOffset()), ! "Field operator()(FieldOffset) bounds error"); ! # endif ! return FieldShiftSimple::make(f[s1.subFieldNumber()], ! s1.cellOffset(), c); ! } ! else ! { ! # if POOMA_BOUNDS_CHECK ! PInsist(s1.subFieldNumber() == 0, ! "subField bounds error"); ! PInsist(contains(f.totalDomain(), f.domain() + s1.cellOffset()), ! "Field operator()(FieldOffset) bounds error"); ! # endif ! return FieldShiftSimple::make(f, s1.cellOffset(), c); ! } } inline static --- 710,716 ---- const Centering &c) { CTAssert(Dim == Subject_t::dimensions); ! return FieldShiftSimple::make(f, s1, c); } inline static *************** struct View2 &c) { CTAssert(Dim == Subject_t::dimensions); ! if (f.numSubFields() > 0) ! { ! # if POOMA_BOUNDS_CHECK ! PInsist((s1.subFieldNumber() < f.numSubFields()) && ! (s1.subFieldNumber() >= 0), ! "subField bounds error"); ! PInsist(contains(f[s1.subFieldNumber()].totalDomain(), ! f[s1.subFieldNumber()].domain() + s1.cellOffset()), ! "Field operator()(FieldOffset) bounds error"); ! # endif ! return FieldShiftSimple::make(f[s1.subFieldNumber()], ! s1.cellOffset(), c); ! } ! else ! { ! # if POOMA_BOUNDS_CHECK ! PInsist(s1.subFieldNumber() == 0, ! "subField bounds error"); ! PInsist(contains(f.totalDomain(), f.domain() + s1.cellOffset()), ! "Field operator()(FieldOffset) bounds error"); ! # endif ! return FieldShiftSimple::make(f, s1.cellOffset(), c); ! } } }; --- 718,764 ---- const Centering &c) { CTAssert(Dim == Subject_t::dimensions); + return FieldShiftSimple::make(f, s1, c); + } + }; + + //----------------------------------------------------------------------------- + // View2, Centering> specialization for indexing a + // field with a vector. + //----------------------------------------------------------------------------- + + template + struct View2, std::vector >, + Centering > + { + // Convenience typedef for the thing we're taking a view of. + + typedef Field Subject_t; + typedef typename Subject_t::Engine_t Engine_t; + + // The return types. + + typedef Field > ReadType_t; + typedef Field > Type_t; + + // The functions that do the indexing. + + inline static + Type_t make(const Subject_t &f, + const std::vector > &s1, + const Centering &c) + { + CTAssert(Dim == Subject_t::dimensions); + return FieldShiftSimple::make(f, s1, c); + } ! inline static ! ReadType_t makeRead(const Subject_t &f, ! const std::vector > &s1, ! const Centering &c) ! { ! CTAssert(Dim == Subject_t::dimensions); ! return FieldShiftSimple::make(f, s1, c); } }; Index: tests/Replicate.cpp =================================================================== RCS file: Replicate.cpp diff -N Replicate.cpp *** /dev/null Tue May 5 14:32:27 1998 --- Replicate.cpp Thu Aug 16 11:18:00 2001 *************** *** 0 **** --- 1,98 ---- + // -*- 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 + //----------------------------------------------------------------------------- + // Test replicating field values. + //----------------------------------------------------------------------------- + + #include "Pooma/NewFields.h" + #include "Utilities/Tester.h" + #include + + + int main(int argc, char *argv[]) + { + Pooma::initialize(argc, argv); + Pooma::Tester tester(argc, argv); + + const double epsilon = 1.0e-08; + const int Dim = 2; + Centering inputCenteringTwo, outputCenteringTwo; + Interval physicalVertexDomain(4, 4); + DomainLayout layout(physicalVertexDomain, GuardLayers(1)); + typedef Field, double, Brick> Field_t; + + // Test 2D Continuous Cell -> Discontinuous Edge. + + inputCenteringTwo = canonicalCentering(CellType, Continuous, AllDim); + outputCenteringTwo = canonicalCentering(EdgeType, Discontinuous, AllDim); + Field_t g(outputCenteringTwo, layout, + Vector(0.0), Vector(1.0, 2.0)); + Field_t f(inputCenteringTwo, layout, + Vector(0.0), Vector(1.0, 2.0)); + f.all() = 2.0; + g.all() = 1.0; + + g = replicate(f, nearestNeighbors(inputCenteringTwo, + outputCenteringTwo, true), + outputCenteringTwo); + + tester.check("cell->discontinuous edge", + g(FieldOffset(Loc(0), 0), Loc(0)), + 2.0, epsilon); + + // Test 2D Continuous Vertex -> Discontinuous Vertex. + + inputCenteringTwo = + canonicalCentering(VertexType, Continuous, AllDim); + outputCenteringTwo = + canonicalCentering(VertexType, Discontinuous, AllDim); + + Field_t g2(outputCenteringTwo, layout, + Vector(0.0), Vector(1.0, 2.0)); + Field_t f2(inputCenteringTwo, layout, + Vector(0.0), Vector(1.0, 2.0)); + f2.all() = 2.0; + g2.all() = 1.0; + + g2 = replicate(f2, nearestNeighbors(inputCenteringTwo, outputCenteringTwo), + outputCenteringTwo); + tester.check("vertex->discontinuous vertex", + g2(FieldOffset(Loc(0), 0), Loc(0)), + 2.0, epsilon); + + int ret = tester.results("Replicate"); + Pooma::finalize(); + return ret; + } + + // ACL:rcsinfo + // ---------------------------------------------------------------------- + // $RCSfile: Replicate.cpp,v $ $Author: oldham $ + // $Revision: 1.1.2.2 $ $Date: 2001/08/14 20:24:18 $ + // ---------------------------------------------------------------------- + // ACL:rcsinfo Index: tests/makefile =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/tests/makefile,v retrieving revision 1.11.2.8 diff -c -p -r1.11.2.8 makefile *** tests/makefile 2001/08/14 20:24:18 1.11.2.8 --- tests/makefile 2001/08/16 17:18:00 *************** run_tests: tests *** 57,62 **** --- 57,63 ---- $(ODIR)/Gradient $(TSTOPTS) 1>Gradient.out 2>&1 $(ODIR)/MeshTest1 $(TSTOPTS) 1>MeshTest1.out 2>&1 $(ODIR)/NearestNeighbors $(TSTOPTS) 1>NearestNeighbors.out 2>&1 + $(ODIR)/Replicate $(TSTOPTS) 1>Replicate.out 2>&1 $(ODIR)/ScalarCode $(TSTOPTS) 1>ScalarCode.out 2>&1 $(ODIR)/StencilTests $(TSTOPTS) 1>StencilTests.out 2>&1 $(ODIR)/VectorTest $(TSTOPTS) 1>VectorTest.out 2>&1 *************** field_tests:: $(ODIR)/BasicTest1 $(ODIR) *** 68,73 **** --- 69,75 ---- $(ODIR)/FieldTour1 $(ODIR)/FieldTour2 \ $(ODIR)/FieldTour3 $(ODIR)/Gradient\ $(ODIR)/MeshTest1 $(ODIR)/NearestNeighbors \ + $(ODIR)/Replicate \ $(ODIR)/ScalarCode $(ODIR)/StencilTests \ $(ODIR)/VectorTest $(ODIR)/WhereTest *************** $(ODIR)/NearestNeighbors: $(ODIR)/Neares *** 169,174 **** --- 171,183 ---- Positions: $(ODIR)/Positions $(ODIR)/Positions: $(ODIR)/Positions.o + $(LinkToSuite) + + .PHONY: Replicate + + Replicate: $(ODIR)/Replicate + + $(ODIR)/Replicate: $(ODIR)/Replicate.o $(LinkToSuite) .PHONY: ScalarCode From oldham at codesourcery.com Thu Aug 16 20:21:52 2001 From: oldham at codesourcery.com (Jeffrey Oldham) Date: Thu, 16 Aug 2001 13:21:52 -0700 Subject: [newfield_revision Patch] Fix nearestNeighbors() Message-ID: <20010816132152.A18803@codesourcery.com> This patch fixes a typographical error and inlines some trivial functions. 2001-08-16 Jeffrey D. Oldham * NearestNeighbors.h: (NearestNeighborClass::operator()(Center,FieldOffsetList_t,Center): Correct the return type. (nearestNeighbors): Inline. Applied to newfield_revision branch Approved by Stephen Smith Tested on sequential Linux using gcc 3.0.1 by compiling Pooma library and NewField tests Thanks, Jeffrey D. Oldham oldham at codesourcery.com -------------- next part -------------- Index: NearestNeighbors.h =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/Attic/NearestNeighbors.h,v retrieving revision 1.1.2.6 diff -c -p -r1.1.2.6 NearestNeighbors.h *** NearestNeighbors.h 2001/08/16 00:39:36 1.1.2.6 --- NearestNeighbors.h 2001/08/16 17:59:54 *************** public: *** 158,164 **** // Return the nearest neighbors for multiple output positions, specified // by a FieldOffsetList. ! inline FieldOffsetList_t operator()(const Center &inputCentering, const FieldOffsetList_t &fieldOffsetList, const Center &outputCentering) --- 158,164 ---- // Return the nearest neighbors for multiple output positions, specified // by a FieldOffsetList. ! inline std::vector operator()(const Center &inputCentering, const FieldOffsetList_t &fieldOffsetList, const Center &outputCentering) *************** NearestNeighborClass *** 431,436 **** --- 431,437 ---- //----------------------------------------------------------------------------- template + inline std::vector > nearestNeighbors(const Centering &inputCentering, const Centering &outputCentering) *************** nearestNeighbors(const Centering &i *** 439,444 **** --- 440,446 ---- } template + inline std::vector > nearestNeighbors(const Centering &inputCentering, const Centering &outputCentering, *************** nearestNeighbors(const Centering &i *** 448,453 **** --- 450,456 ---- } template + inline std::vector > nearestNeighbors(const Centering &inputCentering, const FieldOffsetList &fOL, *************** nearestNeighbors(const Centering &i *** 457,462 **** --- 460,466 ---- } template + inline std::vector > nearestNeighbors(const Centering &inputCentering, const FieldOffsetList &fOL, *************** nearestNeighbors(const Centering &i *** 468,473 **** --- 472,478 ---- } template + inline FieldOffsetList nearestNeighbors(const Centering &inputCentering, const FieldOffset &fieldOffset, *************** nearestNeighbors(const Centering &i *** 478,483 **** --- 483,489 ---- } template + inline FieldOffsetList nearestNeighbors(const Centering &inputCentering, const FieldOffset &fieldOffset, From oldham at codesourcery.com Thu Aug 16 20:31:15 2001 From: oldham at codesourcery.com (Jeffrey Oldham) Date: Thu, 16 Aug 2001 13:31:15 -0700 Subject: [newfield_revision Patch] Add Linear Algebra to Statigraphic Flow Message-ID: <20010816133115.C18803@codesourcery.com> This patch to the (Chevron^r) statigraphic flow program adds the linear algebra computation. We use the open-source beta Template Numerical Toolkit package from the NIST. The linear algebra computation needs to be moved to a stencil. We are currently working on that. 2001-08-16 Jeffrey D. Oldham * StatigraphicFlow.cpp: Add header files for linear algebra computations. Remove answered question and finished functions. Add sum() to unfinished work list. Update explanations with revised replicate() information and new information for nearestNeighbors(Centering, FieldOffset, Centering) and sum(). (findIndex): New function. (main): Fix creation of spoke centering. Add creation of disspoke centering. Add directedPermeability and faceDistance fields. Replace linear algebra pseudocode with explicit computation. Revise computation of totalFlux. * makefile: (RULE_INCLUDES): Add support for linear alegebra library. * tnt/A10x10.dat: New file from linear algebra package. * tnt/AB10x10.dat: Likewise. * tnt/Makefile: Likewise. * tnt/SPD10x10.dat: Likewise. * tnt/cholesky.h: Likewise. * tnt/cmat.h: Likewise. * tnt/fchol.cc: Likewise. * tnt/fcscmat.h: Likewise. * tnt/fmat.h: Likewise. * tnt/fortran.h: Likewise. * tnt/fspvec.h: Likewise. * tnt/index.h: Likewise. * tnt/lapack.h: Likewise. * tnt/lu-C.cc: Likewise. * tnt/lu.cc: Likewise. * tnt/lu.h: Likewise. * tnt/matrix.dat: Likewise. * tnt/qr.cc: Likewise. * tnt/qr.h: Likewise. * tnt/region1d.h: Likewise. * tnt/region2d.h: Likewise. * tnt/stopwatch.h: Likewise. * tnt/subscript.h: Likewise. * tnt/tnt.h: Likewise. * tnt/tnt.h.patch: Likewise. * tnt/tntmath.h: Likewise. * tnt/tntreqs.h: Likewise. * tnt/transv.h: Likewise. * tnt/triang.h: Likewise. * tnt/trisolve.h: Likewise. * tnt/vec.h: Likewise. * tnt/vec.h.patch: Likewise. * tnt/vecadaptor.h: Likewise. * tnt/version.h: Likewise. Applied to newfield_revision branch of examples/NewField/StatigraphicFlow/ Approved by Stephen Smith Not tested. It does not currently cleanly compile. Thanks, Jeffrey D. Oldham oldham at codesourcery.com -------------- next part -------------- Index: StatigraphicFlow.cpp =================================================================== RCS file: /home/pooma/Repository/r2/examples/NewField/StatigraphicFlow/Attic/StatigraphicFlow.cpp,v retrieving revision 1.1.2.1 diff -c -p -r1.1.2.1 StatigraphicFlow.cpp *** StatigraphicFlow.cpp 2001/08/04 02:19:06 1.1.2.1 --- StatigraphicFlow.cpp 2001/08/16 19:02:55 *************** *** 7,12 **** --- 7,17 ---- #include #include #include "Pooma/NewFields.h" + // linear algebra files: + #include "tnt/tnt.h" + #include "tnt/vec.h" + #include "tnt/cmat.h" + #include "tnt/lu.h" // This program implements "Implementation of a Flux-Continuous Fnite // Difference Method for Stratigraphic, Hexahedron Grids," by *************** *** 28,49 **** // o. I omitted a separate coordinates field, presumably updated each // iteration, in favor of using the mesh. Since I do not know how // the coordinates are updated, I omitted updating the mesh. - // o. Is it important to flesh out the linear algebra solution? We - // might learn something about field syntax, but it will also take - // time for me to determine the correct operands. // o. Creating non-canonical edge and face centerings requires // dimension-dependent code. Is this acceptable? /** UNFINISHED WORK **/ - // o replicate(field, std::vector) // o meshLayout.unitCoordinateNormals() // o field.mesh() // o field.mesh().normals() // o field.mesh().normals().signedMagnitude() - /** EXPLANATIONS **/ // o Centering canonicalCentering(CellType, Continuous): --- 33,50 ---- // o. I omitted a separate coordinates field, presumably updated each // iteration, in favor of using the mesh. Since I do not know how // the coordinates are updated, I omitted updating the mesh. // o. Creating non-canonical edge and face centerings requires // dimension-dependent code. Is this acceptable? /** UNFINISHED WORK **/ // o meshLayout.unitCoordinateNormals() // o field.mesh() // o field.mesh().normals() // o field.mesh().normals().signedMagnitude() + // o sum(field, vector, centering) /** EXPLANATIONS **/ // o Centering canonicalCentering(CellType, Continuous): *************** *** 62,72 **** // o The Chevron algorithm first solves a linear program. I have // omitted since computation since it does not illustrate field // computations. ! // o replicate(field, std::vector): This function, ! // syntactic sugar for a nearest neighbors computation, copies the ! // field values to the positions indicated by the ! // std::vector. Each field value is copied to one ! // or more values. replicate() could be replaced by sum(), but the // latter function has an unnecessary loop since each output value // equals one input value. // o nearestNeighbors(inputCentering, outputCentering): This function --- 63,73 ---- // o The Chevron algorithm first solves a linear program. I have // omitted since computation since it does not illustrate field // computations. ! // o replicate(field, std::vector, centering): This ! // function, syntactic sugar for a nearest neighbors computation, ! // copies the field values to the positions indicated by the ! // std::vector. Each field value is copied to one or ! // more values. replicate() could be replaced by sum(), but the // latter function has an unnecessary loop since each output value // equals one input value. // o nearestNeighbors(inputCentering, outputCentering): This function *************** *** 75,80 **** --- 76,87 ---- // value, the closest input values, wrt Manhattan distance, are // returned. Eventually, these may be pre-computed or cached to // reduce running time. + // o nearestNeighbors(input centering, FieldOffset, offset's centering + // [, bool]): This function returns a FieldOffsetList with entries for + // the closest input values, wrt Manhattan distance, to the value + // specified by the FieldOffset and the offset centering. The + // optional fourth parameter indicates only values from the FieldOffset's + // cell should be returned. // o meshLayout.unitCoordinateNormals(): This returns a discontinuous // face-centered field with unit-length normals all pointing in // positive directions. *************** *** 87,94 **** // equalling the face's area/volume and sign equalling whether the // face's normal is in a positive direction, e.g., the positive // x-direction vs. the negative x-direction. ! // o sum(field, FieldOffsetList): this parallel-data statement adds ! // the values indicated in the FieldOffsetList to form each output value /** DESIGN DECISIONS **/ --- 94,102 ---- // equalling the face's area/volume and sign equalling whether the // face's normal is in a positive direction, e.g., the positive // x-direction vs. the negative x-direction. ! // o sum(field, vector, centering): this ! // parallel-data statement adds the values indicated in the ! // FieldOffsetList to form each output value /** DESIGN DECISIONS **/ *************** *** 98,103 **** --- 106,129 ---- /** THE PROGRAM **/ + + // Return the index of the specified field offset in the given list. + // Return a negative number if not found. + + template + inline int + findIndex(const FieldOffsetList &vec, + const FieldOffset &fo) + { + int indx; + for (indx = vec.size()-1; + indx >= 0 && vec[indx] != fo; + --indx) + ; + return indx; + } + + int main(int argc, char *argv[]) { // Set up the Pooma library. *************** int main(int argc, char *argv[]) *** 158,172 **** position(zeroFace) = 0.0; position(1-zeroFace) = 0.25; spoke.addValue(orientation, position); position(1-zeroFace) = 0.75; spoke.addValue(orientation, position); - position(zeroFace) = 1.0; - position(1-zeroFace) = 0.25; spoke.addValue(orientation, position); - position(1-zeroFace) = 0.75; spoke.addValue(orientation, position); } Fields_t spokeFlux (spoke, meshLayout, origin, spacings); // Face-centered. Centering disFace = canonicalCentering(FaceType, Discontinuous); /* INITIALIZATION */ --- 184,211 ---- position(zeroFace) = 0.0; position(1-zeroFace) = 0.25; spoke.addValue(orientation, position); position(1-zeroFace) = 0.75; spoke.addValue(orientation, position); } Fields_t spokeFlux (spoke, meshLayout, origin, spacings); + Centering disspoke(FaceType, Discontinuous); + // NOTE: This code is not dimension-independent. + for (int zeroFace = 0; zeroFace < 2; ++zeroFace) { + orientation = 1; orientation[zeroFace] = 0; + position(zeroFace) = 0.0; + position(1-zeroFace) = 0.25; disspoke.addValue(orientation, position); + position(1-zeroFace) = 0.75; disspoke.addValue(orientation, position); + position(zeroFace) = 1.0; + position(1-zeroFace) = 0.25; disspoke.addValue(orientation, position); + position(1-zeroFace) = 0.75; disspoke.addValue(orientation, position); + } + // Face-centered. Centering disFace = canonicalCentering(FaceType, Discontinuous); + Fieldv_t directedPermeability (disFace, meshLayout, origin, spacings); + // \gamma_{i,j} = K_i^t \dot \hat{n}_j + Fields_t faceDistance (disFace, meshLayout, origin, spacings); + // distance from cell center to face center /* INITIALIZATION */ *************** int main(int argc, char *argv[]) *** 180,210 **** /* COMPUTATION */ - #ifdef PSEUDOCODE // Compute pressureGradients by simultaneously solving several // linear equations. The operands have different centerings. ! // FIXME ! pressureGradients = ! linearAlgebra<2>(pressure /* cell-centered */, ! /* Interpolate from vertex-centered to cell-centered: */ ! interpolate(coordinates), ! permeability /* cell-centered */, ! normals /* face-centered */); #endif // PSEUDOCODE ! // Compute the spoke fluxes. ! // We must multiply three quantities, each with a different ! // centering, to yield values at a fourth-centering. permeability ! // is cell-centered. pressureGradient is subcell-centered. The ! // normals are face-centered. The product is spoke-centered. spokeFlux = ! dot(replicate(dot(replicate(permeability, nearestNeighbors(cell, subcell)), ! pressureGradient), ! nearestNeighbors(subcell, spoke)), ! replicate(meshLayout.unitCoordinateNormals(), ! nearestNeighbors(disFace, spoke))); // Sum the spoke fluxes into a cell flux. --- 219,339 ---- /* COMPUTATION */ // Compute pressureGradients by simultaneously solving several // linear equations. The operands have different centerings. ! ! // \Gamma is used in the flux continuity equations. ! directedPermeability = ! dot(replicate(permeability, ! nearestNeighbors(permeability.centering(), ! directedPermeability.centering()), ! directedPermeability.centering()), ! meshLayout.unitCoordinateNormals()); ! ! #ifdef PSEUDOCODE ! // These distances are used in the pressure continuity equations. ! faceDistance = face-centered-positions - ! replicate(cell-centered-positions, ! nearestNeighbors(cell, faceDistance.centering()), ! faceDistance.centering()); #endif // PSEUDOCODE + + const int nuRows = (1 << Dim) * Dim; + TNT::Matrix A(nuRows, nuRows, 0.0); + TNT::Vector rhs(nuRows, 0.0); + TNT::Vector ipiv; // ignored + + // FIXME: Move this code to a stencil so it can be applied across + // the entire grid. + + // Assign values to the matrix A and vector rhs. + + const Centering vert = canonicalCentering(VertexType, Continuous); + PInsist(vert.size() == 1, "The vertex centering has too many values."); + + const FieldOffsetList gradients = + nearestNeighbors(pressureGradient.centering(), + FieldOffset(Loc(0)) /* cell origin */, vert); + // gradients's order of pressure gradients will be used for the + // matrix and rhs. + + const FieldOffsetList fluxPoints = + nearestNeighbors(spokeFlux.centering(), + FieldOffset(Loc(0)) /* cell origin */, vert); + // fluxPoints has locations for all faces incident to the vertex. + const int size = fluxPoints.size(); + PAssert(gradients.size() * Dim == size * 2); + + const std::vector > disFluxPoints = + nearestNeighbors(disspoke, fluxPoints, spokeFlux.centering()); + // For every i, disFluxPoints[i] is two discontinuous positions on + // "either side" of the face represented by fluxPoints[i]. + + for (int faceIndex = size-1; faceIndex >= 0; --faceIndex) { + // Work on the "positive" side of the face. + FieldOffset fo = disFluxPoints[faceIndex][0]; + int columnNu = + findIndex(gradients, + nearestNeighbors(pressureGradient.centering(), + fo, disspoke, true)[0]); + // The column number is the pressure gradient corresponding to the + // "positive" side of the face. + + // FIXME: The lhs (double) and rhs (vector field) do not match. + + A[faceIndex][columnNu] = + directedPermeability(nearestNeighbors(directedPermeability.centering(), + fo, disspoke, true)[0]); + A[faceIndex+size][columnNu] = + faceDistance(nearestNeighbors(faceDistance.centering(), + fo, disspoke, true)[0]); + rhs[faceIndex+size] -= + pressure(nearestNeighbors(pressure.centering(), + fo, disspoke, true)[0]); + + fo = disFluxPoints[faceIndex][1]; + columnNu = + findIndex(gradients, + nearestNeighbors(pressureGradient.centering(), + fo, disspoke, true)[0]); + // The column number is the pressure gradient corresponding to the + // "positive" side of the face. + + A[faceIndex][columnNu] = + -directedPermeability(nearestNeighbors(directedPermeability.centering(), + fo, disspoke, true)[0]); + A[faceIndex+size][columnNu] = + -faceDistance(nearestNeighbors(faceDistance.centering(), + fo, disspoke, true)[0]); + rhs[faceIndex+size] -= + -pressure(nearestNeighbors(pressure.centering(), + fo, disspoke, true)[0]); + } ! // Solve for the pressure gradients. ! ! TNT::LU_solve(A, ipiv, rhs); ! ! // Now, rhs has the pressure gradients. ! for (int faceIndex = size-1; faceIndex >= 0; --faceIndex) ! // FIXME: Is this type of assignment supported by the current code base? ! pressureGradient(gradients[faceIndex], subcell) = rhs[faceIndex]; ! ! ! // Compute the spoke fluxes. spokeFlux = ! dot(replicate(pressureGradient, ! nearestNeighbors(pressureGradient.centering(), ! spokeFlux.centering(), ! true), ! spokeFlux.centering()), ! replicate(directedPermeability, ! nearestNeighbors(directedPermeability.centering(), ! spokeFlux.centering(), ! true), ! spokeFlux.centering())); // Sum the spoke fluxes into a cell flux. *************** int main(int argc, char *argv[]) *** 217,224 **** totalFlux = sum(spokeFlux.mesh().normals().signedMagnitude() * ! sum(spokeFlux, nearestNeighbors(spoke, disFace)), ! nearestNeighbors(disFace, cell)); /* TERMINATION */ --- 346,364 ---- totalFlux = sum(spokeFlux.mesh().normals().signedMagnitude() * ! // FIXME: This is not yet implemented. We want a ! // FIXME: data-parallel sum. This is we want a function ! // FIXME: Field_t sum(/* input */ Field_t, ! // FIXME: std::vector, /*output */ ! // FIXME: Centering). The vector's length == the output ! // centering's length. The function works by using the input ! // field with each FieldOffsetList to form one value in the ! // output field. ! sum(spokeFlux, ! nearestNeighbors(spokeFlux.centering(), disFace), ! disFace), ! nearestNeighbors(disFace, totalFlux.centering()), ! totalFlux.centering()); /* TERMINATION */ Index: makefile =================================================================== RCS file: /home/pooma/Repository/r2/examples/NewField/StatigraphicFlow/Attic/makefile,v retrieving revision 1.1.2.1 diff -c -p -r1.1.2.1 makefile *** makefile 2001/08/04 02:19:06 1.1.2.1 --- makefile 2001/08/16 20:26:07 *************** $(ODIR)/StatigraphicFlow: $(ODIR)/Statig *** 44,49 **** --- 44,51 ---- include $(SHARED_ROOT)/tail.mk + RULE_INCLUDES += -I$(PROJECT_ROOT)/examples/NewField/StatigraphicFlow # permit inclusion of the TNT linear algebra library + # ACL:rcsinfo # ---------------------------------------------------------------------- # $RCSfile: makefile,v $ $Author: oldham $ Index: tnt/A10x10.dat =================================================================== RCS file: A10x10.dat diff -N A10x10.dat *** /dev/null Tue May 5 14:32:27 1998 --- A10x10.dat Thu Aug 16 13:02:55 2001 *************** *** 0 **** --- 1,12 ---- + 10 10 + 0.218959 0.5297 0.526929 0.328234 0.0726859 0.166507 0.493977 0.464446 0.629543 0.845982 + 0.0470446 0.671149 0.0919649 0.632639 0.631635 0.486517 0.266145 0.94098 0.736225 0.412081 + 0.678865 0.00769819 0.653919 0.75641 0.884707 0.897656 0.0907329 0.050084 0.725412 0.841511 + 0.679296 0.383416 0.415999 0.991037 0.27271 0.909208 0.947764 0.761514 0.999458 0.269317 + 0.934693 0.0668422 0.701191 0.365339 0.436411 0.0605643 0.0737491 0.770205 0.888572 0.415395 + 0.383502 0.417486 0.910321 0.247039 0.766495 0.904653 0.500707 0.827817 0.233195 0.537304 + 0.519416 0.686773 0.762198 0.98255 0.477732 0.504523 0.384142 0.125365 0.306322 0.467917 + 0.830965 0.588977 0.262453 0.72266 0.237774 0.516292 0.277082 0.0158677 0.351015 0.287212 + 0.0345721 0.930436 0.0474645 0.753356 0.274907 0.319033 0.913817 0.688455 0.513274 0.178328 + 0.0534616 0.846167 0.736082 0.651519 0.359265 0.986642 0.529747 0.868247 0.591114 0.15372 + Index: tnt/AB10x10.dat =================================================================== RCS file: AB10x10.dat diff -N AB10x10.dat *** /dev/null Tue May 5 14:32:27 1998 --- AB10x10.dat Thu Aug 16 13:02:55 2001 *************** *** 0 **** --- 1,24 ---- + 10 10 + 0.218959 0.5297 0.526929 0.328234 0.0726859 0.166507 0.493977 0.464446 0.629543 0.845982 + 0.0470446 0.671149 0.0919649 0.632639 0.631635 0.486517 0.266145 0.94098 0.736225 0.412081 + 0.678865 0.00769819 0.653919 0.75641 0.884707 0.897656 0.0907329 0.050084 0.725412 0.841511 + 0.679296 0.383416 0.415999 0.991037 0.27271 0.909208 0.947764 0.761514 0.999458 0.269317 + 0.934693 0.0668422 0.701191 0.365339 0.436411 0.0605643 0.0737491 0.770205 0.888572 0.415395 + 0.383502 0.417486 0.910321 0.247039 0.766495 0.904653 0.500707 0.827817 0.233195 0.537304 + 0.519416 0.686773 0.762198 0.98255 0.477732 0.504523 0.384142 0.125365 0.306322 0.467917 + 0.830965 0.588977 0.262453 0.72266 0.237774 0.516292 0.277082 0.0158677 0.351015 0.287212 + 0.0345721 0.930436 0.0474645 0.753356 0.274907 0.319033 0.913817 0.688455 0.513274 0.178328 + 0.0534616 0.846167 0.736082 0.651519 0.359265 0.986642 0.529747 0.868247 0.591114 0.15372 + + 10 10 + 0.571655 0.84204 0.70982 0.387725 0.408767 0.629269 0.901673 0.365339 0.215248 0.462245 + 0.802406 0.159768 0.937897 0.499741 0.14182 0.126712 0.426497 0.253057 0.679592 0.951367 + 0.0330538 0.212752 0.239911 0.147533 0.564899 0.651254 0.142021 0.135109 0.908922 0.632739 + 0.53445 0.71471 0.180896 0.587187 0.252126 0.621634 0.947487 0.783153 0.250126 0.43933 + 0.49848 0.130427 0.31754 0.845576 0.488515 0.803073 0.410313 0.455307 0.86086 0.824697 + 0.955361 0.0909903 0.886991 0.590109 0.464031 0.247842 0.131189 0.349524 0.471262 0.688981 + 0.748293 0.274588 0.652059 0.955409 0.961095 0.476432 0.885648 0.4523 0.505956 0.702207 + 0.554584 0.0029996 0.150335 0.556146 0.126031 0.389314 0.0921736 0.808945 0.600394 0.987145 + 0.890737 0.414293 0.681346 0.148152 0.199757 0.20325 0.162199 0.931674 0.817561 0.954415 + 0.624849 0.0268763 0.385815 0.983305 0.31925 0.0283752 0.0710636 0.651646 0.755844 0.85127 + Index: tnt/Makefile =================================================================== RCS file: Makefile diff -N Makefile *** /dev/null Tue May 5 14:32:27 1998 --- Makefile Thu Aug 16 13:02:55 2001 *************** *** 0 **** --- 1,29 ---- + ### Oldham, Jeffrey D. + ### 1999 Nov 22 + ### programming + ### + ### Compile C++ Program + + WCFLAGS= -pedantic -Wall -W -Wstrict-prototypes -Wpointer-arith -Wbad-function-cast -Wcast-align -Wconversion -Wnested-externs -Wundef -Winline + CFLAGS= -g $(WCFLAGS) -I.. # -DTIME -DSTATS + CC= ${HOME}/gcc-install/gcc1/bin/gcc + CXXFLAGS= -DUSE_LIBGXX_INLINES $(CFLAGS) + CXX= ${HOME}/gcc-install/gcc1/bin/g++ + LDFLAGS= #-lm + + CCSOURCES = main.cc + + OBJECTS = $(CCSOURCES:%.cc=%.o) + + + %: %.o + $(CXX) $(CXXFLAGS) $^ $(LIBS) -o $@ $(LDFLAGS) + + clean: + rm -f *.o + + header-dependencies: + gcc -MM $(CFLAGS) $(CCSOURCES) $(CSOURCES) + + ## ADD header file dependencies + ## Create them using "gmake -k header-dependencies". Index: tnt/SPD10x10.dat =================================================================== RCS file: SPD10x10.dat diff -N SPD10x10.dat *** /dev/null Tue May 5 14:32:27 1998 --- SPD10x10.dat Thu Aug 16 13:02:55 2001 *************** *** 0 **** --- 1,11 ---- + 10 10 + 2.3186576e+00 2.1294424e+00 2.1960039e+00 2.7464350e+00 2.0762250e+00 2.3053886e+00 2.1570514e+00 1.5808710e+00 2.0909577e+00 2.4191432e+00 + 2.1294424e+00 3.1651186e+00 2.5234253e+00 3.3847286e+00 2.2593036e+00 2.7678316e+00 2.3628136e+00 1.7825304e+00 2.7783113e+00 3.2137616e+00 + 2.1960039e+00 2.5234253e+00 4.2942805e+00 3.6189729e+00 2.8497810e+00 3.2440901e+00 3.1321684e+00 2.4829696e+00 1.8009041e+00 2.8701790e+00 + 2.7464350e+00 3.3847286e+00 3.6189729e+00 5.2143007e+00 3.1447822e+00 3.5583692e+00 3.3876913e+00 2.8527866e+00 3.4629890e+00 4.1031277e+00 + 2.0762250e+00 2.2593036e+00 2.8497810e+00 3.1447822e+00 3.2581495e+00 2.6091394e+00 2.2553001e+00 1.8630124e+00 1.6701147e+00 2.3741290e+00 + 2.3053886e+00 2.7678316e+00 3.2440901e+00 3.5583692e+00 2.6091394e+00 3.8960566e+00 2.8640541e+00 2.0193737e+00 2.3733266e+00 3.5771674e+00 + 2.1570514e+00 2.3628136e+00 3.1321684e+00 3.3876913e+00 2.2553001e+00 2.8640541e+00 3.2466334e+00 2.4706183e+00 2.4036480e+00 3.0448446e+00 + 1.5808710e+00 1.7825304e+00 2.4829696e+00 2.8527866e+00 1.8630124e+00 2.0193737e+00 2.4706183e+00 2.2343394e+00 1.8592024e+00 2.2138309e+00 + 2.0909577e+00 2.7783113e+00 1.8009041e+00 3.4629890e+00 1.6701147e+00 2.3733266e+00 2.4036480e+00 1.8592024e+00 3.2183447e+00 3.1411090e+00 + 2.4191432e+00 3.2137616e+00 2.8701790e+00 4.1031277e+00 2.3741290e+00 3.5771674e+00 3.0448446e+00 2.2138309e+00 3.1411090e+00 4.1952140e+00 Index: tnt/cholesky.h =================================================================== RCS file: cholesky.h diff -N cholesky.h *** /dev/null Tue May 5 14:32:27 1998 --- cholesky.h Thu Aug 16 13:02:55 2001 *************** *** 0 **** --- 1,96 ---- + /* + * + * Template Numerical Toolkit (TNT): Linear Algebra Module + * + * Mathematical and Computational Sciences Division + * National Institute of Technology, + * Gaithersburg, MD USA + * + * + * This software was developed at the National Institute of Standards and + * Technology (NIST) by employees of the Federal Government in the course + * of their official duties. Pursuant to title 17 Section 105 of the + * United States Code, this software is not subject to copyright protection + * and is in the public domain. The Template Numerical Toolkit (TNT) is + * an experimental system. NIST assumes no responsibility whatsoever for + * its use by other parties, and makes no guarantees, expressed or implied, + * about its quality, reliability, or any other characteristic. + * + * BETA VERSION INCOMPLETE AND SUBJECT TO CHANGE + * see http://math.nist.gov/tnt for latest updates. + * + */ + + + + #ifndef CHOLESKY_H + #define CHOLESKY_H + + #include + + // index method + + namespace TNT + { + + + // + // Only upper part of A is used. Cholesky factor is returned in + // lower part of L. Returns 0 if successful, 1 otherwise. + // + template + int Cholesky_upper_factorization(SPDMatrix &A, SymmMatrix &L) + { + Subscript M = A.dim(1); + Subscript N = A.dim(2); + + assert(M == N); // make sure A is square + + // readjust size of L, if necessary + + if (M != L.dim(1) || N != L.dim(2)) + L = SymmMatrix(N,N); + + Subscript i,j,k; + + + typename SPDMatrix::element_type dot=0; + + + for (j=1; j<=N; j++) // form column j of L + { + dot= 0; + + for (i=1; i + #include + #include + #include + #ifdef TNT_USE_REGIONS + #include "tnt/region2d.h" + #endif + + namespace TNT + { + + template + class Matrix + { + + + public: + + typedef Subscript size_type; + typedef T value_type; + typedef T element_type; + typedef T* pointer; + typedef T* iterator; + typedef T& reference; + typedef const T* const_iterator; + typedef const T& const_reference; + + Subscript lbound() const { return 1;} + + protected: + Subscript m_; + Subscript n_; + Subscript mn_; // total size + T* v_; + T** row_; + T* vm1_ ; // these point to the same data, but are 1-based + T** rowm1_; + + // internal helper function to create the array + // of row pointers + + void initialize(Subscript M, Subscript N) + { + mn_ = M*N; + m_ = M; + n_ = N; + + v_ = new T[mn_]; + row_ = new T*[M]; + rowm1_ = new T*[M]; + + assert(v_ != NULL); + assert(row_ != NULL); + assert(rowm1_ != NULL); + + T* p = v_; + vm1_ = v_ - 1; + for (Subscript i=0; i &A) + { + initialize(A.m_, A.n_); + copy(A.v_); + } + + Matrix(Subscript M, Subscript N, const T& value = T()) + { + initialize(M,N); + set(value); + } + + Matrix(Subscript M, Subscript N, const T* v) + { + initialize(M,N); + copy(v); + } + + Matrix(Subscript M, Subscript N, const char *s) + { + initialize(M,N); + std::istringstream ins(s); + + Subscript i, j; + + for (i=0; i> row_[i][j]; + } + + // destructor + // + ~Matrix() + { + destroy(); + } + + + // reallocating + // + Matrix& newsize(Subscript M, Subscript N) + { + if (num_rows() == M && num_cols() == N) + return *this; + + destroy(); + initialize(M,N); + + return *this; + } + + + + + // assignments + // + Matrix& operator=(const Matrix &A) + { + if (v_ == A.v_) + return *this; + + if (m_ == A.m_ && n_ == A.n_) // no need to re-alloc + copy(A.v_); + + else + { + destroy(); + initialize(A.m_, A.n_); + copy(A.v_); + } + + return *this; + } + + Matrix& operator=(const T& scalar) + { + set(scalar); + return *this; + } + + + Subscript dim(Subscript d) const + { + #ifdef TNT_BOUNDS_CHECK + assert( d >= 1); + assert( d <= 2); + #endif + return (d==1) ? m_ : ((d==2) ? n_ : 0); + } + + Subscript num_rows() const { return m_; } + Subscript num_cols() const { return n_; } + + + + + inline T* operator[](Subscript i) + { + #ifdef TNT_BOUNDS_CHECK + assert(0<=i); + assert(i < m_) ; + #endif + return row_[i]; + } + + inline const T* operator[](Subscript i) const + { + #ifdef TNT_BOUNDS_CHECK + assert(0<=i); + assert(i < m_) ; + #endif + return row_[i]; + } + + inline reference operator()(Subscript i) + { + #ifdef TNT_BOUNDS_CHECK + assert(1<=i); + assert(i <= mn_) ; + #endif + return vm1_[i]; + } + + inline const_reference operator()(Subscript i) const + { + #ifdef TNT_BOUNDS_CHECK + assert(1<=i); + assert(i <= mn_) ; + #endif + return vm1_[i]; + } + + + + inline reference operator()(Subscript i, Subscript j) + { + #ifdef TNT_BOUNDS_CHECK + assert(1<=i); + assert(i <= m_) ; + assert(1<=j); + assert(j <= n_); + #endif + return rowm1_[i][j]; + } + + + + inline const_reference operator() (Subscript i, Subscript j) const + { + #ifdef TNT_BOUNDS_CHECK + assert(1<=i); + assert(i <= m_) ; + assert(1<=j); + assert(j <= n_); + #endif + return rowm1_[i][j]; + } + + + + #ifdef TNT_USE_REGIONS + + typedef Region2D > Region; + + + Region operator()(const Index1D &I, const Index1D &J) + { + return Region(*this, I,J); + } + + + typedef const_Region2D< Matrix > const_Region; + const_Region operator()(const Index1D &I, const Index1D &J) const + { + return const_Region(*this, I,J); + } + + #endif + + + }; + + + /* *************************** I/O ********************************/ + + template + std::ostream& operator<<(std::ostream &s, const Matrix &A) + { + Subscript M=A.num_rows(); + Subscript N=A.num_cols(); + + s << M << " " << N << "\n"; + + for (Subscript i=0; i + std::istream& operator>>(std::istream &s, Matrix &A) + { + + Subscript M, N; + + s >> M >> N; + + if ( !(M == A.num_rows() && N == A.num_cols() )) + { + A.newsize(M,N); + } + + + for (Subscript i=0; i> A[i][j]; + } + + + return s; + } + + // *******************[ basic matrix algorithms ]*************************** + + + template + Matrix operator+(const Matrix &A, + const Matrix &B) + { + Subscript M = A.num_rows(); + Subscript N = A.num_cols(); + + assert(M==B.num_rows()); + assert(N==B.num_cols()); + + Matrix tmp(M,N); + Subscript i,j; + + for (i=0; i + Matrix operator-(const Matrix &A, + const Matrix &B) + { + Subscript M = A.num_rows(); + Subscript N = A.num_cols(); + + assert(M==B.num_rows()); + assert(N==B.num_cols()); + + Matrix tmp(M,N); + Subscript i,j; + + for (i=0; i + Matrix mult_element(const Matrix &A, + const Matrix &B) + { + Subscript M = A.num_rows(); + Subscript N = A.num_cols(); + + assert(M==B.num_rows()); + assert(N==B.num_cols()); + + Matrix tmp(M,N); + Subscript i,j; + + for (i=0; i + Matrix transpose(const Matrix &A) + { + Subscript M = A.num_rows(); + Subscript N = A.num_cols(); + + Matrix S(N,M); + Subscript i, j; + + for (i=0; i + inline Matrix matmult(const Matrix &A, + const Matrix &B) + { + + #ifdef TNT_BOUNDS_CHECK + assert(A.num_cols() == B.num_rows()); + #endif + + Subscript M = A.num_rows(); + Subscript N = A.num_cols(); + Subscript K = B.num_cols(); + + Matrix tmp(M,K); + T sum; + + for (Subscript i=0; i + inline Matrix operator*(const Matrix &A, + const Matrix &B) + { + return matmult(A,B); + } + + template + inline int matmult(Matrix& C, const Matrix &A, + const Matrix &B) + { + + assert(A.num_cols() == B.num_rows()); + + Subscript M = A.num_rows(); + Subscript N = A.num_cols(); + Subscript K = B.num_cols(); + + C.newsize(M,K); + + T sum; + + const T* row_i; + const T* col_k; + + for (Subscript i=0; i + Vector matmult(const Matrix &A, const Vector &x) + { + + #ifdef TNT_BOUNDS_CHECK + assert(A.num_cols() == x.dim()); + #endif + + Subscript M = A.num_rows(); + Subscript N = A.num_cols(); + + Vector tmp(M); + T sum; + + for (Subscript i=0; i + inline Vector operator*(const Matrix &A, const Vector &x) + { + return matmult(A,x); + } + + } // namespace TNT + + #endif + // CMAT_H Index: tnt/fchol.cc =================================================================== RCS file: fchol.cc diff -N fchol.cc *** /dev/null Tue May 5 14:32:27 1998 --- fchol.cc Thu Aug 16 13:02:55 2001 *************** *** 0 **** --- 1,60 ---- + + + + // Test Cholesky module + + #include + + #include "tnt/tnt.h" + #include "tnt/vec.h" + #include "tnt/fmat.h" + #include "tnt/cholesky.h" + #include "tnt/trisolve.h" + #include "tnt/transv.h" /* transpose views */ + + using namespace std; + using namespace TNT; + + int main() + { + Fortran_Matrix A; + + cin >> A; /* A should be symmetric positive definite */ + + Subscript N = A.num_rows(); + assert(N == A.num_cols()); + + Vector b(N, 1.0); // b= [1,1,1,...] + Fortran_Matrix L(N, N); + + + cout << "A: " << A << endl; + + if (Cholesky_upper_factorization(A, L) !=0) + { + cout << "Cholesky did not work." << endl; + exit(1); + } + + + cout << L << endl; + + // solve Ax =b, as L*L'x =b + // + // let y=L'x, then + // + // + // solve L y = b; + // solve L'x = y; + + Vector y = Lower_triangular_solve(L, b); + TNT::Transpose_View > foo(L); + Vector x1= + Upper_triangular_solve(Transpose_View >(L), y); + Vector x= Upper_triangular_solve(foo, y); + + cout << "x: " << x << endl; + cout << "Residual A*x-b: " << A*x-b << endl; + + return 0; + } Index: tnt/fcscmat.h =================================================================== RCS file: fcscmat.h diff -N fcscmat.h *** /dev/null Tue May 5 14:32:27 1998 --- fcscmat.h Thu Aug 16 13:02:55 2001 *************** *** 0 **** --- 1,165 ---- + /* + * + * Template Numerical Toolkit (TNT): Linear Algebra Module + * + * Mathematical and Computational Sciences Division + * National Institute of Technology, + * Gaithersburg, MD USA + * + * + * This software was developed at the National Institute of Standards and + * Technology (NIST) by employees of the Federal Government in the course + * of their official duties. Pursuant to title 17 Section 105 of the + * United States Code, this software is not subject to copyright protection + * and is in the public domain. The Template Numerical Toolkit (TNT) is + * an experimental system. NIST assumes no responsibility whatsoever for + * its use by other parties, and makes no guarantees, expressed or implied, + * about its quality, reliability, or any other characteristic. + * + * BETA VERSION INCOMPLETE AND SUBJECT TO CHANGE + * see http://math.nist.gov/tnt for latest updates. + * + */ + + + + // Templated compressed sparse column matrix (Fortran conventions). + // uses 1-based offsets in storing row indices. + // Used primarily to interface with Fortran sparse matrix libaries. + // (CANNOT BE USED AS AN STL CONTAINER.) + + + #ifndef FCSCMAT_H + #define FCSCMAT_H + + #include + #include + #include "tnt/tnt.h" + #include "tnt/vec.h" + + using namespace std; + + namespace TNT + { + + template + class Fortran_Sparse_Col_Matrix + { + + protected: + + Vector val_; // data values (nz_ elements) + Vector rowind_; // row_ind (nz_ elements) + Vector colptr_; // col_ptr (n_+1 elements) + + int nz_; // number of nonzeros + Subscript m_; // global dimensions + Subscript n_; + + public: + + + Fortran_Sparse_Col_Matrix(void); + Fortran_Sparse_Col_Matrix(const Fortran_Sparse_Col_Matrix &S) + : val_(S.val_), rowind_(S.rowind_), colptr_(S.colptr_), nz_(S.nz_), + m_(S.m_), n_(S.n_) {}; + Fortran_Sparse_Col_Matrix(Subscript M, Subscript N, + Subscript nz, const T *val, const Subscript *r, + const Subscript *c) : val_(nz, val), rowind_(nz, r), + colptr_(N+1, c), nz_(nz), m_(M), n_(N) {}; + + Fortran_Sparse_Col_Matrix(Subscript M, Subscript N, + Subscript nz, char *val, char *r, + char *c) : val_(nz, val), rowind_(nz, r), + colptr_(N+1, c), nz_(nz), m_(M), n_(N) {}; + + Fortran_Sparse_Col_Matrix(Subscript M, Subscript N, + Subscript nz, const T *val, Subscript *r, Subscript *c) + : val_(nz, val), rowind_(nz, r), colptr_(N+1, c), nz_(nz), + m_(M), n_(N) {}; + + ~Fortran_Sparse_Col_Matrix() {}; + + + T & val(Subscript i) { return val_(i); } + const T & val(Subscript i) const { return val_(i); } + + Subscript & row_ind(Subscript i) { return rowind_(i); } + const Subscript & row_ind(Subscript i) const { return rowind_(i); } + + Subscript col_ptr(Subscript i) { return colptr_(i);} + const Subscript col_ptr(Subscript i) const { return colptr_(i);} + + + Subscript num_cols() const { return m_;} + Subscript num_rows() const { return n_; } + + Subscript dim(Subscript i) const + { + #ifdef TNT_BOUNDS_CHECK + assert( 1 <= i ); + assert( i <= 2 ); + #endif + if (i==1) return m_; + else if (i==2) return m_; + else return 0; + } + + Subscript num_nonzeros() const {return nz_;}; + Subscript lbound() const {return 1;} + + + + Fortran_Sparse_Col_Matrix& operator=(const + Fortran_Sparse_Col_Matrix &C) + { + val_ = C.val_; + rowind_ = C.rowind_; + colptr_ = C.colptr_; + nz_ = C.nz_; + m_ = C.m_; + n_ = C.n_; + + return *this; + } + + Fortran_Sparse_Col_Matrix& newsize(Subscript M, Subscript N, + Subscript nz) + { + val_.newsize(nz); + rowind_.newsize(nz); + colptr_.newsize(N+1); + return *this; + } + }; + + template + ostream& operator<<(ostream &s, const Fortran_Sparse_Col_Matrix &A) + { + Subscript M=A.num_rows(); + Subscript N=A.num_cols(); + + s << M << " " << N << " " << A.num_nonzeros() << endl; + + + for (Subscript k=1; k<=N; k++) + { + Subscript start = A.col_ptr(k); + Subscript end = A.col_ptr(k+1); + + for (Subscript i= start; i + #include + #include + #include + #ifdef TNT_USE_REGIONS + #include "tnt/region2d.h" + #endif + + // simple 1-based, column oriented Matrix class + + namespace TNT + { + + template + class Fortran_Matrix + { + + + public: + + typedef T value_type; + typedef T element_type; + typedef T* pointer; + typedef T* iterator; + typedef T& reference; + typedef const T* const_iterator; + typedef const T& const_reference; + + Subscript lbound() const { return 1;} + + protected: + T* v_; // these are adjusted to simulate 1-offset + Subscript m_; + Subscript n_; + T** col_; // these are adjusted to simulate 1-offset + + // internal helper function to create the array + // of row pointers + + void initialize(Subscript M, Subscript N) + { + // adjust col_[] pointers so that they are 1-offset: + // col_[j][i] is really col_[j-1][i-1]; + // + // v_[] is the internal contiguous array, it is still 0-offset + // + v_ = new T[M*N]; + col_ = new T*[N]; + + assert(v_ != NULL); + assert(col_ != NULL); + + + m_ = M; + n_ = N; + T* p = v_ - 1; + for (Subscript i=0; i &A) + { + initialize(A.m_, A.n_); + copy(A.v_); + } + + Fortran_Matrix(Subscript M, Subscript N, const T& value = T()) + { + initialize(M,N); + set(value); + } + + Fortran_Matrix(Subscript M, Subscript N, const T* v) + { + initialize(M,N); + copy(v); + } + + + Fortran_Matrix(Subscript M, Subscript N, char *s) + { + initialize(M,N); + std::istringstream ins(s); + + Subscript i, j; + + for (i=1; i<=M; i++) + for (j=1; j<=N; j++) + ins >> (*this)(i,j); + } + + // destructor + ~Fortran_Matrix() + { + destroy(); + } + + + // assignments + // + Fortran_Matrix& operator=(const Fortran_Matrix &A) + { + if (v_ == A.v_) + return *this; + + if (m_ == A.m_ && n_ == A.n_) // no need to re-alloc + copy(A.v_); + + else + { + destroy(); + initialize(A.m_, A.n_); + copy(A.v_); + } + + return *this; + } + + Fortran_Matrix& operator=(const T& scalar) + { + set(scalar); + return *this; + } + + + Subscript dim(Subscript d) const + { + #ifdef TNT_BOUNDS_CHECK + assert( d >= 1); + assert( d <= 2); + #endif + return (d==1) ? m_ : ((d==2) ? n_ : 0); + } + + Subscript num_rows() const { return m_; } + Subscript num_cols() const { return n_; } + + Fortran_Matrix& newsize(Subscript M, Subscript N) + { + if (num_rows() == M && num_cols() == N) + return *this; + + destroy(); + initialize(M,N); + + return *this; + } + + + + // 1-based element access + // + inline reference operator()(Subscript i, Subscript j) + { + #ifdef TNT_BOUNDS_CHECK + assert(1<=i); + assert(i <= m_) ; + assert(1<=j); + assert(j <= n_); + #endif + return col_[j][i]; + } + + inline const_reference operator() (Subscript i, Subscript j) const + { + #ifdef TNT_BOUNDS_CHECK + assert(1<=i); + assert(i <= m_) ; + assert(1<=j); + assert(j <= n_); + #endif + return col_[j][i]; + } + + + #ifdef TNT_USE_REGIONS + + typedef Region2D > Region; + typedef const_Region2D< Fortran_Matrix > const_Region; + + Region operator()(const Index1D &I, const Index1D &J) + { + return Region(*this, I,J); + } + + const_Region operator()(const Index1D &I, const Index1D &J) const + { + return const_Region(*this, I,J); + } + + #endif + + + }; + + + /* *************************** I/O ********************************/ + + template + std::ostream& operator<<(std::ostream &s, const Fortran_Matrix &A) + { + Subscript M=A.num_rows(); + Subscript N=A.num_cols(); + + s << M << " " << N << "\n"; + + for (Subscript i=1; i<=M; i++) + { + for (Subscript j=1; j<=N; j++) + { + s << A(i,j) << " "; + } + s << "\n"; + } + + + return s; + } + + template + std::istream& operator>>(std::istream &s, Fortran_Matrix &A) + { + + Subscript M, N; + + s >> M >> N; + + if ( !(M == A.num_rows() && N == A.num_cols())) + { + A.newsize(M,N); + } + + + for (Subscript i=1; i<=M; i++) + for (Subscript j=1; j<=N; j++) + { + s >> A(i,j); + } + + + return s; + } + + // *******************[ basic matrix algorithms ]*************************** + + + template + Fortran_Matrix operator+(const Fortran_Matrix &A, + const Fortran_Matrix &B) + { + Subscript M = A.num_rows(); + Subscript N = A.num_cols(); + + assert(M==B.num_rows()); + assert(N==B.num_cols()); + + Fortran_Matrix tmp(M,N); + Subscript i,j; + + for (i=1; i<=M; i++) + for (j=1; j<=N; j++) + tmp(i,j) = A(i,j) + B(i,j); + + return tmp; + } + + template + Fortran_Matrix operator-(const Fortran_Matrix &A, + const Fortran_Matrix &B) + { + Subscript M = A.num_rows(); + Subscript N = A.num_cols(); + + assert(M==B.num_rows()); + assert(N==B.num_cols()); + + Fortran_Matrix tmp(M,N); + Subscript i,j; + + for (i=1; i<=M; i++) + for (j=1; j<=N; j++) + tmp(i,j) = A(i,j) - B(i,j); + + return tmp; + } + + // element-wise multiplication (use matmult() below for matrix + // multiplication in the linear algebra sense.) + // + // + template + Fortran_Matrix mult_element(const Fortran_Matrix &A, + const Fortran_Matrix &B) + { + Subscript M = A.num_rows(); + Subscript N = A.num_cols(); + + assert(M==B.num_rows()); + assert(N==B.num_cols()); + + Fortran_Matrix tmp(M,N); + Subscript i,j; + + for (i=1; i<=M; i++) + for (j=1; j<=N; j++) + tmp(i,j) = A(i,j) * B(i,j); + + return tmp; + } + + + template + Fortran_Matrix transpose(const Fortran_Matrix &A) + { + Subscript M = A.num_rows(); + Subscript N = A.num_cols(); + + Fortran_Matrix S(N,M); + Subscript i, j; + + for (i=1; i<=M; i++) + for (j=1; j<=N; j++) + S(j,i) = A(i,j); + + return S; + } + + + + template + inline Fortran_Matrix matmult(const Fortran_Matrix &A, + const Fortran_Matrix &B) + { + + #ifdef TNT_BOUNDS_CHECK + assert(A.num_cols() == B.num_rows()); + #endif + + Subscript M = A.num_rows(); + Subscript N = A.num_cols(); + Subscript K = B.num_cols(); + + Fortran_Matrix tmp(M,K); + T sum; + + for (Subscript i=1; i<=M; i++) + for (Subscript k=1; k<=K; k++) + { + sum = 0; + for (Subscript j=1; j<=N; j++) + sum = sum + A(i,j) * B(j,k); + + tmp(i,k) = sum; + } + + return tmp; + } + + template + inline Fortran_Matrix operator*(const Fortran_Matrix &A, + const Fortran_Matrix &B) + { + return matmult(A,B); + } + + template + inline int matmult(Fortran_Matrix& C, const Fortran_Matrix &A, + const Fortran_Matrix &B) + { + + assert(A.num_cols() == B.num_rows()); + + Subscript M = A.num_rows(); + Subscript N = A.num_cols(); + Subscript K = B.num_cols(); + + C.newsize(M,K); // adjust shape of C, if necessary + + + T sum; + + const T* row_i; + const T* col_k; + + for (Subscript i=1; i<=M; i++) + { + for (Subscript k=1; k<=K; k++) + { + row_i = &A(i,1); + col_k = &B(1,k); + sum = 0; + for (Subscript j=1; j<=N; j++) + { + sum += *row_i * *col_k; + row_i += M; + col_k ++; + } + + C(i,k) = sum; + } + + } + + return 0; + } + + + template + Vector matmult(const Fortran_Matrix &A, const Vector &x) + { + + #ifdef TNT_BOUNDS_CHECK + assert(A.num_cols() == x.dim()); + #endif + + Subscript M = A.num_rows(); + Subscript N = A.num_cols(); + + Vector tmp(M); + T sum; + + for (Subscript i=1; i<=M; i++) + { + sum = 0; + for (Subscript j=1; j<=N; j++) + sum = sum + A(i,j) * x(j); + + tmp(i) = sum; + } + + return tmp; + } + + template + inline Vector operator*(const Fortran_Matrix &A, const Vector &x) + { + return matmult(A,x); + } + + template + inline Fortran_Matrix operator*(const Fortran_Matrix &A, const T &x) + { + Subscript M = A.num_rows(); + Subscript N = A.num_cols(); + + Subscript MN = M*N; + + Fortran_Matrix res(M,N); + const T* a = A.begin(); + T* t = res.begin(); + T* tend = res.end(); + + for (t=res.begin(); t < tend; t++, a++) + *t = *a * x; + + return res; + } + + } // namespace TNT + #endif + // FMAT_H Index: tnt/fortran.h =================================================================== RCS file: fortran.h diff -N fortran.h *** /dev/null Tue May 5 14:32:27 1998 --- fortran.h Thu Aug 16 13:02:55 2001 *************** *** 0 **** --- 1,67 ---- + /* + * + * Template Numerical Toolkit (TNT): Linear Algebra Module + * + * Mathematical and Computational Sciences Division + * National Institute of Technology, + * Gaithersburg, MD USA + * + * + * This software was developed at the National Institute of Standards and + * Technology (NIST) by employees of the Federal Government in the course + * of their official duties. Pursuant to title 17 Section 105 of the + * United States Code, this software is not subject to copyright protection + * and is in the public domain. The Template Numerical Toolkit (TNT) is + * an experimental system. NIST assumes no responsibility whatsoever for + * its use by other parties, and makes no guarantees, expressed or implied, + * about its quality, reliability, or any other characteristic. + * + * BETA VERSION INCOMPLETE AND SUBJECT TO CHANGE + * see http://math.nist.gov/tnt for latest updates. + * + */ + + + + // Header file to define C/Fortran conventions (Platform specific) + + #ifndef FORTRAN_H + #define FORTRAN_H + + // help map between C/C++ data types and Fortran types + + typedef int Fortran_integer; + typedef float Fortran_float; + typedef double Fortran_double; + + + typedef Fortran_double *fda_; // (in/out) double precision array + typedef const Fortran_double *cfda_; // (in) double precsion array + + typedef Fortran_double *fd_; // (in/out) single double precision + typedef const Fortran_double *cfd_; // (in) single double precision + + typedef Fortran_float *ffa_; // (in/out) float precision array + typedef const Fortran_float *cffa_; // (in) float precsion array + + typedef Fortran_float *ff_; // (in/out) single float precision + typedef const Fortran_float *cff_; // (in) single float precision + + typedef Fortran_integer *fia_; // (in/out) single integer array + typedef const Fortran_integer *cfia_; // (in) single integer array + + typedef Fortran_integer *fi_; // (in/out) single integer + typedef const Fortran_integer *cfi_; // (in) single integer + + typedef char *fch_; // (in/out) single character + typedef char *cfch_; // (in) single character + + + + #ifndef TNT_SUBSCRIPT_TYPE + #define TNT_SUBSCRIPT_TYPE TNT::Fortran_integer + #endif + + + #endif + // FORTRAN_H Index: tnt/fspvec.h =================================================================== RCS file: fspvec.h diff -N fspvec.h *** /dev/null Tue May 5 14:32:27 1998 --- fspvec.h Thu Aug 16 13:02:55 2001 *************** *** 0 **** --- 1,168 ---- + /* + * + * Template Numerical Toolkit (TNT): Linear Algebra Module + * + * Mathematical and Computational Sciences Division + * National Institute of Technology, + * Gaithersburg, MD USA + * + * + * This software was developed at the National Institute of Standards and + * Technology (NIST) by employees of the Federal Government in the course + * of their official duties. Pursuant to title 17 Section 105 of the + * United States Code, this software is not subject to copyright protection + * and is in the public domain. The Template Numerical Toolkit (TNT) is + * an experimental system. NIST assumes no responsibility whatsoever for + * its use by other parties, and makes no guarantees, expressed or implied, + * about its quality, reliability, or any other characteristic. + * + * BETA VERSION INCOMPLETE AND SUBJECT TO CHANGE + * see http://math.nist.gov/tnt for latest updates. + * + */ + + + // Templated sparse vector (Fortran conventions). + // Used primarily to interface with Fortran sparse matrix libaries. + // (CANNOT BE USED AS AN STL CONTAINER.) + + #ifndef FSPVEC_H + #define FSPVEC_H + + #include "tnt/tnt.h" + #include "tnt/vec.h" + #include + #include + #include + #include + + using namespace std; + + namespace TNT + { + + template + class Fortran_Sparse_Vector + { + + + public: + + typedef Subscript size_type; + typedef T value_type; + typedef T element_type; + typedef T* pointer; + typedef T* iterator; + typedef T& reference; + typedef const T* const_iterator; + typedef const T& const_reference; + + Subscript lbound() const { return 1;} + + protected: + Vector val_; + Vector index_; + Subscript dim_; // prescribed dimension + + + public: + + // size and shape information + + Subscript dim() const { return dim_; } + Subscript num_nonzeros() const { return val_.dim(); } + + // access + + T& val(Subscript i) { return val_(i); } + const T& val(Subscript i) const { return val_(i); } + + Subscript &index(Subscript i) { return index_(i); } + const Subscript &index(Subscript i) const { return index_(i); } + + // constructors + + Fortran_Sparse_Vector() : val_(), index_(), dim_(0) {}; + Fortran_Sparse_Vector(Subscript N, Subscript nz) : val_(nz), + index_(nz), dim_(N) {}; + Fortran_Sparse_Vector(Subscript N, Subscript nz, const T *values, + const Subscript *indices): val_(nz, values), index_(nz, indices), + dim_(N) {} + + Fortran_Sparse_Vector(const Fortran_Sparse_Vector &S): + val_(S.val_), index_(S.index_), dim_(S.dim_) {} + + // initialize from string, e.g. + // + // Fortran_Sparse_Vector A(N, 2, "1.0 2.1", "1 3"); + // + Fortran_Sparse_Vector(Subscript N, Subscript nz, char *v, + char *ind) : val_(nz, v), index_(nz, ind), dim_(N) {} + + // assignments + + Fortran_Sparse_Vector & newsize(Subscript N, Subscript nz) + { + val_.newsize(nz); + index_.newsize(nz); + dim_ = N; + return *this; + } + + Fortran_Sparse_Vector & operator=( const Fortran_Sparse_Vector &A) + { + val_ = A.val_; + index_ = A.index_; + dim_ = A.dim_; + + return *this; + } + + // methods + + + + }; + + + /* *************************** I/O ********************************/ + + template + ostream& operator<<(ostream &s, const Fortran_Sparse_Vector &A) + { + // output format is : N nz val1 ind1 val2 ind2 ... + Subscript nz=A.num_nonzeros(); + + s << A.dim() << " " << nz << endl; + + for (Subscript i=1; i<=nz; i++) + s << A.val(i) << " " << A.index(i) << endl; + s << endl; + + return s; + } + + + template + istream& operator>>(istream &s, Fortran_Sparse_Vector &A) + { + // output format is : N nz val1 ind1 val2 ind2 ... + + Subscript N; + Subscript nz; + + s >> N >> nz; + + A.newsize(N, nz); + + for (Subscript i=1; i<=nz; i++) + s >> A.val(i) >> A.index(i); + + + return s; + } + + } // namespace TNT + + #endif + // FSPVEC_H Index: tnt/index.h =================================================================== RCS file: index.h diff -N index.h *** /dev/null Tue May 5 14:32:27 1998 --- index.h Thu Aug 16 13:02:55 2001 *************** *** 0 **** --- 1,83 ---- + /* + * + * Template Numerical Toolkit (TNT): Linear Algebra Module + * + * Mathematical and Computational Sciences Division + * National Institute of Technology, + * Gaithersburg, MD USA + * + * + * This software was developed at the National Institute of Standards and + * Technology (NIST) by employees of the Federal Government in the course + * of their official duties. Pursuant to title 17 Section 105 of the + * United States Code, this software is not subject to copyright protection + * and is in the public domain. The Template Numerical Toolkit (TNT) is + * an experimental system. NIST assumes no responsibility whatsoever for + * its use by other parties, and makes no guarantees, expressed or implied, + * about its quality, reliability, or any other characteristic. + * + * BETA VERSION INCOMPLETE AND SUBJECT TO CHANGE + * see http://math.nist.gov/tnt for latest updates. + * + */ + + + + // Vector/Matrix/Array Index Module + + #ifndef INDEX_H + #define INDEX_H + + #include "tnt/subscript.h" + + namespace TNT + { + + class Index1D + { + Subscript lbound_; + Subscript ubound_; + + public: + + Subscript lbound() const { return lbound_; } + Subscript ubound() const { return ubound_; } + + Index1D(const Index1D &D) : lbound_(D.lbound_), ubound_(D.ubound_) {} + Index1D(Subscript i1, Subscript i2) : lbound_(i1), ubound_(i2) {} + + Index1D & operator=(const Index1D &D) + { + lbound_ = D.lbound_; + ubound_ = D.ubound_; + return *this; + } + + }; + + inline Index1D operator+(const Index1D &D, Subscript i) + { + return Index1D(i+D.lbound(), i+D.ubound()); + } + + inline Index1D operator+(Subscript i, const Index1D &D) + { + return Index1D(i+D.lbound(), i+D.ubound()); + } + + + + inline Index1D operator-(Index1D &D, Subscript i) + { + return Index1D(D.lbound()-i, D.ubound()-i); + } + + inline Index1D operator-(Subscript i, Index1D &D) + { + return Index1D(i-D.lbound(), i-D.ubound()); + } + + } // namespace TNT + + #endif + Index: tnt/lapack.h =================================================================== RCS file: lapack.h diff -N lapack.h *** /dev/null Tue May 5 14:32:27 1998 --- lapack.h Thu Aug 16 13:02:55 2001 *************** *** 0 **** --- 1,193 ---- + /* + * + * Template Numerical Toolkit (TNT): Linear Algebra Module + * + * Mathematical and Computational Sciences Division + * National Institute of Technology, + * Gaithersburg, MD USA + * + * + * This software was developed at the National Institute of Standards and + * Technology (NIST) by employees of the Federal Government in the course + * of their official duties. Pursuant to title 17 Section 105 of the + * United States Code, this software is not subject to copyright protection + * and is in the public domain. The Template Numerical Toolkit (TNT) is + * an experimental system. NIST assumes no responsibility whatsoever for + * its use by other parties, and makes no guarantees, expressed or implied, + * about its quality, reliability, or any other characteristic. + * + * BETA VERSION INCOMPLETE AND SUBJECT TO CHANGE + * see http://math.nist.gov/tnt for latest updates. + * + */ + + + + // Header file for Fortran Lapack + + #ifndef LAPACK_H + #define LAPACK_H + + // This file incomplete and included here to only demonstrate the + // basic framework for linking with the Fortran Lapack routines. + + #include "tnt/fortran.h" + #include "tnt/vec.h" + #include "tnt/fmat.h" + + + #define F77_DGESV dgesv_ + #define F77_DGELS dgels_ + #define F77_DSYEV dsyev_ + #define F77_DGEEV dgeev_ + + extern "C" + { + + // linear equations (general) using LU factorizaiton + // + void F77_DGESV(cfi_ N, cfi_ nrhs, fda_ A, cfi_ lda, + fia_ ipiv, fda_ b, cfi_ ldb, fi_ info); + + // solve linear least squares using QR or LU factorization + // + void F77_DGELS(cfch_ trans, cfi_ M, + cfi_ N, cfi_ nrhs, fda_ A, cfi_ lda, fda_ B, cfi_ ldb, fda_ work, + cfi_ lwork, fi_ info); + + // solve symmetric eigenvalues + // + void F77_DSYEV( cfch_ jobz, cfch_ uplo, cfi_ N, fda_ A, cfi_ lda, + fda_ W, fda_ work, cfi_ lwork, fi_ info); + + // solve unsymmetric eigenvalues + // + void F77_DGEEV(cfch_ jobvl, cfch_ jobvr, cfi_ N, fda_ A, cfi_ lda, + fda_ wr, fda_ wi, fda_ vl, cfi_ ldvl, fda_ vr, + cfi_ ldvr, fda_ work, cfi_ lwork, fi_ info); + + } + + // solve linear equations using LU factorization + + using namespace TNT; + + Vector Lapack_LU_linear_solve(const Fortran_Matrix &A, + const Vector &b) + { + const Fortran_integer one=1; + Subscript M=A.num_rows(); + Subscript N=A.num_cols(); + + Fortran_Matrix Tmp(A); + Vector x(b); + Vector index(M); + Fortran_integer info = 0; + + F77_DGESV(&N, &one, &Tmp(1,1), &M, &index(1), &x(1), &M, &info); + + if (info != 0) return Vector(0); + else + return x; + } + + // solve linear least squares problem using QR factorization + // + Vector Lapack_LLS_QR_linear_solve(const Fortran_Matrix &A, + const Vector &b) + { + const Fortran_integer one=1; + Subscript M=A.num_rows(); + Subscript N=A.num_cols(); + + Fortran_Matrix Tmp(A); + Vector x(b); + Fortran_integer info = 0; + + char transp = 'N'; + Fortran_integer lwork = 5 * (M+N); // temporary work space + Vector work(lwork); + + F77_DGELS(&transp, &M, &N, &one, &Tmp(1,1), &M, &x(1), &M, &work(1), + &lwork, &info); + + if (info != 0) return Vector(0); + else + return x; + } + + // *********************** Eigenvalue problems ******************* + + // solve symmetric eigenvalue problem (eigenvalues only) + // + Vector Upper_symmetric_eigenvalue_solve(const Fortran_Matrix &A) + { + char jobz = 'N'; + char uplo = 'U'; + Subscript N = A.num_rows(); + + assert(N == A.num_cols()); + + Vector eigvals(N); + Fortran_integer worksize = 3*N; + Fortran_integer info = 0; + Vector work(worksize); + Fortran_Matrix Tmp = A; + + F77_DSYEV(&jobz, &uplo, &N, &Tmp(1,1), &N, eigvals.begin(), work.begin(), + &worksize, &info); + + if (info != 0) return Vector(); + else + return eigvals; + } + + + // solve unsymmetric eigenvalue problems + // + int eigenvalue_solve(const Fortran_Matrix &A, + Vector &wr, Vector &wi) + { + char jobvl = 'N'; + char jobvr = 'N'; + + Fortran_integer N = A.num_rows(); + + + assert(N == A.num_cols()); + + if (N<1) return 1; + + Fortran_Matrix vl(1,N); /* should be NxN ? **** */ + Fortran_Matrix vr(1,N); + Fortran_integer one = 1; + + Fortran_integer worksize = 5*N; + Fortran_integer info = 0; + Vector work(worksize, 0.0); + Fortran_Matrix Tmp = A; + + wr.newsize(N); + wi.newsize(N); + + // void F77_DGEEV(cfch_ jobvl, cfch_ jobvr, cfi_ N, fda_ A, cfi_ lda, + // fda_ wr, fda_ wi, fda_ vl, cfi_ ldvl, fda_ vr, + // cfi_ ldvr, fda_ work, cfi_ lwork, fi_ info); + + F77_DGEEV(&jobvl, &jobvr, &N, &Tmp(1,1), &N, &(wr(1)), + &(wi(1)), &(vl(1,1)), &one, &(vr(1,1)), &one, + &(work(1)), &worksize, &info); + + return (info==0 ? 0: 1); + } + + + + + + #endif + // LAPACK_H + + + + Index: tnt/lu-C.cc =================================================================== RCS file: lu-C.cc diff -N lu-C.cc *** /dev/null Tue May 5 14:32:27 1998 --- lu-C.cc Thu Aug 16 13:02:55 2001 *************** *** 0 **** --- 1,57 ---- + // Solve a linear system using LU factorization. + // + // Usage: a.out < matrix.dat + // + // where matrix.dat is an ASCII file consisting of the + // matrix size (M,N) followed by its values. For example, + // + // 3 3 + // 8.1 1.2 4.3 + // 1.3 4.3 2.9 + // 0.4 1.3 6.1 + + #include + + #include "tnt/tnt.h" + #include "tnt/vec.h" + #include "tnt/cmat.h" + #include "tnt/lu.h" + + using namespace std; + using namespace TNT; + + int main() + { + Matrix A; + + cin >> A; + + Subscript N = A.dim(1); + assert(N == A.dim(2)); + + Vector b(N, 1.0); // b= [1,1,1,...] + Vector index(N); + + cout << "Original Matrix A: " << A << endl; + + Matrix T(A); + if (LU_factor(T, index) !=0) + { + cout << "LU_factor() failed." << endl; + exit(1); + } + + Vector x(b); + if (LU_solve(T, index, x) != 0) + { + cout << "LU_Solve() failed." << endl; + exit(1); + } + cout << "Solution x for Ax=b, where b=[1,1,...] " < + + #include "tnt/tnt.h" + #include "tnt/vec.h" + #include "tnt/fmat.h" + #include "tnt/lu.h" + + using namespace std; + using namespace TNT; + + int main() + { + Fortran_Matrix A; + + cin >> A; + + + Subscript N = A.dim(1); + assert(N == A.dim(2)); + + Vector b(N, 1.0); // b= [1,1,1,...] + Vector index(N); + + + + cout << "Original Matrix A: " << A << endl; + + Fortran_Matrix T(A); + if (LU_factor(T, index) !=0) + { + cout << "LU_factor() failed." << endl; + exit(1); + } + + Vector x(b); + if (LU_solve(T, index, x) != 0) + { + cout << "LU_Solve() failed." << endl; + exit(1); + } + cout << "Solution x for Ax=b, where b=[1,1,...] " < A; + // Vector ipiv; + // Vector b; + // + // 1) LU_factor(A,ipiv); + // 2) LU_solve(A,ipiv,b); + // + // Now b has the solution x. Note that both A and b + // are overwritten. If these values need to be preserved, + // one can make temporary copies, as in + // + // O) Matrix T = A; + // 1) LU_factor(T,ipiv); + // 1a) Vector x=b; + // 2) LU_solve(T,ipiv,x); + // + // See details below. + // + + + // for fabs() + // + #include + + // right-looking LU factorization algorithm (unblocked) + // + // Factors matrix A into lower and upper triangular matrices + // (L and U respectively) in solving the linear equation Ax=b. + // + // + // Args: + // + // A (input/output) Matrix(1:n, 1:n) In input, matrix to be + // factored. On output, overwritten with lower and + // upper triangular factors. + // + // indx (output) Vector(1:n) Pivot vector. Describes how + // the rows of A were reordered to increase + // numerical stability. + // + // Return value: + // + // int (0 if successful, 1 otherwise) + // + // + + + namespace TNT + { + + template + int LU_factor( MaTRiX &A, VecToRSubscript &indx) + { + assert(A.lbound() == 1); // currently for 1-offset + assert(indx.lbound() == 1); // vectors and matrices + + Subscript M = A.num_rows(); + Subscript N = A.num_cols(); + + if (M == 0 || N==0) return 0; + if (indx.dim() != M) + indx.newsize(M); + + Subscript i=0,j=0,k=0; + Subscript jp=0; + + typename MaTRiX::element_type t; + + Subscript minMN = (M < N ? M : N) ; // min(M,N); + + for (j=1; j<= minMN; j++) + { + + // find pivot in column j and test for singularity. + + jp = j; + t = fabs(A(j,j)); + for (i=j+1; i<=M; i++) + if ( fabs(A(i,j)) > t) + { + jp = i; + t = fabs(A(i,j)); + } + + indx(j) = jp; + + // jp now has the index of maximum element + // of column j, below the diagonal + + if ( A(jp,j) == 0 ) + return 1; // factorization failed because of zero pivot + + + if (jp != j) // swap rows j and jp + for (k=1; k<=N; k++) + { + t = A(j,k); + A(j,k) = A(jp,k); + A(jp,k) =t; + } + + if (j + int LU_solve(const MaTRiX &A, const VecToRSubscripts &indx, VecToR &b) + { + assert(A.lbound() == 1); // currently for 1-offset + assert(indx.lbound() == 1); // vectors and matrices + assert(b.lbound() == 1); + + Subscript i,ii=0,ip,j; + Subscript n = b.dim(); + typename MaTRiX::element_type sum = 0.0; + + for (i=1;i<=n;i++) + { + ip=indx(i); + sum=b(ip); + b(ip)=b(i); + if (ii) + for (j=ii;j<=i-1;j++) + sum -= A(i,j)*b(j); + else if (sum) ii=i; + b(i)=sum; + } + for (i=n;i>=1;i--) + { + sum=b(i); + for (j=i+1;j<=n;j++) + sum -= A(i,j)*b(j); + b(i)=sum/A(i,i); + } + + return 0; + } + + } // namespace TNT + + #endif + // LU_H Index: tnt/matrix.dat =================================================================== RCS file: matrix.dat diff -N matrix.dat *** /dev/null Tue May 5 14:32:27 1998 --- matrix.dat Thu Aug 16 13:02:56 2001 *************** *** 0 **** --- 1,4 ---- + 3 3 + 8.1 1.2 4.3 + 1.3 4.3 2.9 + 0.4 1.3 6.1 Index: tnt/qr.cc =================================================================== RCS file: qr.cc diff -N qr.cc *** /dev/null Tue May 5 14:32:27 1998 --- qr.cc Thu Aug 16 13:02:56 2001 *************** *** 0 **** --- 1,66 ---- + + + + // Solve a linear system using QR factorization. + // + // Usage: a.out < matrix.dat + // + // where matrix.dat is an ASCII file consisting of the + // matrix size (M,N) followed by its values. For example, + // + // 3 2 + // 8.1 1.2 4.3 + // 1.3 4.3 2.9 + // 0.4 1.3 6.1 + // + // + + #include + + #include "tnt/tnt.h" + #include "tnt/vec.h" + #include "tnt/fmat.h" + #include "tnt/qr.h" + + using namespace std; + using namespace TNT; + + int main() + + { + Fortran_Matrix A; + + cin >> A; + + Subscript N = A.num_rows(); + assert(N == A.num_cols()); + + Vector b(N, 1.0); // b= [1,1,1,...] + Vector C(N), D(N); + + + cout << "A: " << A << endl; + + Fortran_Matrix T(A); + + if (QR_factor(T, C, D) !=0) + { + cout << "QR failed." << endl; + cout << " returned: \n" << T << endl; + exit(1); + } + + Vector x(b); + if (QR_solve(T, C, D, x) == 1) + { + cout << "QR_Solve did not work." << endl; + exit(1); + } + + cout << "Solution x for Ax=b, where b=[1,1,...] " < //for sqrt() & fabs() + #include "tnt/tntmath.h" // for sign() + + // Classical QR factorization, based on Stewart[1973]. + // + // + // This algorithm computes the factorization of a matrix A + // into a product of an orthognal matrix (Q) and an upper triangular + // matrix (R), such that QR = A. + // + // Parameters: + // + // A (in/out): On input, A is square, Matrix(1:N, 1:N), that represents + // the matrix to be factored. + // + // On output, Q and R is encoded in the same Matrix(1:N,1:N) + // in the following manner: + // + // R is contained in the upper triangular section of A, + // except that R's main diagonal is in D. The lower + // triangular section of A represents Q, where each + // column j is the vector Qj = I - uj*uj'/pi_j. + // + // C (output): vector of Pi[j] + // D (output): main diagonal of R, i.e. D(i) is R(i,i) + // + // Returns: + // + // 0 if successful, 1 if A is detected to be singular + // + + namespace TNT + { + + template + int QR_factor(MaTRiX &A, Vector& C, Vector &D) + { + assert(A.lbound() == 1); // ensure these are all + assert(C.lbound() == 1); // 1-based arrays and vectors + assert(D.lbound() == 1); + + Subscript M = A.num_rows(); + Subscript N = A.num_cols(); + + assert(M == N); // make sure A is square + + Subscript i,j,k; + typename MaTRiX::element_type eta, sigma, sum; + + // adjust the shape of C and D, if needed... + + if (N != C.size()) C.newsize(N); + if (N != D.size()) D.newsize(N); + + for (k=1; k eta ? absA : eta ); + } + + if (eta == 0) // matrix is singular + { + cerr << "QR: k=" << k << "\n"; + return 1; + } + + // form Qk and premiltiply M by it + // + for(i=k; i<=N; i++) + A(i,k) = A(i,k) / eta; + + sum = 0; + for (i=k; i<=N; i++) + sum = sum + A(i,k)*A(i,k); + sigma = sign(A(k,k)) * sqrt(sum); + + + A(k,k) = A(k,k) + sigma; + C(k) = sigma * A(k,k); + D(k) = -eta * sigma; + + for (j=k+1; j<=N; j++) + { + sum = 0; + for (i=k; i<=N; i++) + sum = sum + A(i,k)*A(i,j); + sum = sum / C(k); + + for (i=k; i<=N; i++) + A(i,j) = A(i,j) - sum * A(i,k); + } + + D(N) = A(N,N); + } + + return 0; + } + + // modified form of upper triangular solve, except that the main diagonal + // of R (upper portion of A) is in D. + // + template + int R_solve(const MaTRiX &A, /*const*/ Vector &D, Vector &b) + { + assert(A.lbound() == 1); // ensure these are all + assert(D.lbound() == 1); // 1-based arrays and vectors + assert(b.lbound() == 1); + + Subscript i,j; + Subscript N = A.num_rows(); + + assert(N == A.num_cols()); + assert(N == D.dim()); + assert(N == b.dim()); + + typename MaTRiX::element_type sum; + + if (D(N) == 0) + return 1; + + b(N) = b(N) / + D(N); + + for (i=N-1; i>=1; i--) + { + if (D(i) == 0) + return 1; + sum = 0; + for (j=i+1; j<=N; j++) + sum = sum + A(i,j)*b(j); + b(i) = ( b(i) - sum ) / + D(i); + } + + return 0; + } + + + template + int QR_solve(const MaTRiX &A, const Vector &c, /*const*/ Vector &d, + Vector &b) + { + assert(A.lbound() == 1); // ensure these are all + assert(c.lbound() == 1); // 1-based arrays and vectors + assert(d.lbound() == 1); + + Subscript N=A.num_rows(); + + assert(N == A.num_cols()); + assert(N == c.dim()); + assert(N == d.dim()); + assert(N == b.dim()); + + Subscript i,j; + typename MaTRiX::element_type sum, tau; + + for (j=1; j + #include + + namespace TNT + { + + template + class const_Region1D; + + template + class Region1D + { + protected: + + Array1D & A_; + Subscript offset_; // 0-based + Subscript dim_; + + typedef typename Array1D::element_type T; + + public: + const Array1D & array() const { return A_; } + + Subscript offset() const { return offset_;} + Subscript dim() const { return dim_; } + + Subscript offset(Subscript i) const + { + #ifdef TNT_BOUNDS_CHECK + assert(i==TNT_BASE_OFFSET); + #endif + return offset_; + } + + Subscript dim(Subscript i) const + { + #ifdef TNT_BOUNDS_CHECK + assert(i== TNT_BASE_OFFSET); + #endif + return offset_; + } + + + Region1D(Array1D &A, Subscript i1, Subscript i2) : A_(A) + { + #ifdef TNT_BOUNDS_CHECK + assert(TNT_BASE_OFFSET <= i1 ); + assert(i2 <= A.dim() + (TNT_BASE_OFFSET-1)); + assert(i1 <= i2); + #endif + offset_ = i1 - TNT_BASE_OFFSET; + dim_ = i2-i1 + 1; + } + + Region1D(Array1D &A, const Index1D &I) : A_(A) + { + #ifdef TNT_BOUNDS_CHECK + assert(TNT_BASE_OFFSET <=I.lbound()); + assert(I.ubound() <= A.dim() + (TNT_BASE_OFFSET-1)); + assert(I.lbound() <= I.ubound()); + #endif + offset_ = I.lbound() - TNT_BASE_OFFSET; + dim_ = I.ubound() - I.lbound() + 1; + } + + Region1D(Region1D &A, Subscript i1, Subscript i2) : + A_(A.A_) + { + #ifdef TNT_BOUNDS_CHECK + assert(TNT_BASE_OFFSET <= i1 ); + assert(i2 <= A.dim() + (TNT_BASE_OFFSET - 1)); + assert(i1 <= i2); + #endif + // (old-offset) (new-offset) + // + offset_ = (i1 - TNT_BASE_OFFSET) + A.offset_; + dim_ = i2-i1 + 1; + } + + Region1D operator()(Subscript i1, Subscript i2) + { + #ifdef TNT_BOUNDS_CHECK + assert(TNT_BASE_OFFSET <= i1); + assert(i2 <= dim() + (TNT_BASE_OFFSET -1)); + assert(i1 <= i2); + #endif + // offset_ is 0-based, so no need for + // ( - TNT_BASE_OFFSET) + // + return Region1D(A_, i1+offset_, + offset_ + i2); + } + + + Region1D operator()(const Index1D &I) + { + #ifdef TNT_BOUNDS_CHECK + assert(TNT_BASE_OFFSET<=I.lbound()); + assert(I.ubound() <= dim() + (TNT_BASE_OFFSET-1)); + assert(I.lbound() <= I.ubound()); + #endif + return Region1D(A_, I.lbound()+offset_, + offset_ + I.ubound()); + } + + + + + T & operator()(Subscript i) + { + #ifdef TNT_BOUNDS_CHECK + assert(TNT_BASE_OFFSET <= i); + assert(i <= dim() + (TNT_BASE_OFFSET-1)); + #endif + return A_(i+offset_); + } + + const T & operator() (Subscript i) const + { + #ifdef TNT_BOUNDS_CHECK + assert(TNT_BASE_OFFSET <= i); + assert(i <= dim() + (TNT_BASE_OFFSET-1)); + #endif + return A_(i+offset_); + } + + + Region1D & operator=(const Region1D &R) + { + // make sure both sides conform + assert(dim() == R.dim()); + + Subscript N = dim(); + Subscript i; + Subscript istart = TNT_BASE_OFFSET; + Subscript iend = istart + N-1; + + for (i=istart; i<=iend; i++) + (*this)(i) = R(i); + + return *this; + } + + + + Region1D & operator=(const const_Region1D &R) + { + // make sure both sides conform + assert(dim() == R.dim()); + + Subscript N = dim(); + Subscript i; + Subscript istart = TNT_BASE_OFFSET; + Subscript iend = istart + N-1; + + for (i=istart; i<=iend; i++) + (*this)(i) = R(i); + + return *this; + + } + + + Region1D & operator=(const T& t) + { + Subscript N=dim(); + Subscript i; + Subscript istart = TNT_BASE_OFFSET; + Subscript iend = istart + N-1; + + for (i=istart; i<= iend; i++) + (*this)(i) = t; + + return *this; + + } + + + Region1D & operator=(const Array1D &R) + { + // make sure both sides conform + Subscript N = dim(); + assert(dim() == R.dim()); + + Subscript i; + Subscript istart = TNT_BASE_OFFSET; + Subscript iend = istart + N-1; + + for (i=istart; i<=iend; i++) + (*this)(i) = R(i); + + return *this; + + } + + }; + + template + std::ostream& operator<<(std::ostream &s, Region1D &A) + { + Subscript N=A.dim(); + Subscript istart = TNT_BASE_OFFSET; + Subscript iend = N - 1 + TNT_BASE_OFFSET; + + for (Subscript i=istart; i<=iend; i++) + s << A(i) << endl; + + return s; + } + + + /* --------- class const_Region1D ------------ */ + + template + class const_Region1D + { + protected: + + const Array1D & A_; + Subscript offset_; // 0-based + Subscript dim_; + typedef typename Array1D::element_type T; + + public: + const Array1D & array() const { return A_; } + + Subscript offset() const { return offset_;} + Subscript dim() const { return dim_; } + + Subscript offset(Subscript i) const + { + #ifdef TNT_BOUNDS_CHECK + assert(i==TNT_BASE_OFFSET); + #endif + return offset_; + } + + Subscript dim(Subscript i) const + { + #ifdef TNT_BOUNDS_CHECK + assert(i== TNT_BASE_OFFSET); + #endif + return offset_; + } + + + const_Region1D(const Array1D &A, Subscript i1, Subscript i2) : A_(A) + { + #ifdef TNT_BOUNDS_CHECK + assert(TNT_BASE_OFFSET <= i1 ); + assert(i2 <= A.dim() + (TNT_BASE_OFFSET-1)); + assert(i1 <= i2); + #endif + offset_ = i1 - TNT_BASE_OFFSET; + dim_ = i2-i1 + 1; + } + + const_Region1D(const Array1D &A, const Index1D &I) : A_(A) + { + #ifdef TNT_BOUNDS_CHECK + assert(TNT_BASE_OFFSET <=I.lbound()); + assert(I.ubound() <= A.dim() + (TNT_BASE_OFFSET-1)); + assert(I.lbound() <= I.ubound()); + #endif + offset_ = I.lbound() - TNT_BASE_OFFSET; + dim_ = I.ubound() - I.lbound() + 1; + } + + const_Region1D(const_Region1D &A, Subscript i1, Subscript i2) : + A_(A.A_) + { + #ifdef TNT_BOUNDS_CHECK + assert(TNT_BASE_OFFSET <= i1 ); + assert(i2 <= A.dim() + (TNT_BASE_OFFSET - 1)); + assert(i1 <= i2); + #endif + // (old-offset) (new-offset) + // + offset_ = (i1 - TNT_BASE_OFFSET) + A.offset_; + dim_ = i2-i1 + 1; + } + + const_Region1D operator()(Subscript i1, Subscript i2) + { + #ifdef TNT_BOUNDS_CHECK + assert(TNT_BASE_OFFSET <= i1); + assert(i2 <= dim() + (TNT_BASE_OFFSET -1)); + assert(i1 <= i2); + #endif + // offset_ is 0-based, so no need for + // ( - TNT_BASE_OFFSET) + // + return const_Region1D(A_, i1+offset_, + offset_ + i2); + } + + + const_Region1D operator()(const Index1D &I) + { + #ifdef TNT_BOUNDS_CHECK + assert(TNT_BASE_OFFSET<=I.lbound()); + assert(I.ubound() <= dim() + (TNT_BASE_OFFSET-1)); + assert(I.lbound() <= I.ubound()); + #endif + return const_Region1D(A_, I.lbound()+offset_, + offset_ + I.ubound()); + } + + + const T & operator() (Subscript i) const + { + #ifdef TNT_BOUNDS_CHECK + assert(TNT_BASE_OFFSET <= i); + assert(i <= dim() + (TNT_BASE_OFFSET-1)); + #endif + return A_(i+offset_); + } + + + + + }; + + template + std::ostream& operator<<(std::ostream &s, const_Region1D &A) + { + Subscript N=A.dim(); + + for (Subscript i=1; i<=N; i++) + s << A(i) << endl; + + return s; + } + + + } // namespace TNT + + #endif + // const_Region1D_H Index: tnt/region2d.h =================================================================== RCS file: region2d.h diff -N region2d.h *** /dev/null Tue May 5 14:32:27 1998 --- region2d.h Thu Aug 16 13:02:56 2001 *************** *** 0 **** --- 1,467 ---- + /* + * + * Template Numerical Toolkit (TNT): Linear Algebra Module + * + * Mathematical and Computational Sciences Division + * National Institute of Technology, + * Gaithersburg, MD USA + * + * + * This software was developed at the National Institute of Standards and + * Technology (NIST) by employees of the Federal Government in the course + * of their official duties. Pursuant to title 17 Section 105 of the + * United States Code, this software is not subject to copyright protection + * and is in the public domain. The Template Numerical Toolkit (TNT) is + * an experimental system. NIST assumes no responsibility whatsoever for + * its use by other parties, and makes no guarantees, expressed or implied, + * about its quality, reliability, or any other characteristic. + * + * BETA VERSION INCOMPLETE AND SUBJECT TO CHANGE + * see http://math.nist.gov/tnt for latest updates. + * + */ + + + // 2D Regions for arrays and matrices + + #ifndef REGION2D_H + #define REGION2D_H + + #include "tnt/index.h" + #include + #include + + namespace TNT + { + + template + class const_Region2D; + + + template + class Region2D + { + protected: + + Array2D & A_; + Subscript offset_[2]; // 0-offset internally + Subscript dim_[2]; + + public: + typedef typename Array2D::value_type T; + typedef Subscript size_type; + typedef T value_type; + typedef T element_type; + typedef T* pointer; + typedef T* iterator; + typedef T& reference; + typedef const T* const_iterator; + typedef const T& const_reference; + + Array2D & array() { return A_; } + const Array2D & array() const { return A_; } + Subscript lbound() const { return A_.lbound(); } + Subscript num_rows() const { return dim_[0]; } + Subscript num_cols() const { return dim_[1]; } + Subscript offset(Subscript i) const // 1-offset + { + #ifdef TNT_BOUNDS_CHECK + assert( A_.lbound() <= i); + assert( i<= dim_[0] + A_.lbound()-1); + #endif + return offset_[i-A_.lbound()]; + } + + Subscript dim(Subscript i) const + { + #ifdef TNT_BOUNDS_CHECK + assert( A_.lbound() <= i); + assert( i<= dim_[0] + A_.lbound()-1); + #endif + return dim_[i-A_.lbound()]; + } + + + + Region2D(Array2D &A, Subscript i1, Subscript i2, Subscript j1, + Subscript j2) : A_(A) + { + #ifdef TNT_BOUNDS_CHECK + assert( i1 <= i2 ); + assert( j1 <= j2); + assert( A.lbound() <= i1); + assert( i2<= A.dim(A.lbound()) + A.lbound()-1); + assert( A.lbound() <= j1); + assert( j2<= A.dim(A.lbound()+1) + A.lbound()-1 ); + #endif + + + offset_[0] = i1-A.lbound(); + offset_[1] = j1-A.lbound(); + dim_[0] = i2-i1+1; + dim_[1] = j2-j1+1; + } + + Region2D(Array2D &A, const Index1D &I, const Index1D &J) : A_(A) + { + #ifdef TNT_BOUNDS_CHECK + assert( I.lbound() <= I.ubound() ); + assert( J.lbound() <= J.ubound() ); + assert( A.lbound() <= I.lbound()); + assert( I.ubound()<= A.dim(A.lbound()) + A.lbound()-1); + assert( A.lbound() <= J.lbound()); + assert( J.ubound() <= A.dim(A.lbound()+1) + A.lbound()-1 ); + #endif + + offset_[0] = I.lbound()-A.lbound(); + offset_[1] = J.lbound()-A.lbound(); + dim_[0] = I.ubound() - I.lbound() + 1; + dim_[1] = J.ubound() - J.lbound() + 1; + } + + Region2D(Region2D &A, Subscript i1, Subscript i2, + Subscript j1, Subscript j2) : A_(A.A_) + { + #ifdef TNT_BOUNDS_CHECK + assert( i1 <= i2 ); + assert( j1 <= j2); + assert( A.lbound() <= i1); + assert( i2<= A.dim(A.lbound()) + A.lbound()-1); + assert( A.lbound() <= j1); + assert( j2<= A.dim(A.lbound()+1) + A.lbound()-1 ); + #endif + offset_[0] = (i1 - A.lbound()) + A.offset_[0]; + offset_[1] = (j1 - A.lbound()) + A.offset_[1]; + dim_[0] = i2-i1 + 1; + dim_[1] = j2-j1+1; + } + + Region2D operator()(Subscript i1, Subscript i2, + Subscript j1, Subscript j2) + { + #ifdef TNT_BOUNDS_CHECK + assert( i1 <= i2 ); + assert( j1 <= j2); + assert( A_.lbound() <= i1); + assert( i2<= dim_[0] + A_.lbound()-1); + assert( A_.lbound() <= j1); + assert( j2<= dim_[1] + A_.lbound()-1 ); + #endif + return Region2D(A_, + i1+offset_[0], offset_[0] + i2, + j1+offset_[1], offset_[1] + j2); + } + + + Region2D operator()(const Index1D &I, + const Index1D &J) + { + #ifdef TNT_BOUNDS_CHECK + assert( I.lbound() <= I.ubound() ); + assert( J.lbound() <= J.ubound() ); + assert( A_.lbound() <= I.lbound()); + assert( I.ubound()<= dim_[0] + A_.lbound()-1); + assert( A_.lbound() <= J.lbound()); + assert( J.ubound() <= dim_[1] + A_.lbound()-1 ); + #endif + + return Region2D(A_, I.lbound()+offset_[0], + offset_[0] + I.ubound(), offset_[1]+J.lbound(), + offset_[1] + J.ubound()); + } + + inline T & operator()(Subscript i, Subscript j) + { + #ifdef TNT_BOUNDS_CHECK + assert( A_.lbound() <= i); + assert( i<= dim_[0] + A_.lbound()-1); + assert( A_.lbound() <= j); + assert( j<= dim_[1] + A_.lbound()-1 ); + #endif + return A_(i+offset_[0], j+offset_[1]); + } + + inline const T & operator() (Subscript i, Subscript j) const + { + #ifdef TNT_BOUNDS_CHECK + assert( A_.lbound() <= i); + assert( i<= dim_[0] + A_.lbound()-1); + assert( A_.lbound() <= j); + assert( j<= dim_[1] + A_.lbound()-1 ); + #endif + return A_(i+offset_[0], j+offset_[1]); + } + + + Region2D & operator=(const Region2D &R) + { + Subscript M = num_rows(); + Subscript N = num_cols(); + + // make sure both sides conform + assert(M == R.num_rows()); + assert(N == R.num_cols()); + + + Subscript start = R.lbound(); + Subscript Mend = start + M - 1; + Subscript Nend = start + N - 1; + for (Subscript i=start; i<=Mend; i++) + for (Subscript j=start; j<=Nend; j++) + (*this)(i,j) = R(i,j); + + return *this; + } + + Region2D & operator=(const const_Region2D &R) + { + Subscript M = num_rows(); + Subscript N = num_cols(); + + // make sure both sides conform + assert(M == R.num_rows()); + assert(N == R.num_cols()); + + + Subscript start = R.lbound(); + Subscript Mend = start + M - 1; + Subscript Nend = start + N - 1; + for (Subscript i=start; i<=Mend; i++) + for (Subscript j=start; j<=Nend; j++) + (*this)(i,j) = R(i,j); + + return *this; + } + + Region2D & operator=(const Array2D &R) + { + Subscript M = num_rows(); + Subscript N = num_cols(); + + // make sure both sides conform + assert(M == R.num_rows()); + assert(N == R.num_cols()); + + + Subscript start = R.lbound(); + Subscript Mend = start + M - 1; + Subscript Nend = start + N - 1; + for (Subscript i=start; i<=Mend; i++) + for (Subscript j=start; j<=Nend; j++) + (*this)(i,j) = R(i,j); + + return *this; + } + + Region2D & operator=(const T &scalar) + { + Subscript start = lbound(); + Subscript Mend = lbound() + num_rows() - 1; + Subscript Nend = lbound() + num_cols() - 1; + + + for (Subscript i=start; i<=Mend; i++) + for (Subscript j=start; j<=Nend; j++) + (*this)(i,j) = scalar; + + return *this; + } + + }; + + //************************ + + template + class const_Region2D + { + protected: + + const Array2D & A_; + Subscript offset_[2]; // 0-offset internally + Subscript dim_[2]; + + public: + typedef typename Array2D::value_type T; + typedef T value_type; + typedef T element_type; + typedef const T* const_iterator; + typedef const T& const_reference; + + const Array2D & array() const { return A_; } + Subscript lbound() const { return A_.lbound(); } + Subscript num_rows() const { return dim_[0]; } + Subscript num_cols() const { return dim_[1]; } + Subscript offset(Subscript i) const // 1-offset + { + #ifdef TNT_BOUNDS_CHECK + assert( TNT_BASE_OFFSET <= i); + assert( i<= dim_[0] + TNT_BASE_OFFSET-1); + #endif + return offset_[i-TNT_BASE_OFFSET]; + } + + Subscript dim(Subscript i) const + { + #ifdef TNT_BOUNDS_CHECK + assert( TNT_BASE_OFFSET <= i); + assert( i<= dim_[0] + TNT_BASE_OFFSET-1); + #endif + return dim_[i-TNT_BASE_OFFSET]; + } + + + const_Region2D(const Array2D &A, Subscript i1, Subscript i2, + Subscript j1, Subscript j2) : A_(A) + { + #ifdef TNT_BOUNDS_CHECK + assert( i1 <= i2 ); + assert( j1 <= j2); + assert( TNT_BASE_OFFSET <= i1); + assert( i2<= A.dim(TNT_BASE_OFFSET) + TNT_BASE_OFFSET-1); + assert( TNT_BASE_OFFSET <= j1); + assert( j2<= A.dim(TNT_BASE_OFFSET+1) + TNT_BASE_OFFSET-1 ); + #endif + + offset_[0] = i1-TNT_BASE_OFFSET; + offset_[1] = j1-TNT_BASE_OFFSET; + dim_[0] = i2-i1+1; + dim_[1] = j2-j1+1; + } + + const_Region2D(const Array2D &A, const Index1D &I, const Index1D &J) + : A_(A) + { + #ifdef TNT_BOUNDS_CHECK + assert( I.lbound() <= I.ubound() ); + assert( J.lbound() <= J.ubound() ); + assert( TNT_BASE_OFFSET <= I.lbound()); + assert( I.ubound()<= A.dim(TNT_BASE_OFFSET) + TNT_BASE_OFFSET-1); + assert( TNT_BASE_OFFSET <= J.lbound()); + assert( J.ubound() <= A.dim(TNT_BASE_OFFSET+1) + TNT_BASE_OFFSET-1 ); + #endif + + offset_[0] = I.lbound()-TNT_BASE_OFFSET; + offset_[1] = J.lbound()-TNT_BASE_OFFSET; + dim_[0] = I.ubound() - I.lbound() + 1; + dim_[1] = J.ubound() - J.lbound() + 1; + } + + + const_Region2D(const_Region2D &A, Subscript i1, + Subscript i2, + Subscript j1, Subscript j2) : A_(A.A_) + { + #ifdef TNT_BOUNDS_CHECK + assert( i1 <= i2 ); + assert( j1 <= j2); + assert( TNT_BASE_OFFSET <= i1); + assert( i2<= A.dim(TNT_BASE_OFFSET) + TNT_BASE_OFFSET-1); + assert( TNT_BASE_OFFSET <= j1); + assert( j2<= A.dim(TNT_BASE_OFFSET+1) + TNT_BASE_OFFSET-1 ); + #endif + offset_[0] = (i1 - TNT_BASE_OFFSET) + A.offset_[0]; + offset_[1] = (j1 - TNT_BASE_OFFSET) + A.offset_[1]; + dim_[0] = i2-i1 + 1; + dim_[1] = j2-j1+1; + } + + const_Region2D operator()(Subscript i1, Subscript i2, + Subscript j1, Subscript j2) + { + #ifdef TNT_BOUNDS_CHECK + assert( i1 <= i2 ); + assert( j1 <= j2); + assert( TNT_BASE_OFFSET <= i1); + assert( i2<= dim_[0] + TNT_BASE_OFFSET-1); + assert( TNT_BASE_OFFSET <= j1); + assert( j2<= dim_[0] + TNT_BASE_OFFSET-1 ); + #endif + return const_Region2D(A_, + i1+offset_[0], offset_[0] + i2, + j1+offset_[1], offset_[1] + j2); + } + + + const_Region2D operator()(const Index1D &I, + const Index1D &J) + { + #ifdef TNT_BOUNDS_CHECK + assert( I.lbound() <= I.ubound() ); + assert( J.lbound() <= J.ubound() ); + assert( TNT_BASE_OFFSET <= I.lbound()); + assert( I.ubound()<= dim_[0] + TNT_BASE_OFFSET-1); + assert( TNT_BASE_OFFSET <= J.lbound()); + assert( J.ubound() <= dim_[1] + TNT_BASE_OFFSET-1 ); + #endif + + return const_Region2D(A_, I.lbound()+offset_[0], + offset_[0] + I.ubound(), offset_[1]+J.lbound(), + offset_[1] + J.ubound()); + } + + + inline const T & operator() (Subscript i, Subscript j) const + { + #ifdef TNT_BOUNDS_CHECK + assert( TNT_BASE_OFFSET <= i); + assert( i<= dim_[0] + TNT_BASE_OFFSET-1); + assert( TNT_BASE_OFFSET <= j); + assert( j<= dim_[1] + TNT_BASE_OFFSET-1 ); + #endif + return A_(i+offset_[0], j+offset_[1]); + } + + }; + + + // ************** std::ostream algorithms ******************************* + + template + std::ostream& operator<<(std::ostream &s, const const_Region2D &A) + { + Subscript start = A.lbound(); + Subscript Mend=A.lbound()+ A.num_rows() - 1; + Subscript Nend=A.lbound() + A.num_cols() - 1; + + + s << A.num_rows() << " " << A.num_cols() << "\n"; + for (Subscript i=start; i<=Mend; i++) + { + for (Subscript j=start; j<=Nend; j++) + { + s << A(i,j) << " "; + } + s << "\n"; + } + + + return s; + } + + template + std::ostream& operator<<(std::ostream &s, const Region2D &A) + { + Subscript start = A.lbound(); + Subscript Mend=A.lbound()+ A.num_rows() - 1; + Subscript Nend=A.lbound() + A.num_cols() - 1; + + + s << A.num_rows() << " " << A.num_cols() << "\n"; + for (Subscript i=start; i<=Mend; i++) + { + for (Subscript j=start; j<=Nend; j++) + { + s << A(i,j) << " "; + } + s << "\n"; + } + + + return s; + + } + + } // namespace TNT + + #endif + // REGION2D_H Index: tnt/stopwatch.h =================================================================== RCS file: stopwatch.h diff -N stopwatch.h *** /dev/null Tue May 5 14:32:27 1998 --- stopwatch.h Thu Aug 16 13:02:56 2001 *************** *** 0 **** --- 1,83 ---- + /* + * + * Template Numerical Toolkit (TNT): Linear Algebra Module + * + * Mathematical and Computational Sciences Division + * National Institute of Technology, + * Gaithersburg, MD USA + * + * + * This software was developed at the National Institute of Standards and + * Technology (NIST) by employees of the Federal Government in the course + * of their official duties. Pursuant to title 17 Section 105 of the + * United States Code, this software is not subject to copyright protection + * and is in the public domain. The Template Numerical Toolkit (TNT) is + * an experimental system. NIST assumes no responsibility whatsoever for + * its use by other parties, and makes no guarantees, expressed or implied, + * about its quality, reliability, or any other characteristic. + * + * BETA VERSION INCOMPLETE AND SUBJECT TO CHANGE + * see http://math.nist.gov/tnt for latest updates. + * + */ + + + + #ifndef STPWATCH_H + #define STPWATCH_H + + // for clock() and CLOCKS_PER_SEC + #include + + namespace TNT + { + + /* Simple stopwatch object: + + void start() : start timing + double stop() : stop timing + void reset() : set elapsed time to 0.0 + double read() : read elapsed time (in seconds) + + */ + + inline double seconds(void) + { + static const double secs_per_tick = 1.0 / CLOCKS_PER_SEC; + return ( (double) clock() ) * secs_per_tick; + } + + + class stopwatch { + private: + int running; + double last_time; + double total; + + public: + stopwatch() : running(0), last_time(0.0), total(0.0) {} + void reset() { running = 0; last_time = 0.0; total=0.0; } + void start() { if (!running) { last_time = seconds(); running = 1;}} + double stop() { if (running) + { + total += seconds() - last_time; + running = 0; + } + return total; + } + double read() { if (running) + { + total+= seconds() - last_time; + last_time = seconds(); + } + return total; + } + + }; + + } // namespace TNT + + #endif + + + Index: tnt/subscript.h =================================================================== RCS file: subscript.h diff -N subscript.h *** /dev/null Tue May 5 14:32:27 1998 --- subscript.h Thu Aug 16 13:02:56 2001 *************** *** 0 **** --- 1,58 ---- + /* + * + * Template Numerical Toolkit (TNT): Linear Algebra Module + * + * Mathematical and Computational Sciences Division + * National Institute of Technology, + * Gaithersburg, MD USA + * + * + * This software was developed at the National Institute of Standards and + * Technology (NIST) by employees of the Federal Government in the course + * of their official duties. Pursuant to title 17 Section 105 of the + * United States Code, this software is not subject to copyright protection + * and is in the public domain. The Template Numerical Toolkit (TNT) is + * an experimental system. NIST assumes no responsibility whatsoever for + * its use by other parties, and makes no guarantees, expressed or implied, + * about its quality, reliability, or any other characteristic. + * + * BETA VERSION INCOMPLETE AND SUBJECT TO CHANGE + * see http://math.nist.gov/tnt for latest updates. + * + */ + + + #ifndef SUBSCRPT_H + #define SUBSCRPT_H + + + //--------------------------------------------------------------------- + // This definition describes the default TNT data type used for + // indexing into TNT matrices and vectors. The data type should + // be wide enough to index into large arrays. It defaults to an + // "int", but can be overriden at compile time redefining TNT_SUBSCRIPT_TYPE, + // e.g. + // + // g++ -DTNT_SUBSCRIPT_TYPE='unsigned int' ... + // + //--------------------------------------------------------------------- + // + + #ifndef TNT_SUBSCRIPT_TYPE + #define TNT_SUBSCRIPT_TYPE int + #endif + + namespace TNT + { + typedef TNT_SUBSCRIPT_TYPE Subscript; + } + + + // () indexing in TNT means 1-offset, i.e. x(1) and A(1,1) are the + // first elements. This offset is left as a macro for future + // purposes, but should not be changed in the current release. + // + // + #define TNT_BASE_OFFSET (1) + + #endif Index: tnt/tnt.h =================================================================== RCS file: tnt.h diff -N tnt.h *** /dev/null Tue May 5 14:32:27 1998 --- tnt.h Thu Aug 16 13:02:56 2001 *************** *** 0 **** --- 1,90 ---- + /* + * + * Template Numerical Toolkit (TNT): Linear Algebra Module + * + * Mathematical and Computational Sciences Division + * National Institute of Technology, + * Gaithersburg, MD USA + * + * + * This software was developed at the National Institute of Standards and + * Technology (NIST) by employees of the Federal Government in the course + * of their official duties. Pursuant to title 17 Section 105 of the + * United States Code, this software is not subject to copyright protection + * and is in the public domain. The Template Numerical Toolkit (TNT) is + * an experimental system. NIST assumes no responsibility whatsoever for + * its use by other parties, and makes no guarantees, expressed or implied, + * about its quality, reliability, or any other characteristic. + * + * BETA VERSION INCOMPLETE AND SUBJECT TO CHANGE + * see http://math.nist.gov/tnt for latest updates. + * + */ + + + #ifndef TNT_H + #define TNT_H + + //--------------------------------------------------------------------- + // tnt.h TNT general header file. Defines default types + // and conventions. + //--------------------------------------------------------------------- + + //--------------------------------------------------------------------- + // Include current version + //--------------------------------------------------------------------- + #include "tnt/version.h" + + //--------------------------------------------------------------------- + // Define the data type used for matrix and vector Subscripts. + // This will default to "int", but it can be overridden at compile time, + // e.g. + // + // g++ -DTNT_SUBSCRIPT_TYPE='unsigned long' ... + // + // See subscript.h for details. + //--------------------------------------------------------------------- + + #include "tnt/subscript.h" + + + + //--------------------------------------------------------------------- + // Define this macro if you want TNT to ensure all refernces + // are within the bounds of the array. This encurs a run-time + // overhead, of course, but is recommended while developing + // code. It can be turned off for production runs. + // + // #define TNT_BOUNDS_CHECK + //--------------------------------------------------------------------- + // + #define TNT_BOUNDS_CHECK + #ifdef TNT_NO_BOUNDS_CHECK + #undef TNT_BOUNDS_CHECK + #endif + + //--------------------------------------------------------------------- + // Define this macro if you want to utilize matrix and vector + // regions. This is typically on, but you can save some + // compilation time by turning it off. If you do this and + // attempt to use regions you will get an error message. + // + // #define TNT_USE_REGIONS + //--------------------------------------------------------------------- + // + #define TNT_USE_REGIONS + + //--------------------------------------------------------------------- + // + //--------------------------------------------------------------------- + // If your system doesn't have abs(), min(), and max() uncomment the following. + //--------------------------------------------------------------------- + // + // + //#define __NEED_ABS_MIN_MAX_ + + #include "tnt/tntmath.h" + + + #endif + // TNT_H Index: tnt/tnt.h.patch =================================================================== RCS file: tnt.h.patch diff -N tnt.h.patch *** /dev/null Tue May 5 14:32:27 1998 --- tnt.h.patch Thu Aug 16 13:02:56 2001 *************** *** 0 **** --- 1,47 ---- + *** tnt.h.~1~ Sun Aug 6 21:52:04 2000 + --- tnt.h Tue Aug 7 19:27:13 2001 + *************** + *** 38,45 **** + //--------------------------------------------------------------------- + // Define the data type used for matrix and vector Subscripts. + ! // This will default to "int", but it can be overriden at compile time, + // e.g. + // + ! // g++ -DTNT_SUBSCRIPT_TYPE='unsinged long' ... + // + // See subscript.h for details. + --- 38,45 ---- + //--------------------------------------------------------------------- + // Define the data type used for matrix and vector Subscripts. + ! // This will default to "int", but it can be overridden at compile time, + // e.g. + // + ! // g++ -DTNT_SUBSCRIPT_TYPE='unsigned long' ... + // + // See subscript.h for details. + *************** + *** 51,55 **** + + //--------------------------------------------------------------------- + ! // Define this macro if you want TNT to ensure all refernces + // are within the bounds of the array. This encurs a run-time + // overhead, of course, but is recommended while developing + --- 51,55 ---- + + //--------------------------------------------------------------------- + ! // Define this macro if you want TNT to ensure all refernces + // are within the bounds of the array. This encurs a run-time + // overhead, of course, but is recommended while developing + *************** + *** 78,82 **** + // + //--------------------------------------------------------------------- + ! // if your system doesn't have abs() min(), and max() uncoment the following + //--------------------------------------------------------------------- + // + --- 78,82 ---- + // + //--------------------------------------------------------------------- + ! // If your system doesn't have abs(), min(), and max() uncomment the following. + //--------------------------------------------------------------------- + // Index: tnt/tntmath.h =================================================================== RCS file: tntmath.h diff -N tntmath.h *** /dev/null Tue May 5 14:32:27 1998 --- tntmath.h Thu Aug 16 13:02:56 2001 *************** *** 0 **** --- 1,85 ---- + /* + * + * Template Numerical Toolkit (TNT): Linear Algebra Module + * + * Mathematical and Computational Sciences Division + * National Institute of Technology, + * Gaithersburg, MD USA + * + * + * This software was developed at the National Institute of Standards and + * Technology (NIST) by employees of the Federal Government in the course + * of their official duties. Pursuant to title 17 Section 105 of the + * United States Code, this software is not subject to copyright protection + * and is in the public domain. The Template Numerical Toolkit (TNT) is + * an experimental system. NIST assumes no responsibility whatsoever for + * its use by other parties, and makes no guarantees, expressed or implied, + * about its quality, reliability, or any other characteristic. + * + * BETA VERSION INCOMPLETE AND SUBJECT TO CHANGE + * see http://math.nist.gov/tnt for latest updates. + * + */ + + + + // Header file for scalar math functions + + #ifndef TNTMATH_H + #define TNTMATH_H + + // conventional functions required by several matrix algorithms + + + + namespace TNT + { + + inline double abs(double t) + { + return ( t > 0 ? t : -t); + } + + inline double min(double a, double b) + { + return (a < b ? a : b); + } + + inline double max(double a, double b) + { + return (a > b ? a : b); + } + + inline float abs(float t) + { + return ( t > 0 ? t : -t); + } + + inline float min(float a, float b) + { + return (a < b ? a : b); + } + + inline float max(float a, float b) + { + return (a > b ? a : b); + } + + inline double sign(double a) + { + return (a > 0 ? 1.0 : -1.0); + } + + + + inline float sign(float a) + { + return (a > 0.0 ? 1.0f : -1.0f); + } + + } /* namespace TNT */ + + + #endif + /* TNTMATH_H */ + Index: tnt/tntreqs.h =================================================================== RCS file: tntreqs.h diff -N tntreqs.h *** /dev/null Tue May 5 14:32:27 1998 --- tntreqs.h Thu Aug 16 13:02:56 2001 *************** *** 0 **** --- 1,70 ---- + /* + * + * Template Numerical Toolkit (TNT): Linear Algebra Module + * + * Mathematical and Computational Sciences Division + * National Institute of Technology, + * Gaithersburg, MD USA + * + * + * This software was developed at the National Institute of Standards and + * Technology (NIST) by employees of the Federal Government in the course + * of their official duties. Pursuant to title 17 Section 105 of the + * United States Code, this software is not subject to copyright protection + * and is in the public domain. The Template Numerical Toolkit (TNT) is + * an experimental system. NIST assumes no responsibility whatsoever for + * its use by other parties, and makes no guarantees, expressed or implied, + * about its quality, reliability, or any other characteristic. + * + * BETA VERSION INCOMPLETE AND SUBJECT TO CHANGE + * see http://math.nist.gov/tnt for latest updates. + * + */ + + + + // The requirements for a bare-bones vector class: + // + // + // o) must have 0-based [] indexing for const and + // non-const objects (i.e. operator[] defined) + // + // o) must have size() method to denote the number of + // elements + // o) must clean up after itself when destructed + // (i.e. no memory leaks) + // + // -) must have begin() and end() methods (The begin() + // method is necessary, because relying on + // &v_[0] may not work on a empty vector (i.e. v_ is NULL.) + // + // o) must be templated + // o) must have X::value_type defined to be the types of elements + // o) must have X::X(const &x) copy constructor (by *value*) + // o) must have X::X(int N) constructor to N-length vector + // (NOTE: this constructor need *NOT* initalize elements) + // + // -) must have X::X(int N, T scalar) constructor to initalize + // elements to value of "scalar". + // + // ( removed, because valarray<> class uses (scalar, N) rather + // than (N, scalar) ) + // -) must have X::X(int N, const T* scalars) constructor to copy from + // any C linear array + // + // ( removed, because of same reverse order of valarray<> ) + // + // o) must have assignment A=B, by value + // + // NOTE: this class is *NOT* meant to be derived from, + // so its methods (particularly indexing) need not be + // declared virtual. + // + // + // Some things it *DOES NOT* need to do are + // + // o) bounds checking + // o) array referencing (e.g. reference counting) + // o) support () indexing + // o) I/O + // Index: tnt/transv.h =================================================================== RCS file: transv.h diff -N transv.h *** /dev/null Tue May 5 14:32:27 1998 --- transv.h Thu Aug 16 13:02:56 2001 *************** *** 0 **** --- 1,160 ---- + /* + * + * Template Numerical Toolkit (TNT): Linear Algebra Module + * + * Mathematical and Computational Sciences Division + * National Institute of Technology, + * Gaithersburg, MD USA + * + * + * This software was developed at the National Institute of Standards and + * Technology (NIST) by employees of the Federal Government in the course + * of their official duties. Pursuant to title 17 Section 105 of the + * United States Code, this software is not subject to copyright protection + * and is in the public domain. The Template Numerical Toolkit (TNT) is + * an experimental system. NIST assumes no responsibility whatsoever for + * its use by other parties, and makes no guarantees, expressed or implied, + * about its quality, reliability, or any other characteristic. + * + * BETA VERSION INCOMPLETE AND SUBJECT TO CHANGE + * see http://math.nist.gov/tnt for latest updates. + * + */ + + + + // Matrix Transpose Views + + #ifndef TRANSV_H + #define TRANSV_H + + #include + #include + #include "tnt/vec.h" + + namespace TNT + { + + template + class Transpose_View + { + protected: + + const Array2D & A_; + + public: + + typedef typename Array2D::element_type T; + typedef T value_type; + typedef T element_type; + typedef T* pointer; + typedef T* iterator; + typedef T& reference; + typedef const T* const_iterator; + typedef const T& const_reference; + + + const Array2D & array() const { return A_; } + Subscript num_rows() const { return A_.num_cols();} + Subscript num_cols() const { return A_.num_rows();} + Subscript lbound() const { return A_.lbound(); } + Subscript dim(Subscript i) const + { + #ifdef TNT_BOUNDS_CHECK + assert( A_.lbound() <= i); + assert( i<= A_.lbound()+1); + #endif + if (i== A_.lbound()) + return num_rows(); + else + return num_cols(); + } + + + Transpose_View(const Transpose_View &A) : A_(A.A_) {}; + Transpose_View(const Array2D &A) : A_(A) {}; + + + inline const typename Array2D::element_type & operator()( + Subscript i, Subscript j) const + { + #ifdef TNT_BOUNDS_CHECK + assert(lbound()<=i); + assert(i<=A_.num_cols() + lbound() - 1); + assert(lbound()<=j); + assert(j<=A_.num_rows() + lbound() - 1); + #endif + + return A_(j,i); + } + + + }; + + template + Transpose_View Transpose_view(const Matrix &A) + { + return Transpose_View(A); + } + + template + Vector matmult( + const Transpose_View & A, + const Vector &B) + { + Subscript M = A.num_rows(); + Subscript N = A.num_cols(); + + assert(B.dim() == N); + + Vector x(N); + + Subscript i, j; + T tmp = 0; + + for (i=1; i<=M; i++) + { + tmp = 0; + for (j=1; j<=N; j++) + tmp += A(i,j) * B(j); + x(i) = tmp; + } + + return x; + } + + template + inline Vector operator*(const Transpose_View & A, const Vector &B) + { + return matmult(A,B); + } + + + template + std::ostream& operator<<(std::ostream &s, const Transpose_View &A) + { + Subscript M=A.num_rows(); + Subscript N=A.num_cols(); + + Subscript start = A.lbound(); + Subscript Mend = M + A.lbound() - 1; + Subscript Nend = N + A.lbound() - 1; + + s << M << " " << N << endl; + for (Subscript i=start; i<=Mend; i++) + { + for (Subscript j=start; j<=Nend; j++) + { + s << A(i,j) << " "; + } + s << endl; + } + + + return s; + } + + } // namespace TNT + + #endif + // TRANSV_H Index: tnt/triang.h =================================================================== RCS file: triang.h diff -N triang.h *** /dev/null Tue May 5 14:32:27 1998 --- triang.h Thu Aug 16 13:02:56 2001 *************** *** 0 **** --- 1,638 ---- + /* + * + * Template Numerical Toolkit (TNT): Linear Algebra Module + * + * Mathematical and Computational Sciences Division + * National Institute of Technology, + * Gaithersburg, MD USA + * + * + * This software was developed at the National Institute of Standards and + * Technology (NIST) by employees of the Federal Government in the course + * of their official duties. Pursuant to title 17 Section 105 of the + * United States Code, this software is not subject to copyright protection + * and is in the public domain. The Template Numerical Toolkit (TNT) is + * an experimental system. NIST assumes no responsibility whatsoever for + * its use by other parties, and makes no guarantees, expressed or implied, + * about its quality, reliability, or any other characteristic. + * + * BETA VERSION INCOMPLETE AND SUBJECT TO CHANGE + * see http://math.nist.gov/tnt for latest updates. + * + */ + + + + // Triangular Matrices (Views and Adpators) + + #ifndef TRIANG_H + #define TRIANG_H + + // default to use lower-triangular portions of arrays + // for symmetric matrices. + + namespace TNT + { + + template + class LowerTriangularView + { + protected: + + + const MaTRiX &A_; + const typename MaTRiX::element_type zero_; + + public: + + + typedef typename MaTRiX::const_reference const_reference; + typedef const typename MaTRiX::element_type element_type; + typedef const typename MaTRiX::element_type value_type; + typedef element_type T; + + Subscript dim(Subscript d) const { return A_.dim(d); } + Subscript lbound() const { return A_.lbound(); } + Subscript num_rows() const { return A_.num_rows(); } + Subscript num_cols() const { return A_.num_cols(); } + + + // constructors + + LowerTriangularView(/*const*/ MaTRiX &A) : A_(A), zero_(0) {} + + + inline const_reference get(Subscript i, Subscript j) const + { + #ifdef TNT_BOUNDS_CHECK + assert(lbound()<=i); + assert(i<=A_.num_rows() + lbound() - 1); + assert(lbound()<=j); + assert(j<=A_.num_cols() + lbound() - 1); + #endif + if (i > + const_Region; + + const_Region operator()(/*const*/ Index1D &I, + /*const*/ Index1D &J) const + { + return const_Region(*this, I, J); + } + + const_Region operator()(Subscript i1, Subscript i2, + Subscript j1, Subscript j2) const + { + return const_Region(*this, i1, i2, j1, j2); + } + + + + #endif + // TNT_USE_REGIONS + + }; + + + /* *********** Lower_triangular_view() algorithms ****************** */ + + template + VecToR matmult(/*const*/ LowerTriangularView &A, VecToR &x) + { + Subscript M = A.num_rows(); + Subscript N = A.num_cols(); + + assert(N == x.dim()); + + Subscript i, j; + typename MaTRiX::element_type sum=0.0; + VecToR result(M); + + Subscript start = A.lbound(); + Subscript Mend = M + A.lbound() -1 ; + + for (i=start; i<=Mend; i++) + { + sum = 0.0; + for (j=start; j<=i; j++) + sum = sum + A(i,j)*x(j); + result(i) = sum; + } + + return result; + } + + template + inline VecToR operator*(/*const*/ LowerTriangularView &A, VecToR &x) + { + return matmult(A,x); + } + + template + class UnitLowerTriangularView + { + protected: + + const MaTRiX &A_; + const typename MaTRiX::element_type zero; + const typename MaTRiX::element_type one; + + public: + + typedef typename MaTRiX::const_reference const_reference; + typedef typename MaTRiX::element_type element_type; + typedef typename MaTRiX::element_type value_type; + typedef element_type T; + + Subscript lbound() const { return 1; } + Subscript dim(Subscript d) const { return A_.dim(d); } + Subscript num_rows() const { return A_.num_rows(); } + Subscript num_cols() const { return A_.num_cols(); } + + + // constructors + + UnitLowerTriangularView(/*const*/ MaTRiX &A) : A_(A), zero(0), one(1) {} + + + inline const_reference get(Subscript i, Subscript j) const + { + #ifdef TNT_BOUNDS_CHECK + assert(1<=i); + assert(i<=A_.dim(1)); + assert(1<=j); + assert(j<=A_.dim(2)); + assert(0<=i && ij) + return A_(i,j); + else if (i==j) + return one; + else + return zero; + } + + + inline const_reference operator() (Subscript i, Subscript j) const + { + #ifdef TNT_BOUNDS_CHECK + assert(1<=i); + assert(i<=A_.dim(1)); + assert(1<=j); + assert(j<=A_.dim(2)); + #endif + if (i>j) + return A_(i,j); + else if (i==j) + return one; + else + return zero; + } + + + #ifdef TNT_USE_REGIONS + // These are the "index-aware" features + + typedef const_Region2D< UnitLowerTriangularView > + const_Region; + + const_Region operator()(/*const*/ Index1D &I, + /*const*/ Index1D &J) const + { + return const_Region(*this, I, J); + } + + const_Region operator()(Subscript i1, Subscript i2, + Subscript j1, Subscript j2) const + { + return const_Region(*this, i1, i2, j1, j2); + } + #endif + // TNT_USE_REGIONS + }; + + template + LowerTriangularView Lower_triangular_view( + /*const*/ MaTRiX &A) + { + return LowerTriangularView(A); + } + + + template + UnitLowerTriangularView Unit_lower_triangular_view( + /*const*/ MaTRiX &A) + { + return UnitLowerTriangularView(A); + } + + template + VecToR matmult(/*const*/ UnitLowerTriangularView &A, VecToR &x) + { + Subscript M = A.num_rows(); + Subscript N = A.num_cols(); + + assert(N == x.dim()); + + Subscript i, j; + typename MaTRiX::element_type sum=0.0; + VecToR result(M); + + Subscript start = A.lbound(); + Subscript Mend = M + A.lbound() -1 ; + + for (i=start; i<=Mend; i++) + { + sum = 0.0; + for (j=start; j + inline VecToR operator*(/*const*/ UnitLowerTriangularView &A, VecToR &x) + { + return matmult(A,x); + } + + + //********************** Algorithms ************************************* + + + + template + std::ostream& operator<<(std::ostream &s, const LowerTriangularView&A) + { + Subscript M=A.num_rows(); + Subscript N=A.num_cols(); + + s << M << " " << N << endl; + + for (Subscript i=1; i<=M; i++) + { + for (Subscript j=1; j<=N; j++) + { + s << A(i,j) << " "; + } + s << endl; + } + + + return s; + } + + template + std::ostream& operator<<(std::ostream &s, + const UnitLowerTriangularView&A) + { + Subscript M=A.num_rows(); + Subscript N=A.num_cols(); + + s << M << " " << N << endl; + + for (Subscript i=1; i<=M; i++) + { + for (Subscript j=1; j<=N; j++) + { + s << A(i,j) << " "; + } + s << endl; + } + + + return s; + } + + + + // ******************* Upper Triangular Section ************************** + + template + class UpperTriangularView + { + protected: + + + /*const*/ MaTRiX &A_; + /*const*/ typename MaTRiX::element_type zero_; + + public: + + + typedef typename MaTRiX::const_reference const_reference; + typedef /*const*/ typename MaTRiX::element_type element_type; + typedef /*const*/ typename MaTRiX::element_type value_type; + typedef element_type T; + + Subscript dim(Subscript d) const { return A_.dim(d); } + Subscript lbound() const { return A_.lbound(); } + Subscript num_rows() const { return A_.num_rows(); } + Subscript num_cols() const { return A_.num_cols(); } + + + // constructors + + UpperTriangularView(/*const*/ MaTRiX &A) : A_(A), zero_(0) {} + + + inline const_reference get(Subscript i, Subscript j) const + { + #ifdef TNT_BOUNDS_CHECK + assert(lbound()<=i); + assert(i<=A_.num_rows() + lbound() - 1); + assert(lbound()<=j); + assert(j<=A_.num_cols() + lbound() - 1); + #endif + if (i>j) + return zero_; + else + return A_(i,j); + } + + + inline const_reference operator() (Subscript i, Subscript j) const + { + #ifdef TNT_BOUNDS_CHECK + assert(lbound()<=i); + assert(i<=A_.num_rows() + lbound() - 1); + assert(lbound()<=j); + assert(j<=A_.num_cols() + lbound() - 1); + #endif + if (i>j) + return zero_; + else + return A_(i,j); + } + + #ifdef TNT_USE_REGIONS + + typedef const_Region2D< UpperTriangularView > + const_Region; + + const_Region operator()(const Index1D &I, + const Index1D &J) const + { + return const_Region(*this, I, J); + } + + const_Region operator()(Subscript i1, Subscript i2, + Subscript j1, Subscript j2) const + { + return const_Region(*this, i1, i2, j1, j2); + } + + + + #endif + // TNT_USE_REGIONS + + }; + + + /* *********** Upper_triangular_view() algorithms ****************** */ + + template + VecToR matmult(/*const*/ UpperTriangularView &A, VecToR &x) + { + Subscript M = A.num_rows(); + Subscript N = A.num_cols(); + + assert(N == x.dim()); + + Subscript i, j; + typename VecToR::element_type sum=0.0; + VecToR result(M); + + Subscript start = A.lbound(); + Subscript Mend = M + A.lbound() -1 ; + + for (i=start; i<=Mend; i++) + { + sum = 0.0; + for (j=i; j<=N; j++) + sum = sum + A(i,j)*x(j); + result(i) = sum; + } + + return result; + } + + template + inline VecToR operator*(/*const*/ UpperTriangularView &A, VecToR &x) + { + return matmult(A,x); + } + + template + class UnitUpperTriangularView + { + protected: + + const MaTRiX &A_; + const typename MaTRiX::element_type zero; + const typename MaTRiX::element_type one; + + public: + + typedef typename MaTRiX::const_reference const_reference; + typedef typename MaTRiX::element_type element_type; + typedef typename MaTRiX::element_type value_type; + typedef element_type T; + + Subscript lbound() const { return 1; } + Subscript dim(Subscript d) const { return A_.dim(d); } + Subscript num_rows() const { return A_.num_rows(); } + Subscript num_cols() const { return A_.num_cols(); } + + + // constructors + + UnitUpperTriangularView(/*const*/ MaTRiX &A) : A_(A), zero(0), one(1) {} + + + inline const_reference get(Subscript i, Subscript j) const + { + #ifdef TNT_BOUNDS_CHECK + assert(1<=i); + assert(i<=A_.dim(1)); + assert(1<=j); + assert(j<=A_.dim(2)); + assert(0<=i && i > + const_Region; + + const_Region operator()(const Index1D &I, + const Index1D &J) const + { + return const_Region(*this, I, J); + } + + const_Region operator()(Subscript i1, Subscript i2, + Subscript j1, Subscript j2) const + { + return const_Region(*this, i1, i2, j1, j2); + } + #endif + // TNT_USE_REGIONS + }; + + template + UpperTriangularView Upper_triangular_view( + /*const*/ MaTRiX &A) + { + return UpperTriangularView(A); + } + + + template + UnitUpperTriangularView Unit_upper_triangular_view( + /*const*/ MaTRiX &A) + { + return UnitUpperTriangularView(A); + } + + template + VecToR matmult(/*const*/ UnitUpperTriangularView &A, VecToR &x) + { + Subscript M = A.num_rows(); + Subscript N = A.num_cols(); + + assert(N == x.dim()); + + Subscript i, j; + typename VecToR::element_type sum=0.0; + VecToR result(M); + + Subscript start = A.lbound(); + Subscript Mend = M + A.lbound() -1 ; + + for (i=start; i<=Mend; i++) + { + sum = x(i); + for (j=i+1; j<=N; j++) + sum = sum + A(i,j)*x(j); + result(i) = sum + x(i); + } + + return result; + } + + template + inline VecToR operator*(/*const*/ UnitUpperTriangularView &A, VecToR &x) + { + return matmult(A,x); + } + + + //********************** Algorithms ************************************* + + + + template + std::ostream& operator<<(std::ostream &s, + /*const*/ UpperTriangularView&A) + { + Subscript M=A.num_rows(); + Subscript N=A.num_cols(); + + s << M << " " << N << endl; + + for (Subscript i=1; i<=M; i++) + { + for (Subscript j=1; j<=N; j++) + { + s << A(i,j) << " "; + } + s << endl; + } + + + return s; + } + + template + std::ostream& operator<<(std::ostream &s, + /*const*/ UnitUpperTriangularView&A) + { + Subscript M=A.num_rows(); + Subscript N=A.num_cols(); + + s << M << " " << N << endl; + + for (Subscript i=1; i<=M; i++) + { + for (Subscript j=1; j<=N; j++) + { + s << A(i,j) << " "; + } + s << endl; + } + + + return s; + } + + } // namespace TNT + + + + + + #endif + //TRIANG_H + Index: tnt/trisolve.h =================================================================== RCS file: trisolve.h diff -N trisolve.h *** /dev/null Tue May 5 14:32:27 1998 --- trisolve.h Thu Aug 16 13:02:56 2001 *************** *** 0 **** --- 1,184 ---- + /* + * + * Template Numerical Toolkit (TNT): Linear Algebra Module + * + * Mathematical and Computational Sciences Division + * National Institute of Technology, + * Gaithersburg, MD USA + * + * + * This software was developed at the National Institute of Standards and + * Technology (NIST) by employees of the Federal Government in the course + * of their official duties. Pursuant to title 17 Section 105 of the + * United States Code, this software is not subject to copyright protection + * and is in the public domain. The Template Numerical Toolkit (TNT) is + * an experimental system. NIST assumes no responsibility whatsoever for + * its use by other parties, and makes no guarantees, expressed or implied, + * about its quality, reliability, or any other characteristic. + * + * BETA VERSION INCOMPLETE AND SUBJECT TO CHANGE + * see http://math.nist.gov/tnt for latest updates. + * + */ + + + + // Triangular Solves + + #ifndef TRISLV_H + #define TRISLV_H + + + #include "triang.h" + + namespace TNT + { + + template + VecToR Lower_triangular_solve(/*const*/ MaTriX &A, /*const*/ VecToR &b) + { + Subscript N = A.num_rows(); + + // make sure matrix sizes agree; A must be square + + assert(A.num_cols() == N); + assert(b.dim() == N); + + VecToR x(N); + + Subscript i; + for (i=1; i<=N; i++) + { + typename MaTriX::element_type tmp=0; + + for (Subscript j=1; j + VecToR Unit_lower_triangular_solve(/*const*/ MaTriX &A, /*const*/ VecToR &b) + { + Subscript N = A.num_rows(); + + // make sure matrix sizes agree; A must be square + + assert(A.num_cols() == N); + assert(b.dim() == N); + + VecToR x(N); + + Subscript i; + for (i=1; i<=N; i++) + { + + typename MaTriX::element_type tmp=0; + + for (Subscript j=1; j + VecToR linear_solve(/*const*/ LowerTriangularView &A, + /*const*/ VecToR &b) + { + return Lower_triangular_solve(A, b); + } + + template + VecToR linear_solve(/*const*/ UnitLowerTriangularView &A, + /*const*/ VecToR &b) + { + return Unit_lower_triangular_solve(A, b); + } + + + + //********************** Upper triangular section **************** + + template + VecToR Upper_triangular_solve(/*const*/ MaTriX &A, /*const*/ VecToR &b) + { + Subscript N = A.num_rows(); + + // make sure matrix sizes agree; A must be square + + assert(A.num_cols() == N); + assert(b.dim() == N); + + VecToR x(N); + + Subscript i; + for (i=N; i>=1; i--) + { + + typename MaTriX::element_type tmp=0; + + for (Subscript j=i+1; j<=N; j++) + tmp = tmp + A(i,j)*x(j); + + x(i) = (b(i) - tmp)/ A(i,i); + } + + return x; + } + + + template + VecToR Unit_upper_triangular_solve(/*const*/ MaTriX &A, /*const*/ VecToR &b) + { + Subscript N = A.num_rows(); + + // make sure matrix sizes agree; A must be square + + assert(A.num_cols() == N); + assert(b.dim() == N); + + VecToR x(N); + + Subscript i; + for (i=N; i>=1; i--) + { + + typename MaTriX::element_type tmp=0; + + for (Subscript j=i+1; j + VecToR linear_solve(/*const*/ UpperTriangularView &A, + /*const*/ VecToR &b) + { + return Upper_triangular_solve(A, b); + } + + template + VecToR linear_solve(/*const*/ UnitUpperTriangularView &A, + /*const*/ VecToR &b) + { + return Unit_upper_triangular_solve(A, b); + } + + + } // namespace TNT + + #endif + // TRISLV_H Index: tnt/vec.h =================================================================== RCS file: vec.h diff -N vec.h *** /dev/null Tue May 5 14:32:27 1998 --- vec.h Thu Aug 16 13:02:56 2001 *************** *** 0 **** --- 1,403 ---- + /* + * + * Template Numerical Toolkit (TNT): Linear Algebra Module + * + * Mathematical and Computational Sciences Division + * National Institute of Technology, + * Gaithersburg, MD USA + * + * + * This software was developed at the National Institute of Standards and + * Technology (NIST) by employees of the Federal Government in the course + * of their official duties. Pursuant to title 17 Section 105 of the + * United States Code, this software is not subject to copyright protection + * and is in the public domain. The Template Numerical Toolkit (TNT) is + * an experimental system. NIST assumes no responsibility whatsoever for + * its use by other parties, and makes no guarantees, expressed or implied, + * about its quality, reliability, or any other characteristic. + * + * BETA VERSION INCOMPLETE AND SUBJECT TO CHANGE + * see http://math.nist.gov/tnt for latest updates. + * + */ + + + // Basic TNT numerical vector (0-based [i] AND 1-based (i) indexing ) + // + + #ifndef VEC_H + #define VEC_H + + #include "tnt/subscript.h" + #include + #include + #include + #include + + namespace TNT + { + + template + class Vector + { + + + public: + + typedef Subscript size_type; + typedef T value_type; + typedef T element_type; + typedef T* pointer; + typedef T* iterator; + typedef T& reference; + typedef const T* const_iterator; + typedef const T& const_reference; + + Subscript lbound() const { return 1;} + + protected: + T* v_; + T* vm1_; // pointer adjustment for optimized 1-offset indexing + Subscript n_; + + // internal helper function to create the array + // of row pointers + + void initialize(Subscript N) + { + // adjust pointers so that they are 1-offset: + // v_[] is the internal contiguous array, it is still 0-offset + // + assert(v_ == NULL); + v_ = new T[N]; + assert(v_ != NULL); + vm1_ = v_-1; + n_ = N; + } + + void copy(const T* v) + { + Subscript N = n_; + Subscript i; + + #ifdef TNT_UNROLL_LOOPS + Subscript Nmod4 = N & 3; + Subscript N4 = N - Nmod4; + + for (i=0; i &A) : v_(0), vm1_(0), n_(0) + { + initialize(A.n_); + copy(A.v_); + } + + Vector(Subscript N, const T& value = T()) : v_(0), vm1_(0), n_(0) + { + initialize(N); + set(value); + } + + Vector(Subscript N, const T* v) : v_(0), vm1_(0), n_(0) + { + initialize(N); + copy(v); + } + + Vector(Subscript N, const char *s) : v_(0), vm1_(0), n_(0) + { + initialize(N); + std::istringstream ins(s); + + Subscript i; + + for (i=0; i> v_[i]; + } + + + // methods + // + Vector& newsize(Subscript N) + { + if (n_ == N) return *this; + + destroy(); + initialize(N); + + return *this; + } + + + // assignments + // + Vector& operator=(const Vector &A) + { + if (v_ == A.v_) + return *this; + + if (n_ == A.n_) // no need to re-alloc + copy(A.v_); + + else + { + destroy(); + initialize(A.n_); + copy(A.v_); + } + + return *this; + } + + Vector& operator=(const T& scalar) + { + set(scalar); + return *this; + } + + inline Subscript dim() const + { + return n_; + } + + inline Subscript size() const + { + return n_; + } + + + inline reference operator()(Subscript i) + { + #ifdef TNT_BOUNDS_CHECK + assert(1<=i); + assert(i <= n_) ; + #endif + return vm1_[i]; + } + + inline const_reference operator() (Subscript i) const + { + #ifdef TNT_BOUNDS_CHECK + assert(1<=i); + assert(i <= n_) ; + #endif + return vm1_[i]; + } + + inline reference operator[](Subscript i) + { + #ifdef TNT_BOUNDS_CHECK + assert(0<=i); + assert(i < n_) ; + #endif + return v_[i]; + } + + inline const_reference operator[](Subscript i) const + { + #ifdef TNT_BOUNDS_CHECK + assert(0<=i); + + + + + + + assert(i < n_) ; + #endif + return v_[i]; + } + + + + }; + + + /* *************************** I/O ********************************/ + + template + std::ostream& operator<<(std::ostream &s, const Vector &A) + { + Subscript N=A.dim(); + + s << N << endl; + + for (Subscript i=0; i + std::istream & operator>>(std::istream &s, Vector &A) + { + + Subscript N; + + s >> N; + + if ( !(N == A.size() )) + { + A.newsize(N); + } + + + for (Subscript i=0; i> A[i]; + + + return s; + } + + // *******************[ basic matrix algorithms ]*************************** + + + template + Vector operator+(const Vector &A, + const Vector &B) + { + Subscript N = A.dim(); + + assert(N==B.dim()); + + Vector tmp(N); + Subscript i; + + for (i=0; i + Vector operator-(const Vector &A, + const Vector &B) + { + Subscript N = A.dim(); + + assert(N==B.dim()); + + Vector tmp(N); + Subscript i; + + for (i=0; i + Vector operator*(const Vector &A, + const Vector &B) + { + Subscript N = A.dim(); + + assert(N==B.dim()); + + Vector tmp(N); + Subscript i; + + for (i=0; i + T dot_prod(const Vector &A, const Vector &B) + { + Subscript N = A.dim(); + assert(N == B.dim()); + + Subscript i; + T sum = 0; + + for (i=0; i + #include + #include + #include + + #include "tnt/subscript.h" + + #ifdef TNT_USE_REGIONS + #include "tnt/region1d.h" + #endif + + namespace TNT + { + + // see "tntreq.h" for TNT requirements for underlying vector + // class. This need NOT be the STL vector<> class, but a subset + // that provides minimal services. + // + // This is a container adaptor that provides the following services. + // + // o) adds 1-offset operator() access ([] is always 0 offset) + // o) adds TNT_BOUNDS_CHECK to () and [] + // o) adds initialization from strings, e.g. "1.0 2.0 3.0"; + // o) adds newsize(N) function (does not preserve previous values) + // o) adds dim() and dim(1) + // o) adds free() function to release memory used by vector + // o) adds regions, e.g. A(Index(1,10)) = ... + // o) add getVector() method to return adapted container + // o) adds simple I/O for ostreams + + template + class Vector_Adaptor + { + + public: + typedef typename BBVec::value_type T; + typedef T value_type; + typedef T element_type; + typedef T* pointer; + typedef T* iterator; + typedef T& reference; + typedef const T* const_iterator; + typedef const T& const_reference; + + Subscript lbound() const { return 1; } + + protected: + BBVec v_; + T* vm1_; + + public: + + Subscript size() const { return v_.size(); } + + // These were removed so that the ANSI C++ valarray class + // would work as a possible storage container. + // + // + //iterator begin() { return v_.begin();} + //iterator begin() { return &v_[0];} + // + //iterator end() { return v_.end(); } + //iterator end() { return &v_[0] + v_.size(); } + // + //const_iterator begin() const { return v_.begin();} + //const_iterator begin() const { return &v_[0];} + // + //const_iterator end() const { return v_.end(); } + //const_iterator end() const { return &v_[0] + v_.size(); } + + BBVec& getVector() { return v_; } + Subscript dim() const { return v_.size(); } + Subscript dim(Subscript i) + { + #ifdef TNT_BOUNDS_CHECK + assert(i==TNT_BASE_OFFSET); + #endif + return (i==TNT_BASE_OFFSET ? v_.size() : 0 ); + } + Vector_Adaptor() : v_() {}; + Vector_Adaptor(const Vector_Adaptor &A) : v_(A.v_) + { + vm1_ = ( v_.size() > 0 ? &(v_[0]) -1 : NULL); + + } + + Vector_Adaptor(Subscript N, const char *s) : v_(N) + { + istringstream ins(s); + for (Subscript i=0; i> v_[i] ; + + vm1_ = ( v_.size() > 0 ? &(v_[0]) -1 : NULL); + }; + + Vector_Adaptor(Subscript N, const T& value = T()) : v_(N) + { + for (Subscript i=0; i 0 ? &(v_[0]) -1 : NULL); + } + + Vector_Adaptor(Subscript N, const T* values) : v_(N) + { + for (Subscript i=0; i 0 ? &(v_[0]) -1 : NULL); + } + Vector_Adaptor(const BBVec & A) : v_(A) + { + vm1_ = ( v_.size() > 0 ? &(v_[0]) -1 : NULL); + } + + // NOTE: this assumes that BBVec(0) constructor creates an + // null vector that does not take up space... It would be + // great to require that BBVec have a corresponding free() + // function, but in particular STL vectors do not. + // + Vector_Adaptor& free() + { + return *this = Vector_Adaptor(0); + } + + Vector_Adaptor& operator=(const Vector_Adaptor &A) + { + v_ = A.v_ ; + vm1_ = ( v_.size() > 0 ? &(v_[0]) -1 : NULL); + return *this; + } + + Vector_Adaptor& newsize(Subscript N) + { + // NOTE: this is not as efficient as it could be + // but to retain compatiblity with STL interface + // we cannot assume underlying implementation + // has a newsize() function. + + return *this = Vector_Adaptor(N); + + } + + Vector_Adaptor& operator=(const T &a) + { + Subscript i; + Subscript N = v_.size(); + for (i=0; i& resize(Subscript N) + { + if (N == size()) return *this; + + Vector_Adaptor tmp(N); + Subscript n = (N < size() ? N : size()); // min(N, size()); + Subscript i; + + for (i=0; i > Region; + + typedef const_Region1D< Vector_Adaptor > const_Region; + + Region operator()(const Index1D &I) + { return Region(*this, I); } + + Region operator()(const Subscript i1, Subscript i2) + { return Region(*this, i1, i2); } + + const_Region operator()(const Index1D &I) const + { return const_Region(*this, I); } + + const_Region operator()(const Subscript i1, Subscript i2) const + { return const_Region(*this, i1, i2); } + #endif + // TNT_USE_REGIONS + + + }; + + #include + + template + std::ostream& operator<<(std::ostream &s, const Vector_Adaptor &A) + { + Subscript M=A.size(); + + s << M << endl; + for (Subscript i=1; i<=M; i++) + s << A(i) << endl; + return s; + } + + template + std::istream& operator>>(std::istream &s, Vector_Adaptor &A) + { + Subscript N; + + s >> N; + + A.resize(N); + + for (Subscript i=1; i<=N; i++) + s >> A(i); + + return s; + } + + } // namespace TNT + + #endif Index: tnt/version.h =================================================================== RCS file: version.h diff -N version.h *** /dev/null Tue May 5 14:32:27 1998 --- version.h Thu Aug 16 13:02:56 2001 *************** *** 0 **** --- 1,20 ---- + // Template Numerical Toolkit (TNT) for Linear Algebra + // + // BETA VERSION INCOMPLETE AND SUBJECT TO CHANGE + // Please see http://math.nist.gov/tnt for updates + // + // R. Pozo + // Mathematical and Computational Sciences Division + // National Institute of Standards and Technology + + + #ifndef TNT_VERSION_H + #define TNT_VERSION_H + + + #define TNT_MAJOR_VERSION '0' + #define TNT_MINOR_VERSION '9' + #define TNT_SUBMINOR_VERSION '4' + #define TNT_VERSION_STRING "0.9.4" + + #endif From oldham at codesourcery.com Thu Aug 16 21:26:22 2001 From: oldham at codesourcery.com (Jeffrey Oldham) Date: Thu, 16 Aug 2001 14:26:22 -0700 Subject: [newfield_revision Patch] Use std::abs, not abs Message-ID: <20010816142622.B20968@codesourcery.com> We want to use std::abs() which supports double arguments, not abs()'s integral arguments. 2001-08-16 Jeffrey D. Oldham * Pooma/PoomaOperatorTags.h (UnaryReturn): Change abs() to std::abs(). * Utilities/Tester.h (Tester::check(const char *, const T&, const T&, const T&)): Likewise. Applied to newfield_revision branch of examples/NewField/StatigraphicFlow/ Approved by Stephen Smith Tested on sequential Linux using gcc 3.0.1 by compiling Pooma library and NewField tests Thanks, Jeffrey D. Oldham oldham at codesourcery.com -------------- next part -------------- Index: Pooma/PoomaOperatorTags.h =================================================================== RCS file: /home/pooma/Repository/r2/src/Pooma/PoomaOperatorTags.h,v retrieving revision 1.17 diff -c -p -r1.17 PoomaOperatorTags.h *** Pooma/PoomaOperatorTags.h 2001/03/28 19:14:51 1.17 --- Pooma/PoomaOperatorTags.h 2001/08/16 20:43:28 *************** struct FnAbs *** 52,58 **** inline typename UnaryReturn::Type_t operator()(const T &a) const { ! return (abs(a)); } }; --- 52,58 ---- inline typename UnaryReturn::Type_t operator()(const T &a) const { ! return (std::abs(a)); } }; Index: Utilities/Tester.h =================================================================== RCS file: /home/pooma/Repository/r2/src/Utilities/Tester.h,v retrieving revision 1.11 diff -c -p -r1.11 Tester.h *** Utilities/Tester.h 2001/06/28 18:56:53 1.11 --- Utilities/Tester.h 2001/08/16 20:43:29 *************** public: *** 213,219 **** bool check(const char *str, const T &val, const T &correct, const T &tol) { ! bool res = check(abs(val - correct) < tol); if (str != 0) out() << "Checking " << str; else --- 213,219 ---- bool check(const char *str, const T &val, const T &correct, const T &tol) { ! bool res = check(std::abs(val - correct) < tol); if (str != 0) out() << "Checking " << str; else From oldham at codesourcery.com Thu Aug 16 21:35:58 2001 From: oldham at codesourcery.com (Jeffrey Oldham) Date: Thu, 16 Aug 2001 14:35:58 -0700 Subject: [mainline Patch] pretty.pl: Fix Spelling Mistake Message-ID: <20010816143558.C20968@codesourcery.com> 2001-08-16 Jeffrey D. Oldham * pretty.pl: Fix spelling mistake. Untested. Approved by Stephen Smith Applied to mainline Thanks, Jeffrey D. Oldham oldham at codesourcery.com -------------- next part -------------- Index: pretty.pl =================================================================== RCS file: /home/pooma/Repository/r2/config/Shared/pretty.pl,v retrieving revision 1.10 diff -c -p -r1.10 pretty.pl *** pretty.pl 1999/07/21 22:19:35 1.10 --- pretty.pl 2001/08/10 01:06:20 *************** *** 37,43 **** # laa, 6/9/97 ##################################################################### local($DEBUG) = 0; ! local($generic_target) = ""; local($mode) = shift(@ARGV); local($target)= shift(@ARGV); if ($DEBUG) { --- 37,43 ---- # laa, 6/9/97 ##################################################################### local($DEBUG) = 0; ! local($generic_target) = ""; local($mode) = shift(@ARGV); local($target)= shift(@ARGV); if ($DEBUG) { From gdr at codesourcery.com Fri Aug 17 00:47:41 2001 From: gdr at codesourcery.com (Gabriel Dos Reis) Date: 17 Aug 2001 02:47:41 +0200 Subject: Profiling POOMA: How to? Message-ID: Profiling POOMA (with gprof) compiled with KCC or GCC This is a short note to let you get started with profiling POOMA compiled with KCC or GCC using gprof as a profiler. That proceeds in three steps: (i) Setting architecture dependent compiler options (ii) Compiling the POOMA library, benchmarks and running them (iii) Producing profiling information. Note that both the library and the program being tested have to be compiled with profiling on, or else you won't have profiling information about the parts not compiled with profiling on. Normally setting correctly options in the configuration file once should be OK. I) Setting architecture dependent compiler options To specify profiling options, you need to modify the architecture configuration file to be used to build POOMA. If you're using KCC then you have to modify config/arch/KCC.conf so as to set both KCC specific options and the back-end C compiler options to include the appropriate profiling option -- when using gprof, that option is usually '-pg'. On my machine (a Linux box) I have the following ### debug or optimized build settings for C++ applications $cppdbg_app = "+K0 -g -pg"; $cppopt_app = "+K3 -O -DNOPAssert -DNOCTAssert -pg"; $cppopt_app .= " --inline_keyword_space_time=10000"; # .... ### debug or optimized build settings for C applications $cdbg_app = "-g -pg"; $copt_app = "-O3 -pg -funroll-loops -fstrict-aliasing"; According to KCC documentation, the following plateforms understand '-pg': Linux on Intel x86 Solaris/SPARC Compaq Tru64 Unix HP-UX If you're using a profiling tool other than gprof you can instruct KCC about that profiler with the following syntax --backend If you're using GCC, then naturally the profiler option for gprof is spelled '-pg' when using both g++ and gcc :-) [ At this point I suspect it would be much flexible to specify the target specific profiling option at configure level instead of modifying config/arch/.conf ] II) Compiling the POOMA library, benchmarks and running them These steps are as usual, e.g. ./configure --arch LINUXKCC --suite LINUXKCC --opt # [ configure blah blah ] export POMMASUITE=LINUXKCC && make -j 3 # [ make blah blah ] cd benchmarks/SimpleArray && make -j 3 # [ make blah blah ] cd LINUXKCC && ./atest --run-impls 2 # [ benchmark blah blah ] Note that when you run the benchmark (or the program you're profiling), it will produce, as a side effect, a file named 'gmon.out' in your *working directory* (well actually the last directory the running program was working in). That file will be created if and only if the program terminates normally, i.e. if it aborts then you won't have any profiling information. The file 'gmon.out' contains the information needed by gprof in the next step. III) Producing profiling information. To produce the actual profiling information, you have to invoke gprof and the program being profiled as its argument. Since gprof writes directly on the standard output, you might want to use a redirection : gprof atest > atest-pooma.prof The profile output has essentially three parts 1) Flat profile 2) Call graph (most inteersting when trying to improve efficiency) 3) The index of the functions. The output of gprof is pretty much well documented and self-contained. You might want to read the man page for specific options. If your system is a Linux box, I would recommand info gprog as the info page is much more documented than the man page. A caveat ======== Since KCC does unexpected transformations with your C++ program when heavily optimizing, trying to profile on basic-block basis won't work. However you can profile on line-by-line basis or basic-block basis with g++ since that compiler does not any unexpected rewriting. I hope this will be useful. If you have further questions, please don't hesitate to ask, I'll try to answer them (within my competence). -- Gaby CodeSourcery, LLC http://www.codesourcery.com From scotth at proximation.com Fri Aug 17 18:02:54 2001 From: scotth at proximation.com (Scott Haney) Date: Fri, 17 Aug 2001 12:02:54 -0600 Subject: Mesh functors - please review [newfield_revision] Message-ID: Attached is a patchUniformRectilinarMesh.h adding functor support for computing positions, normals (outward and coordinate), cell volumes, face areas, and edge lengths. This also includes two functions requested by Julian: vetexPosition() and cellContaining() along with a minor bug-fix for a problem introduced when we started to use some new centering functions. I'd appreciate it if someone could review this. I will be checking in a test of these functors as well once this is done. Scott -------------- next part -------------- Attached is a patchUniformRectilinarMesh.h adding functor support for computing positions, normals (outward and coordinate), cell volumes, face areas, and edge lengths. This also includes two functions requested by Julian: vetexPosition() and cellContaining() along with a minor bug-fix for a problem introduced when we started to use some new centering functions. I'd appreciate it if someone could review this. I will be checking in a test of these functors as well once this is done. Scott -------------- next part -------------- A non-text attachment was scrubbed... Name: 081701.1.patch Type: application/applefile Size: 74 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: 081701.1.patch Type: application/octet-stream Size: 9724 bytes Desc: not available URL: From JimC at proximation.com Tue Aug 21 15:09:32 2001 From: JimC at proximation.com (James Crotinger) Date: Tue, 21 Aug 2001 09:09:32 -0600 Subject: [pooma-dev] Speeding Pooma Code on a Branch? Message-ID: I'm with Mark - for the most part performance tuning won't involve interface changes unless the results of analysis indicate that certain things need redesigned. So I'd say that generic performance tweeks should just go in the main branch, and if we end up redesigning certain abstractions then we can talk about doing those on a branch. Jim > -----Original Message----- > From: Jeffrey Oldham [mailto:oldham at codesourcery.com] > Sent: Tuesday, August 14, 2001 9:43 PM > To: pooma-dev at pooma.codesourcery.com > Subject: [pooma-dev] Speeding Pooma Code on a Branch? > > > > Soon some Pooma developers will turn to reducing Pooma's > running time. Should we modify the code on a separate branch, e.g., > the running_time branch, so that the Blanca people's use of the > mainline is not affected? > > Hopefully next week, the newfield_revision branch will be > merged into whichever branch we choose. > > Thanks, > Jeffrey D. Oldham > oldham at codesourcery.com > -------------- next part -------------- An HTML attachment was scrubbed... URL: From JimC at proximation.com Tue Aug 21 16:11:19 2001 From: JimC at proximation.com (James Crotinger) Date: Tue, 21 Aug 2001 10:11:19 -0600 Subject: [pooma-dev] Plan for Reducing Pooma's Running Time Message-ID: > -----Original Message----- > From: Jeffrey Oldham [mailto:oldham at codesourcery.com] > Sent: Tuesday, August 14, 2001 9:47 PM > To: pooma-dev at pooma.codesourcery.com > Subject: [pooma-dev] Plan for Reducing Pooma's Running Time > [...] > To permit comparisons between executions of different programs, we can > compute the abstraction ratio for using data-parallel or Pooma2 > abstractions. The abstraction ratio is the ratio of a program's > running time to the corresponding C program's running time. We want > this ratio to be at most one. Two comments: First, I think you just said that we want to have the abstraction penalty be negative ("the ratio to be at most one"), which strikes me as unlikely. Especially if the C compiler takes advantage of restrict. Second, it is impractical for us to write C code for comparison with the POOMA kernals running in parallel. Or at least it is impractical to do this for very many kernels. Thus we also need to look at scaling and other measurements of parallel performance. > We need to resolve timing granularity problems and which time > measurements to make, e.g., wall-clock or CPU time. This is really only an issue with the Benchmark class or other experiments that simply amount to timing the execution of an entire run. The profiling tools shouldn't have this problem. > > > Infrastructure: > > We should establish daily builds and benchmark runs to check that > running times do not increase while we try to reduce running times. > Running times on both Irix and Linux is desirable. We'll use QMTest > to perform the testing. > > Question: Should we post these reports on a daily basis? Probably not - if we could automate putting them on a website, that would be cool. > > We should use KCC. Some preliminary performance indicates that KCC's > and gcc's performances differ. Tools to profile the code include > Linux's gprof (instructions available in info pages and > http://sources.redhat.com/binutils/docs-2.10/gprof.html) and Irix's > ssrun(1) and prof(1). > > Question: Are there other profiling tools? When I tried gprof with KCC, it crashed (gprof did, that is). I haven't yet looked at Gaby's notes to figure out if I did something wrong, or if we have a different configuration. At any rate, gprof is OK for serial benchmarking, which is where we want to start, but we need something else when we start benchmarking in parallel. The tool that we've used before is called Tau. I think there are some links to it on the acl web site. I've never used it on linux, so we'll have to check that out. I believe this is supposed to work either with threads or with message passing, but currently it doesn't handle both. But neither does POOMA at this point, so that's OK. > Work: > > Scott Haney suggests first speeding Array execution since (New)Fields > use Arrays. A good initial step would be checking that the KCC > optimizer produces code similar to C code without Pooma abstraction > overheads. I've run ABCTest with KCC and, not too surprisingly, there is an observed abstraction penalty - the C code got about 45 MFlops for large arrays, and the POOMA (Brick) code got about 30. Given that these asymptotic results should be measuring memory speed, this is probably the result of the C loops being jammed or something, resulting in some load-store optimizations that the optimizer can't do with the POOMA code since POOMA does not inline everything. I haven't looked at the C output from KCC yet (which can be a pain to decipher - there used to be a product called "cback" that was designed to clean up the output from CFRONT. I wonder if it still exists.). > First, we can compare C-style arrays with Brick Array > engines on uniprocessor machines. Then, we work with multipatch Array > engines, trying to reduce the overhead of having multiple patches. > Trying various patch sizes on a uniprocessor machine will demonstrate > the overhead of having multipatches. We'll defer threaded and > multi-processor execution to later. The various benchmarks and the Benchmark class were designed with these sort of tests in mind. > > Stephen will soon post a list of Array benchmarks, what they test, and > what they do not test. We can write additional programs to fill any > deficiencies in our testing. Each individual researcher can speed a > benchmark's execution. > > Work on the NewField should be delayed until Stephen Smith and I merge > our work into the mainline. Currently, there is one benchmark program > benchmarks/Doof2d that use NewField.h. We also will have the Lee et > al. statigraphic flow code. Are these sufficient for testing? If > not, should we write more test cases? Will we want to finish the > Caramana et al. hydrodynamics program? > > Question: Who besides Jeffrey has access to a multi-processor computer > with more than a handful of processors? I've got an account on chi now, and should be able to get back onto nirvana without too much hassle (I hope). > > Question: Do we need to check for memory leaks? Bluemountain has > purify, which should reveal leaks. Perhaps we can modify the QMTest > scripts to ease checking. This isn't a performance issue, but we definitely want to put purify in our test suite. > > Procedure for Modifying Pooma Code: > > Even though we'll probably work on a separate development branch, we > need to ensure that the Pooma code compiles at all times to permit > multiple programmers to work on the same code. Before committing a > code change, > > 1. Make sure the Pooma library compiles with the change. Also check > that associated executables still run. > 2. Obtain patch approval from at least one other person. > 3. Commit the patch. > 4. Send email to pooma-dev at pooma.codesourcery.com, listing > a. the changes and an explanation, > b. the test platform, and > c. the patch approver. I never do step 4 - given that all this information should be in the CVS checkin message and that we have a CVS mailing list, why make a redundant post to pooma-dev? > > To Do List: > > o Complete this list. > o Add this list in the Pooma CVS tree for easy sharing and > modification. > o Describe the existing benchmarks. Stephen > o Determine what execution tasks are not covered by existing > code. Stephen > o Determine interesting benchmarks using Arrays. > Stephen recommends starting with benchmarks/Doof2dUMP. Gaby? > o Establish nightly Pooma builds for Linux and Irix, producing summary > reports. Jeffrey > o Ensure Pooma compiles with the threads package. Jim? I can work on SMARTS. I think it is important that we get Tau up and working with POOMA on the platforms that we'll be profiling on. This may not be a small task. Jim -------------- next part -------------- An HTML attachment was scrubbed... URL: From JimC at proximation.com Tue Aug 21 16:17:19 2001 From: JimC at proximation.com (James Crotinger) Date: Tue, 21 Aug 2001 10:17:19 -0600 Subject: [pooma-dev] Profiling POOMA: How to? Message-ID: > -----Original Message----- > From: Gabriel Dos Reis [mailto:gdr at codesourcery.com] > Sent: Thursday, August 16, 2001 6:48 PM > To: pooma-dev at pooma.codesourcery.com > Subject: [pooma-dev] Profiling POOMA: How to? > > > > Profiling POOMA (with gprof) > compiled with KCC or GCC > > This is a short note to let you get started with profiling POOMA > compiled with KCC or GCC using gprof as a profiler. That proceeds in > three steps: > > (i) Setting architecture dependent compiler options > (ii) Compiling the POOMA library, benchmarks and running them > (iii) Producing profiling information. > > Note that both the library and the program being tested have to be > compiled with profiling on, or else you won't have profiling > information about the parts not compiled with profiling on. Normally > setting correctly options in the configuration file once should be > OK. > > I) Setting architecture dependent compiler options > > To specify profiling options, you need to modify the architecture > configuration file to be used to build POOMA. > > If you're using KCC then you have to modify > config/arch/KCC.conf We should probably add a -gprof option to configure to have it make these additions itself. That way you'd be guaranteed that the entire "suite" would be consistent. > [ At this point I suspect it would be much flexible to specify the > target specific profiling option at configure level instead of > modifying config/arch/.conf ] Right. > III) Producing profiling information. > > To produce the actual profiling information, you have to invoke > gprof and the program being profiled as its argument. Since gprof > writes directly on the standard output, you might want to use a > redirection : > > gprof atest > atest-pooma.prof When I do this on my linux box (with ABCTest), gprof goes away for a very long time and then core dumps (after printing a message about not being able to allocate several gigabytes of memory). Any ideas? Is this related to your caveat? Jim -------------- next part -------------- An HTML attachment was scrubbed... URL: From jxyh at lanl.gov Tue Aug 21 16:31:02 2001 From: jxyh at lanl.gov (John Hall) Date: Tue, 21 Aug 2001 10:31:02 -0600 Subject: Branches In-Reply-To: References: Message-ID: For what it is worth. I am at the point where I would try to prevent anyone from our project checking out a new Pooma until October 1st. Maybe at this point we should go on the branch and you guys should return to the head. Just let us know what the branch tag is and we will be set. John P.S. Is there a scheme you can come up with that would allow us to make some progress on making our setup code parallel? We are running short on time now and the biggest remaining problem is our inability to run in parallel due to little setup issues (and ensight dumps) that I haven't gotten around to fixing. The physics is almost complete and appears to be working spectacularly well (really, really, well). We can win this bet and give Pooma/Blanca new life if we run in parallel. FWIW, Jeff Brown has allocated the money for your contract through next February. We are going to be evaluated then for its continuation. So rumors that the contract might disappear are unfounded. From stephens at proximation.com Tue Aug 21 17:19:54 2001 From: stephens at proximation.com (Stephen Smith) Date: Tue, 21 Aug 2001 11:19:54 -0600 Subject: FieldOffset reductions patch. Message-ID: This patch to newfield_revision allows data-parallel reductions using field offsets. The new syntax is: g = sum(f, nearestNeighbor(f.centering(), g.centering()), g.centering()); which sums the points in f that are nearest to the points in g and assigns the results to g. I also fixed a problem with the domain of discontinuous fields by making the translation between domains more explicit. This was reviewed by Jeffrey, and tested on linux with KCC. Stephen <<21Aug.reduction.2.patch>> -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: 21Aug.reduction.2.patch Type: application/octet-stream Size: 28166 bytes Desc: not available URL: From scotth at proximation.com Tue Aug 21 17:30:29 2001 From: scotth at proximation.com (Scott Haney) Date: Tue, 21 Aug 2001 11:30:29 -0600 Subject: [pooma-dev] RE: Branches In-Reply-To: Message-ID: Hi John, What do you need from us to get parallel working? Scott On Tuesday, August 21, 2001, at 10:31 AM, John Hall wrote: > P.S. Is there a scheme you can come up with that would allow us to make > some progress on making our setup code parallel? We are running short > on time now and the biggest remaining problem is our inability to run > in parallel due to little setup issues (and ensight dumps) that I > haven't gotten around to fixing. The physics is almost complete and > appears to be working spectacularly well (really, really, well). We can > win this bet and give Pooma/Blanca new life if we run in parallel. > > FWIW, Jeff Brown has allocated the money for your contract through next > February. We are going to be evaluated then for its continuation. So > rumors that the contract might disappear are unfounded. -- Scott W. Haney Development Manager Proximation LLC 2960 Rodeo Park Drive West Santa Fe, NM 87505 Voice: 505-424-3809 x101 FAX: 505-438-4161 From stephens at proximation.com Tue Aug 21 18:24:32 2001 From: stephens at proximation.com (Stephen Smith) Date: Tue, 21 Aug 2001 12:24:32 -0600 Subject: patch local patch on newfield_revision Message-ID: This patch was ported from the main branch to fix a bug in the way the patchLocal() function worked on fields. Here is the original comment from the main branch: Fixed the patchLocal function on field. Now the patchLocal function returns a field with the correct physical domain and a total domain that includes guard layers (possibly internal guards). Added a test, incorrectly called LocalPatch which verifies correctness of the function, and illustrates how to write SPMD code by getting views of the pieces of a field that are local to the processor. 2001-08-20 Jeffrey D. Oldham * Field.h: Include FieldEnginePatch.h. (Patch::dim): New enumeration. (Patch::make): Revise to use FieldEnginePatch. (Patch>>): New class. * FieldEngine/FieldEngine.Lagrangian.h (FieldEngine::FieldEngine): Revise to use FieldEnginePatch. * FieldEngine/FieldEngine.NoGeometry.h: Likewise. * FieldEngine/FieldEngine.UR.h: Likewise. * FieldEngine/FieldEngineBase.h: Include FieldEnginePatch.h. (FieldEngineBase::initialize): Revise to use FieldEnginePatch parameter. Revise definition. * tests/makefile (run_tests): Add LocalPatch. (MeshTest1): Move to alphabetical order. (LocalPatch): Add PHONY target. <<21Aug.LocalPatch.4.patch>> -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: 21Aug.LocalPatch.4.patch Type: application/octet-stream Size: 27359 bytes Desc: not available URL: From stephens at proximation.com Tue Aug 21 22:08:37 2001 From: stephens at proximation.com (Stephen Smith) Date: Tue, 21 Aug 2001 16:08:37 -0600 Subject: RFA benchmarks (Plans for speeding up POOMA) Message-ID: Attached are some notes I wrote up for Jeffrey to explain some of the terminology used in our benchmark codes along with some recommendations for steps we might want to take to use the existing benchmarks in the performance work for the contract. The benchmark codes (in r2/benchmarks) were intended to encapsulate small kernels that we wish to optimize POOMA's performance on. The benchmarks are handy tools since they can report the performance for several implementations of a given kernel, and let you control the number of iterations etc. The optimization work should probably contain a mix of work on larger applications as well as examining benchmarks. Please post comments on these notes. I believe Jeffrey Oldham is coming up with an overall plan for the optimization work. Stephen Smith <> -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: benchmark_notes Type: application/octet-stream Size: 7635 bytes Desc: not available URL: From scotth at proximation.com Tue Aug 21 22:20:12 2001 From: scotth at proximation.com (Scott Haney) Date: Tue, 21 Aug 2001 16:20:12 -0600 Subject: [pooma-dev] RFA benchmarks (Plans for speeding up POOMA) In-Reply-To: Message-ID: Thanks Stephen, One critical aspect of "making things run fast" is making sure that things run correctly in parallel, across multiple SMPs, using MPI. Our plan needs to include this and this work should be front-loaded because it is very important to Blanca for their 10/1 milestone. Scott On Tuesday, August 21, 2001, at 04:08 PM, Stephen Smith wrote: > Attached are some notes I wrote up for Jeffrey to explain some > of the terminology used in our benchmark codes along with some > recommendations for steps we might want to take to use the > existing benchmarks in the performance work for the contract. > > The benchmark codes (in r2/benchmarks) were intended to > encapsulate small kernels that we wish to optimize POOMA's > performance on. The benchmarks are handy tools since they can > report the performance for several implementations of a given > kernel, and let you control the number of iterations etc. > The optimization work should probably contain a mix of work > on larger applications as well as examining benchmarks. > > Please post comments on these notes.? I believe > Jeffrey Oldham is coming up with an overall plan for the > optimization work. > > ??? Stephen Smith > > <> > > -- Scott W. Haney Development Manager Proximation LLC 2960 Rodeo Park Drive West Santa Fe, NM 87505 Voice: 505-424-3809 x101 FAX: 505-438-4161 -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: text/enriched Size: 1589 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: benchmark_notes Type: application/octet-stream Size: 7635 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: text/enriched Size: 170 bytes Desc: not available URL: From stephens at proximation.com Wed Aug 22 16:03:43 2001 From: stephens at proximation.com (Stephen Smith) Date: Wed, 22 Aug 2001 10:03:43 -0600 Subject: patch: add field offset reductions Message-ID: This patch makes src/NewField/DiffOps/FieldOffsetReduction.h available. 2001-08-21 Jeffrey D. Oldham * NewFields.h: Add FieldOffsetReduction.h. Tested on sequential Linux using gcc 3.0.1 by compiling library and NewField tests Approved by smith Applied to newfield_revision branch <> -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: NewFields.21Aug.19.4.patch Type: application/octet-stream Size: 501 bytes Desc: not available URL: From stephens at proximation.com Thu Aug 23 23:02:46 2001 From: stephens at proximation.com (Stephen Smith) Date: Thu, 23 Aug 2001 17:02:46 -0600 Subject: patch: added mesh to new fields. Message-ID: Added mesh to new field. The only syntax change is that fields now take a mesh as the first parameter, and provide a .mesh() function. Also, flattened the implementation of FieldEngine to just store an array of engines rather than the previous recursive structure. Also, removed offsets() from field engine, since the orientations() in centering should be used instead. *benchmarks/Doof2d/Doof2dInP2.h, examples/NewField/Caramana.cpp, examples/NewField/StatigraphicFlow.cpp, src/NewField/tests/*.cpp -mostly changed UniformRectilinear to UniformRectilinearMesh *src/Engine/*.cpp - added default constructors to a lot of engines. *src/NewField/Field.h - added mesh() and some new subfield accesors *src/NewField/FieldEngine.h FieldEngine.ExprEngine.h -replaced FieldEngineBase and all the existing field engines with a single implementation that stores the mesh *src/NewField/DiffOps/*, src/NewField/Mesh/*, src/NewField/Relations/* -removed offsets, changed to get information from the mesh now Tested with KCC on linux. Reviewed by Haney. Stephen <<23Aug.mesh.2.patch>> -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: 23Aug.mesh.2.patch Type: application/octet-stream Size: 228000 bytes Desc: not available URL: From gdr at codesourcery.com Fri Aug 24 00:47:00 2001 From: gdr at codesourcery.com (Gabriel Dos Reis) Date: 24 Aug 2001 02:47:00 +0200 Subject: [pooma-dev] Profiling POOMA: How to? (3/3) In-Reply-To: James Crotinger's message of "Tue, 21 Aug 2001 10:17:19 -0600" References: Message-ID: IHRoZSBpbmRleCBudW1iZXIuCgoKIEZvciB0aGUgZnVuY3Rpb24ncyBwYXJlbnRzLCB0aGUg ZmllbGRzIGhhdmUgdGhlIGZvbGxvd2luZyBtZWFuaW5nczoKCiAgICAgc2VsZglUaGlzIGlz IHRoZSBhbW91bnQgb2YgdGltZSB0aGF0IHdhcyBwcm9wYWdhdGVkIGRpcmVjdGx5CgkJZnJv bSB0aGUgZnVuY3Rpb24gaW50byB0aGlzIHBhcmVudC4KCiAgICAgY2hpbGRyZW4JVGhpcyBp cyB0aGUgYW1vdW50IG9mIHRpbWUgdGhhdCB3YXMgcHJvcGFnYXRlZCBmcm9tCgkJdGhlIGZ1 bmN0aW9uJ3MgY2hpbGRyZW4gaW50byB0aGlzIHBhcmVudC4KCiAgICAgY2FsbGVkCVRoaXMg aXMgdGhlIG51bWJlciBvZiB0aW1lcyB0aGlzIHBhcmVudCBjYWxsZWQgdGhlCgkJZnVuY3Rp b24gYC8nIHRoZSB0b3RhbCBudW1iZXIgb2YgdGltZXMgdGhlIGZ1bmN0aW9uCgkJd2FzIGNh bGxlZC4gIFJlY3Vyc2l2ZSBjYWxscyB0byB0aGUgZnVuY3Rpb24gYXJlIG5vdAoJCWluY2x1 ZGVkIGluIHRoZSBudW1iZXIgYWZ0ZXIgdGhlIGAvJy4KCiAgICAgbmFtZQlUaGlzIGlzIHRo ZSBuYW1lIG9mIHRoZSBwYXJlbnQuICBUaGUgcGFyZW50J3MgaW5kZXgKCQludW1iZXIgaXMg cHJpbnRlZCBhZnRlciBpdC4gIElmIHRoZSBwYXJlbnQgaXMgYQoJCW1lbWJlciBvZiBhIGN5 Y2xlLCB0aGUgY3ljbGUgbnVtYmVyIGlzIHByaW50ZWQgYmV0d2VlbgoJCXRoZSBuYW1lIGFu ZCB0aGUgaW5kZXggbnVtYmVyLgoKIElmIHRoZSBwYXJlbnRzIG9mIHRoZSBmdW5jdGlvbiBj YW5ub3QgYmUgZGV0ZXJtaW5lZCwgdGhlIHdvcmQKIGA8c3BvbnRhbmVvdXM+JyBpcyBwcmlu dGVkIGluIHRoZSBgbmFtZScgZmllbGQsIGFuZCBhbGwgdGhlIG90aGVyCiBmaWVsZHMgYXJl IGJsYW5rLgoKIEZvciB0aGUgZnVuY3Rpb24ncyBjaGlsZHJlbiwgdGhlIGZpZWxkcyBoYXZl IHRoZSBmb2xsb3dpbmcgbWVhbmluZ3M6CgogICAgIHNlbGYJVGhpcyBpcyB0aGUgYW1vdW50 IG9mIHRpbWUgdGhhdCB3YXMgcHJvcGFnYXRlZCBkaXJlY3RseQoJCWZyb20gdGhlIGNoaWxk IGludG8gdGhlIGZ1bmN0aW9uLgoKICAgICBjaGlsZHJlbglUaGlzIGlzIHRoZSBhbW91bnQg b2YgdGltZSB0aGF0IHdhcyBwcm9wYWdhdGVkIGZyb20gdGhlCgkJY2hpbGQncyBjaGlsZHJl biB0byB0aGUgZnVuY3Rpb24uCgogICAgIGNhbGxlZAlUaGlzIGlzIHRoZSBudW1iZXIgb2Yg dGltZXMgdGhlIGZ1bmN0aW9uIGNhbGxlZAoJCXRoaXMgY2hpbGQgYC8nIHRoZSB0b3RhbCBu dW1iZXIgb2YgdGltZXMgdGhlIGNoaWxkCgkJd2FzIGNhbGxlZC4gIFJlY3Vyc2l2ZSBjYWxs cyBieSB0aGUgY2hpbGQgYXJlIG5vdAoJCWxpc3RlZCBpbiB0aGUgbnVtYmVyIGFmdGVyIHRo ZSBgLycuCgogICAgIG5hbWUJVGhpcyBpcyB0aGUgbmFtZSBvZiB0aGUgY2hpbGQuICBUaGUg Y2hpbGQncyBpbmRleAoJCW51bWJlciBpcyBwcmludGVkIGFmdGVyIGl0LiAgSWYgdGhlIGNo aWxkIGlzIGEKCQltZW1iZXIgb2YgYSBjeWNsZSwgdGhlIGN5Y2xlIG51bWJlciBpcyBwcmlu dGVkCgkJYmV0d2VlbiB0aGUgbmFtZSBhbmQgdGhlIGluZGV4IG51bWJlci4KCiBJZiB0aGVy ZSBhcmUgYW55IGN5Y2xlcyAoY2lyY2xlcykgaW4gdGhlIGNhbGwgZ3JhcGgsIHRoZXJlIGlz IGFuCiBlbnRyeSBmb3IgdGhlIGN5Y2xlLWFzLWEtd2hvbGUuICBUaGlzIGVudHJ5IHNob3dz IHdobyBjYWxsZWQgdGhlCiBjeWNsZSAoYXMgcGFyZW50cykgYW5kIHRoZSBtZW1iZXJzIG9m IHRoZSBjeWNsZSAoYXMgY2hpbGRyZW4uKQogVGhlIGArJyByZWN1cnNpdmUgY2FsbHMgZW50 cnkgc2hvd3MgdGhlIG51bWJlciBvZiBmdW5jdGlvbiBjYWxscyB0aGF0CiB3ZXJlIGludGVy bmFsIHRvIHRoZSBjeWNsZSwgYW5kIHRoZSBjYWxscyBlbnRyeSBmb3IgZWFjaCBtZW1iZXIg c2hvd3MsCiBmb3IgdGhhdCBtZW1iZXIsIGhvdyBtYW55IHRpbWVzIGl0IHdhcyBjYWxsZWQg ZnJvbSBvdGhlciBtZW1iZXJzIG9mCiB0aGUgY3ljbGUuCgoMCkluZGV4IGJ5IGZ1bmN0aW9u IG5hbWUKCiBbMjIwXSBfX0NQUjEwMV9fX19hc19fMzBEYXRhQmxvY2tQdHJfX3RtX18xMF9k WENiTF8xXzBGUkMyN0RhdGFCbG9ja1B0cl9fdG1fXzhfWjFaWFoyWl9SSjQxSiBbMjU1XSBB QkNJbkNwcFRyYW5fX3RtX18xNV81QnJpY2tYQ2JMXzFfMDo6X19kdCh2b2lkKSBbMjhdIHN0 ZDo6Zml4ZWQoc3RkOjppb3NfYmFzZSAmKQogWzI0MF0gX19DUFIxMTFfX19fZHRfX1EyXzNz dGQ5NHZlY3Rvcl9fdG1fXzgwX1BRMl81UG9vbWExNFN0YXRpc3RpY3NEYXRhUTJfM3N0ZDQ0 YWxsb2NhdG9yX190bV9fMjdfUFEyX0ozNEpKNDBKRnYgWzI1Nl0gQUJDSW5QMl9fdG1fXzI4 XzE3Q29tcHJlc3NpYmxlQnJpY2tYQ2JMXzFfMDo6X19kdCh2b2lkKSBbMjFdIHN0ZDo6Zmx1 c2goSW5mb3JtICYpCiBbMjIxXSBfX0NQUjExOV9fX19hc19fNDZFbmdpbmVfX3BzX18xNF9Y WjFaWjJaNUJyaWNrX190bV9fMTBfWENpTF8xXzJkRlJDMjhFbmdpbmVfX3RtX19KMjBKX1JK NTdKIFsyNTddIEFCQ0luUDJfX3RtX18yOF8xN0NvbXByZXNzaWJsZUJyaWNrWENiTF8xXzE6 Ol9fZHQodm9pZCkgWzE2XSBJbmZvcm06OmZsdXNoKHZvaWQpCiBbMjMyXSBfX0NQUjExOV9f aW5zZXJ0X2F1eF9fUTJfM3N0ZDc2dmVjdG9yX190bV9fNjJfUDE0SW1wbGVtZW50YXRpb25R Ml8zc3RkMzVhbGxvY2F0b3JfX3RtX18xOF9QSjM3SkZRMl9aMlo3cG9pbnRlclJDWjFaX3Yg WzIxOF0gRW5naW5lX19wc19fMTRfWFoxWloyWjVCcmlja19fdG1fXzEwX1hDaUxfMV8yZDo6 X19kdCh2b2lkKSBbMjddIHN0ZDo6YmFzaWNfb3N0cmVhbV9fdG1fXzMxX2NRMl8zc3RkMjBj aGFyX3RyYWl0c19fdG1fXzJfYzo6Zmx1c2goc3RkOjpiYXNpY19vc3RyZWFtX190bV9fN19a MVpaMlogJih2b2lkKSkKICBbMTRdIF9fQ1BSMTIzX19fX2xzX190bV9fMzBfUTJfM3N0ZDIw Y2hhcl90cmFpdHNfX3RtX18yX2NfXzNzdGRGUlEyXzNzdGQyNWJhc2ljX29zdHJlYW1fX3Rt X181X2NaMVpQQ2NfUlEyXzNzdGRKNTdKIFsxMV0gRW5naW5lX19wc19fMThfWFoxWloyWjlC cmlja1ZpZXdfX3RtX18xMF9YQ2lMXzFfMmQ6Ol9fZHQodm9pZCkgWzU0XSBCZW5jaG1hcms6 OmdldFJlYWR5VG9SdW4odm9pZCkKIFsyMzNdIF9fQ1BSMTM3X19pbnNlcnRfYXV4X19RMl8z c3RkOTR2ZWN0b3JfX3RtX184MF9QUTJfNVBvb21hMTRTdGF0aXN0aWNzRGF0YVEyXzNzdGQ0 NGFsbG9jYXRvcl9fdG1fXzI3X1BRMl9KNDBKSjQ2SkZRMl9aMlo3cG9pbnRlclJDWjFaX3Yg WzIzNV0gRW5naW5lX19wc19fMjdfWFoxWloyWjE3Q29tcHJlc3NpYmxlQnJpY2tfX3RtX18x MF9YQ2lMXzFfMmQ6Ol9fZHQodm9pZCkgWzI1XSBQb29tYTo6aW5jcmVtZW50TnVtRXhwcmVz c2lvbnMobG9uZykKIFsyNDFdIF9fQ1BSMTY1X19fX2R0X19RMl8zc3RkMTQ3dmVjdG9yX190 bV9fMTMyX1EyXzNzdGQ0M3ZlY3Rvcl9fdG1fXzI5X2RRMl8zc3RkMThhbGxvY2F0b3JfX3Rt X18yX2RRMl8zc3RkNzBhbGxvY2F0b3JfX3RtX181M19RMl8zc3RkSjM5SkZ2IFsyNThdIEFC Q0luQzo6X19kdCh2b2lkKSBbMTJdIFBvb21hOjppbmNyZW1lbnROdW1JbmxpbmVFdmFsdWF0 aW9ucyhsb25nKQogWzI0Ml0gX19DUFIxNzZfX19fYXNfX1EyXzNzdGQ3OGJhc2ljX3N0cmlu Z19fdG1fXzU4X2NRMl8zc3RkMjBjaGFyX3RyYWl0c19fdG1fXzJfY1EyXzNzdGQxOGFsbG9j YXRvcl9fdG1fXzJfY0ZSQ1EyXzNzdGQzMGJhc2ljX3N0cmluZ19fdG1fXzEwX1oxWloyWloz Wl9SUTJfM3N0ZEoxMDNKIFsyNTldIEJlbmNobWFyazo6X19kdCh2b2lkKSBbNDVdIFBvb21h OjppbmZvTWVzc2FnZXMoYm9vbCkKIFsyMzBdIF9fQ1BSMTc5X19tYWtlX25vZGVfX1EyXzVf X2thaTEyMm1hcF9iYXNlX190bV9fMTA1X2lQMTJJbmZvcm1TdHJlYW1RMl8zc3RkMTNsZXNz X190bV9fMl9pUTJfM3N0ZDU3YWxsb2NhdG9yX190bV9fNDBfUTJfM3N0ZDMwcGFpcl9fdG1f XzE4X0NpUEo0M0pGUEN2X1BRMl9KMTRKMTdyYl90cmVlX25vZGVfYmFzZSBbMjI1XSBzdGQ6 OnZlY3Rvcl9fdG1fXzI5X2RRMl8zc3RkMThhbGxvY2F0b3JfX3RtX18yX2Q6Ol9fZHQoICh2 b2lkKSkgWzEwXSBpbml0aWFsaXplX180NUFCQ1Rlc3RCYXNlX19wc19fMTJfWjFaWENiTF8x XzBfX3RtX183XzVCcmlja0ZpX3YKIFsyNDNdIF9fQ1BSMTkxX19pbnNlcnRfYXV4X19RMl8z c3RkMTQ3dmVjdG9yX190bV9fMTMyX1EyXzNzdGQ0M3ZlY3Rvcl9fdG1fXzI5X2RRMl8zc3Rk MThhbGxvY2F0b3JfX3RtX18yX2RRMl8zc3RkNzBhbGxvY2F0b3JfX3RtX181M19RMl8zc3Rk SjQ1SkZRMl9aMlo3cG9pbnRlclJDWjFaX3YgWzI2MF0gc3RkOjp2ZWN0b3JfX3RtX18yOV9p UTJfM3N0ZDE4YWxsb2NhdG9yX190bV9fMl9pOjpfX2R0KCAodm9pZCkpIFs1NV0gUG9vbWE6 OmluaXRpYWxpemUoUG9vbWE6Ok9wdGlvbnMgJiwgYm9vbCwgYm9vbCkKIFsyNDRdIF9fQ1BS MjM2X19fX2R0X19RMl8zc3RkMjE4dmVjdG9yX190bV9fMjAzX1EyXzNzdGQ3OGJhc2ljX3N0 cmluZ19fdG1fXzU4X2NRMl8zc3RkMjBjaGFyX3RyYWl0c19fdG1fXzJfY1EyXzNzdGQxOGFs bG9jYXRvcl9fdG1fXzJfY1EyXzNzdGQxMDVhbGxvY2F0b3JfX3RtX184OF9RMl8zc3RkSjM5 SkZ2IFsyMzldIHN0ZDo6dmVjdG9yX190bV9fMzFfUGNRMl8zc3RkMTlhbGxvY2F0b3JfX3Rt X18zX1BjOjpfX2R0KCAodm9pZCkpIFs1Nl0gUG9vbWE6OmluaXRpYWxpemUoaW50ICYsIGNo YXIgKiomLCBib29sLCBib29sLCBib29sKQogICBbN10gX19DUFIzMzNfX2V2YWx1YXRlX190 bV9fMjQ3XzMzQXJyYXlfX3RtX18yMF9YQ2lMXzFfMmQ5QnJpY2tWaWV3MTk5QXJyYXlfX3Rt X18xODVfWENpTF8xXzJkMTcyRXhwcmVzc2lvblRhZ19fdG1fXzE1MF8xNDZCaW5hcnlOb2Rl X190bV9fMTI3XzVPcEFkZEoxOEo4M0JpbmFyeU5vZGVfX3RtX182NV8xME9wTXVsdGlwbHkx NVNjYWxhcl9fdG1fXzJfZEoxOEo4T3BBc3NpZ25fXzQ2RXZhbHVhdG9yX190bV9fMjZfMjNT aW5nbGVQYXRjaEV2YWx1YXRvclRhZ19fU0NGUkNaMVpSQ1ozWlJDWjJaX3YgWzI2MV0gc3Rk Ojp2ZWN0b3JfX3BzX181X2JaMVpfX3RtX18yOF9RMl8zc3RkMThhbGxvY2F0b3JfX3RtX18y X2I6Ol9fZHQoICh2b2lkKSkgWzU3XSBpbnNlcnRfYXV4X19RMl8zc3RkNDN2ZWN0b3JfX3Rt X18yOV9pUTJfM3N0ZDE4YWxsb2NhdG9yX190bV9fMl9pRlEyX1oyWjdwb2ludGVyUkNaMVpf dgogICBbNl0gX19DUFIzNDBfX2V2YWx1YXRlX190bV9fMjU0XzMzQXJyYXlfX3RtX18yMF9Y Q2lMXzFfMmQ5QnJpY2tWaWV3MjA2QXJyYXlfX3RtX18xOTJfWENpTF8xXzJkMTc5RXhwcmVz c2lvblRhZ19fdG1fXzE1N18xNTNCaW5hcnlOb2RlX190bV9fMTM0XzEwT3BNdWx0aXBseTE1 U2NhbGFyX190bV9fMl9kMTAxQmluYXJ5Tm9kZV9fdG1fXzgzXzEwT3BTdWJ0cmFjdEoxOEpK MThKOE9wQXNzaWduX180NkV2YWx1YXRvcl9fdG1fXzI2XzIzU2luZ2xlUGF0Y2hFdmFsdWF0 b3JUYWdfX1NDRlJDWjFaUkNaM1pSQ1oyWl92IFsyMTRdIHN0ZDo6YmFzaWNfc3RyaW5nX190 bV9fNThfY1EyXzNzdGQyMGNoYXJfdHJhaXRzX190bV9fMl9jUTJfM3N0ZDE4YWxsb2NhdG9y X190bV9fMl9jOjpfX2R0KCAodm9pZCkpIFs0MF0gUG9vbWE6OmludEFyZ3VtZW50KGludCwg Y2hhciAqKiwgaW50LCBpbnQgJikKICBbMThdIFZpZXcwX19wc19fSjIwSl9fdG1fX0ozNkpP WjJaUTNfOTROZXdFbmdpbmVfX3RtX183N19RMl9KMjNKOjpfX0NQUjUxN19fbWFrZV9fMjY2 VmlldzBfX3BzX18yN18yNEFycmF5X190bV9fMTFfWFoxWloyWlozWl9fdG1fXzIxN19YQ2lM XzFfMmQyMDRFeHByZXNzaW9uVGFnX190bV9fMTgyXzE3OEJpbmFyeU5vZGVfX3RtX18xNTlf NU9wQWRkNDlSZWZlcmVuY2VfX3RtX18zMl8yOUFycmF5X190bV9fMTZfWENpTF8xXzJkNUJy aWNrOTlCaW5hcnlOb2RlX190bV9fODFfMTBPcE11bHRpcGx5MTVTY2FsYXJfX3RtX18yX2RK MTIzSlNGUkNKMjNKXzIwOEFycmF5X190bV9fMTk0X1hPY3NpMTY5bmV3RGltKEVuZ2luZV90 LCBfX2NvbXBsZXggSjhEb21haW5fdDZUeXBlX3Q1VGFnX3Q6OikgWzIxNV0gUG9vbWE6OkJy aWNrQmFzZV9fdG1fXzlfWENpTF8xXzI6Ol9fZHQoICh2b2lkKSkgWzI5XSBJbXBsZW1lbnRh dGlvbjo6aW50ZXJuYWxDbG9ja0NhbGxzKCBjb25zdCh2b2lkKSkKICBbMTldIFZpZXcwX19w c19fSjIwSl9fdG1fX0ozNkpPWjJaUTNfOTROZXdFbmdpbmVfX3RtX183N19RMl9KMjNKOjpf X0NQUjUyNV9fbWFrZV9fMjc0VmlldzBfX3BzX18yN18yNEFycmF5X190bV9fMTFfWFoxWloy WlozWl9fdG1fXzIyNV9YQ2lMXzFfMmQyMTJFeHByZXNzaW9uVGFnX190bV9fMTkwXzE4NkJp bmFyeU5vZGVfX3RtX18xNjdfMTBPcE11bHRpcGx5MTVTY2FsYXJfX3RtX18yX2QxMzRCaW5h cnlOb2RlX190bV9fMTE1XzEwT3BTdWJ0cmFjdDQ5UmVmZXJlbmNlX190bV9fMzJfMjlBcnJh eV9fdG1fXzE2X1hDaUxfMV8yZDVCcmlja0oxODFKU0ZSQ0oyM0pfMjA4QXJyYXlfX3RtX18x OTRfWE9jc2kxNjluZXdEaW0oRW5naW5lX3QsIF9fY29tcGxleCBKOERvbWFpbl90NlR5cGVf dDVUYWdfdDo6KSBbMTNdIFBvb21hOjpCcmlja1ZpZXdCYXNlX190bV9fOV9YQ2lMXzFfMjo6 X19kdCggKHZvaWQpKSBbMzBdIHN0ZDo6bGVmdChzdGQ6Omlvc19iYXNlICYpCiBbMjM2XSBf X0NQUjkzX19fX2R0X19RMl8zc3RkNzZ2ZWN0b3JfX3RtX182Ml9QMTRJbXBsZW1lbnRhdGlv blEyXzNzdGQzNWFsbG9jYXRvcl9fdG1fXzE4X1BKMzFKRnYgWzI2Ml0gUG9vbWE6Ok9wdGlv bnM6Ol9fZHQoICh2b2lkKSkgWzU4XSBzdGQ6OmJhc2ljX2lvc19fdG1fXzMxX2NRMl8zc3Rk MjBjaGFyX3RyYWl0c19fdG1fXzJfYzo6bG9hZF9udW1fcHV0X2ZhY2V0KHZvaWQgY29uc3Qo dm9pZCkpCiBbMjQ1XSBQb29tYTo6T3B0aW9uczo6b3BlcmF0b3I9KCAoUG9vbWE6Ok9wdGlv bnMgY29uc3QgJikpIFsyMTldIHN0ZDo6YmFzaWNfb3N0cmVhbV9fdG1fXzMxX2NRMl8zc3Rk MjBjaGFyX3RyYWl0c19fdG1fXzJfYzo6b3BlcmF0b3I8PChzdGQ6OmJhc2ljX29zdHJlYW1f X3RtX183X1oxWloyWiAmKGxvbmcpKSBbNDZdIFBvb21hOjpsb2dNZXNzYWdlcyhjaGFyIGNv bnN0ICopCiBbMjEyXSBEYXRhQmxvY2tQdHJfX3RtX18xMF9kWENiTF8xXzA6Ol9fY3QoRGF0 YUJsb2NrUHRyX190bV9fOF9aMVpYWjJaIGNvbnN0ICYsIGludCkgWzIzMV0gX19tb2RpZnlf X1EyXzVfX2thaTQ5cmJfdHJlZV9fdG1fXzM0X2lRMl8zc3RkMTNsZXNzX190bV9fMl9pWENV aUxfMl8xNkZSQ1oxWlBiUTNfNV9fa2FpMTJyYl90cmVlX2Jhc2UxMW1vZGlmeV9tb2RlX1BR Ml81X19rYWkxN3JiX3RyZWVfbm9kZV9iYXNlIFszMV0gQUJDVGVzdEJhc2VfX3BzX18xMl9a MVpYQ2JMXzFfMF9fdG1fXzdfNUJyaWNrOjpvcENvdW50KGRvdWJsZSBjb25zdCh2b2lkKSkK IFsyMjJdIERhdGFCbG9ja1B0cl9fdG1fXzEwX2RYQ2JMXzFfMDo6X19jdCh1bnNpZ25lZCBp bnQpIFsyNjNdIF9fc3RpX19BQkNfY3BwX21haW4gWzQyXSBJbmZvcm06Om9wZW4oc3RkOjpi YXNpY19vc3RyZWFtX190bV9fMzFfY1EyXzNzdGQyMGNoYXJfdHJhaXRzX190bV9fMl9jICYs IGludCkKIFsyMjNdIEVuZ2luZV9fcHNfXzE0X1haMVpaMlo1QnJpY2tfX3RtX18xMF9YQ2lM XzFfMmQ6Ol9fY3QoUG9vbWE6OkJyaWNrQmFzZV9fdG1fXzVfWFoxWjo6RG9tYWluX3QgY29u c3QgJikgWzI2NF0gX19zdGlfX0JlbmNobWFya19jbXBsX2NwcF8yZWVjN2E3NyBbNDddIElu Zm9ybTo6b3BlbihpbnQpCiBbMjM3XSBQb29sOjpfX2N0KHVuc2lnbmVkIGludCkgWzI2NV0g X19zdGlfX0luZm9ybV9jbXBsX2NwcF9hZWExYzQxMiBbNTldIFBvb21hOjpPcHRpb25zOjpw YXJzZSggKGludCAmLCBjaGFyICoqJikpCiBbMjQ2XSBBQkNUZXN0QmFzZV9fcHNfXzEyX1ox WlhDYkxfMV8wX190bV9fMjBfMTdDb21wcmVzc2libGVCcmljazo6X19jdChpbnQpIFsyNjZd IF9fc3RpX19PcHRpb25zX2NtcGxfY3BwX2U4YzVkNzg4IFsyMF0gQmVuY2htYXJrOjpwcmlu dFJlc3VsdHModm9pZCkKIFsyNDddIEFCQ0luQzo6X19jdCh2b2lkKSAgICBbMjY3XSBfX3N0 aV9fUEFzc2VydF9jbXBsX2NwcF82NDgxNTk1NyBbNjBdIFBvb21hOjpwcmludFN0YXRzKHZv aWQpCiBbMjM0XSBJbmZvcm06Ol9fY3QoY2hhciBjb25zdCAqLCBzdGQ6OmJhc2ljX29zdHJl YW1fX3RtX18zMV9jUTJfM3N0ZDIwY2hhcl90cmFpdHNfX3RtX18yX2MgJiwgaW50KSBbMjY4 XSBfX3N0aV9fUG9vbWFfY21wbF9jcHBfZjAwOTQ1MGQgWzQxXSBBQkNJblAyX190bV9fMTVf NUJyaWNrWENiTF8xXzA6OnF1YWxpZmljYXRpb24oY2hhciBjb25zdCAqY29uc3Qodm9pZCkp CiBbMjM4XSBJbmZvcm06Ol9fY3QoY2hhciBjb25zdCAqLCBpbnQpIFsyNjldIF9fc3RpX19T dGF0aXN0aWNzX2NtcGxfY3BwXzhhNTAwYTFiIFs0OF0gUG9vbWE6Ok9wdGlvbnM6OnJlc2V0 KCAodm9pZCkpCiBbMjQ4XSBCZW5jaG1hcms6Ol9fY3QoaW50LCBjaGFyICoqLCBjaGFyIGNv bnN0ICosIGludCkgWzI3MF0gX19zdGlfX1Rlc3Rlcl9jbXBsX2NwcF9hZjEwMWYzYyBbMzJd IEFCQ1Rlc3RCYXNlX19wc19fMTJfWjFaWENiTF8xXzBfX3RtX183XzVCcmljazo6cmVzdWx0 Q2hlY2soZG91YmxlIGNvbnN0KHZvaWQpKQogWzI0OV0gc3RkOjp2ZWN0b3JfX3RtX18yOV9k UTJfM3N0ZDE4YWxsb2NhdG9yX190bV9fMl9kOjpfX2N0KCAoc3RkOjp2ZWN0b3JfX3RtX183 X1oxWloyWiBjb25zdCAmKSkgWzI3MV0gX19zdGlfX1VuaXF1ZV9jbXBsX2NwcF9hZGYxYjA2 OSBbMzNdIHN0ZDo6cmlnaHQoc3RkOjppb3NfYmFzZSAmKQogWzIyN10gX19jdF9fUTJfM3N0 ZDc4YmFzaWNfc3RyaW5nX190bV9fNThfY1EyXzNzdGQyMGNoYXJfdHJhaXRzX190bV9fMl9j UTJfM3N0ZDE4YWxsb2NhdG9yX190bV9fMl9jRlBDWjFaUkNaM1ogWzIyNl0gX2luaXRpYWxp emVfc3RvcmFnZV9fUTJfM3N0ZDQzdmVjdG9yX190bV9fMjlfZFEyXzNzdGQxOGFsbG9jYXRv cl9fdG1fXzJfZEZRMl9aMlo5c2l6ZV90eXBlUkNaMVpfdiBbM10gQmVuY2htYXJrOjpydW5J bXBsZW1lbnRhdGlvbihJbXBsZW1lbnRhdGlvbiAqLCBpbnQpCiBbMjI4XSBfX2N0X19RMl8z c3RkNzhiYXNpY19zdHJpbmdfX3RtX181OF9jUTJfM3N0ZDIwY2hhcl90cmFpdHNfX3RtX18y X2NRMl8zc3RkMThhbGxvY2F0b3JfX3RtX18yX2NGUkNRMl8zc3RkMzBiYXNpY19zdHJpbmdf X3RtX18xMF9aMVpaMlpaM1pRMl9aM1o5c2l6ZV90eXBlVDJSQ1ozWiBbMzZdIEJlbmNobWFy azo6YWRkSW1wbGVtZW50YXRpb24oSW1wbGVtZW50YXRpb24gKikgWzRdIEJlbmNobWFyazo6 cnVuSXQodm9pZCkKIFsyNTBdIFBvb21hOjpTdGF0aXN0aWNzOjpfX2N0KCAodm9pZCkpIFsz NF0gX19rYWk6Omx3X3ZlY3Rvcl9fdG1fXzIyX1BRM18zc3RkNmxvY2FsZTVmYWNldDo6YXNz aWduKHZvaWQgKF9fa2FpOjpsd192ZWN0b3JfX3RtX180X1oxWiBjb25zdCAmLCB1bnNpZ25l ZCBpbnQpKSBbOV0gcnVuU2V0dXBfXzQ1QUJDVGVzdEJhc2VfX3BzX18xMl9aMVpYQ2JMXzFf MF9fdG1fXzdfNUJyaWNrRnZfdgogWzIyNF0gUG9vbWE6OkJyaWNrQmFzZV9fdG1fXzlfWENp TF8xXzI6Ol9fY3QoIChJbnRlcnZhbF9fdG1fXzVfWFoxWiBjb25zdCAmLCBib29sKSkgWzI2 XSBQb29tYTo6YmxvY2tBbmRFdmFsdWF0ZSh2b2lkKSBbNV0gcnVuX18zMEFCQ0luUDJfX3Rt X18xNV81QnJpY2tYQ2JMXzFfMEZ2X3YKIFsyMjldIFBvb21hOjpCcmlja0Jhc2VfX3RtX185 X1hDaUxfMV8yOjpfX2N0KCAoYm9vbCkpIFsyNF0gUG9vbWE6OmJsb2NraW5nRXhwcmVzc2lv bnModm9pZCkgWzFdIEJlbmNobWFyazo6cnVuKHZvaWQpCiAgWzE1XSBQb29tYTo6QnJpY2tW aWV3QmFzZV9fdG1fXzlfWENpTF8xXzI6Ol9fY3QoIChQb29tYTo6QnJpY2tCYXNlX190bV9f NV9YWjFaIGNvbnN0ICYsIEludGVydmFsX190bV9fNV9YWjFaIGNvbnN0ICYpKSBbNTFdIFBv b21hOjpfX05Qb29tYV9jbXBsX2NwcF9mMDA5NDUwZDo6Y2xlYW51cF9zKCAodm9pZCkpIFsy M10gUG9vbWE6OnNjaGVkdWxlcih2b2lkKQogWzI1MV0gUG9vbWE6Ok9wdGlvbnM6Ol9fY3Qo IChpbnQgJiwgY2hhciAqKikpIFszOV0gSW5mb3JtOjpjbG9zZSh2b2lkKSBbMzVdIEluZm9y bTo6c2V0T3V0cHV0TGV2ZWwoaW50KQogWzI1Ml0gUG9vbWE6Ok9wdGlvbnM6Ol9fY3QoICh2 b2lkKSkgWzQzXSBQb29tYTo6ZGVidWdMZXZlbChpbnQpIFszN10gSW5mb3JtOjpzZXRQcmVm aXgoY2hhciBjb25zdCAqKQogWzIxNl0gc3RkOjpiYXNpY19vc3RyZWFtX190bV9fMzFfY1Ey XzNzdGQyMGNoYXJfdHJhaXRzX190bV9fMl9jOjpzZW50cnk6Ol9fY3QoIChzdGQ6OmJhc2lj X29zdHJlYW1fX3RtX183X1oxWloyWiAmKSkgWzE3XSBzdGQ6OmVuZGwoSW5mb3JtICYpIFs2 MV0gQmVuY2htYXJrOjpzZXRTYW1wbGluZ1BhcmFtZXRlcnMoaW50LCBpbnQsIGludCkKIFsy MTNdIF9fY3RfX3RtX18yN18yNEludGVydmFsX190bV9fOV9YQ2lMXzFfMl9fNDFBcnJheV9f dG1fXzI4X1hDaUxfMV8yZDE2Q29uc3RhbnRGdW5jdGlvbkZSQ1oxXzJaIFs0NF0gUG9vbWE6 OmVycm9yTWVzc2FnZXMoYm9vbCkgWzM4XSBJbmZvcm06OnNldHVwKGNoYXIgY29uc3QgKikK IFsyNTNdIEFCQ0luUDJfX3RtX18xNV81QnJpY2tYQ2JMXzFfMDo6X19kdCh2b2lkKSBbOF0g ZXZhbHVhdGVfX3RtX184OF8zM0FycmF5X190bV9fMjBfWENpTF8xXzJkOUJyaWNrVmlldzQx QXJyYXlfX3RtX18yOF9YQ2lMXzFfMmQxNkNvbnN0YW50RnVuY3Rpb244T3BBc3NpZ25fXzQ2 RXZhbHVhdG9yX190bV9fMjZfMjNTaW5nbGVQYXRjaEV2YWx1YXRvclRhZ19fU0NGUkNaMVpS Q1ozWlJDWjJaX3YgWzQ5XSBBQkNJblAyX190bV9fMTVfNUJyaWNrWENiTF8xXzA6OnR5cGUo Y2hhciBjb25zdCAqY29uc3Qodm9pZCkpCiBbMjU0XSBBQkNJblAyX190bV9fMTVfNUJyaWNr WENiTF8xXzE6Ol9fZHQodm9pZCkgWzUyXSBQb29tYTo6ZmluYWxpemUoYm9vbCwgYm9vbCkg WzUwXSBQb29tYTo6d2Fybk1lc3NhZ2VzKGJvb2wpCiBbMjE3XSBEYXRhQmxvY2tQdHJfX3Rt X18xMF9kWENiTF8xXzA6Ol9fZHQodm9pZCkgWzUzXSBQb29tYTo6ZmluYWxpemUodm9pZCkg WzIyXSA8Y3ljbGUgMT4K --Multipart_Fri_Aug_24_02:46:57_2001-1-- From gdr at codesourcery.com Fri Aug 24 00:46:58 2001 From: gdr at codesourcery.com (Gabriel Dos Reis) Date: 24 Aug 2001 02:46:58 +0200 Subject: [pooma-dev] Profiling POOMA: How to? (1/3) In-Reply-To: James Crotinger's message of "Tue, 21 Aug 2001 10:17:19 -0600" References: Message-ID: James Crotinger writes: [...] | > III) Producing profiling information. | > | > To produce the actual profiling information, you have to invoke | > gprof and the program being profiled as its argument. Since gprof | > writes directly on the standard output, you might want to use a | > redirection : | > | > gprof atest > atest-pooma.prof | | When I do this on my linux box (with ABCTest), gprof goes away for a very | long time and then core dumps (after printing a message about not being able | to allocate several gigabytes of memory). Any ideas? Is this related to your | caveat? Hmm, I'm embarrased because I don't (yet) have any idea of why you're seeing that behaviour. Which parameters did you run the ABC test with? I tried the following to see whether I'll get a core dump ./ABC --run-impls 2 --sim-params 1 3 100 and the test completed fine, but I strongly suspect I must be testing with the wrong parameters (the "nan" part is a bit intriguing). The output is in ABC.out and the profiling information (flat profile and call graph) is in ABC.prof, all attached. I'm using GNU gprof-2.10.91 on a linux box. Thanks, -- Gaby -------------- next part -------------- A non-text attachment was scrubbed... Name: ABC.out Type: application/octet-stream Size: 25295 bytes Desc: not available URL: -------------- next part -------------- -------------- next part -------------- A non-text attachment was scrubbed... Name: ABC.prof Type: application/octet-stream Size: 24894 bytes Desc: not available URL: From gdr at codesourcery.com Fri Aug 24 00:46:59 2001 From: gdr at codesourcery.com (Gabriel Dos Reis) Date: 24 Aug 2001 02:46:59 +0200 Subject: [pooma-dev] Profiling POOMA: How to? (2/3) In-Reply-To: James Crotinger's message of "Tue, 21 Aug 2001 10:17:19 -0600" References: Message-ID: ICAgIDAuMDAgICAgIDMwMS82MzIxICAgICAgICBpbml0aWFsaXplX180NUFCQ1Rlc3RCYXNl X19wc19fMTJfWjFaWENiTF8xXzBfX3RtX183XzVCcmlja0ZpX3YgWzEwXQogICAgICAgICAg ICAgICAgNy41MyAgICAwLjAwICAgIDMwMTAvNjMyMSAgICAgICAgcnVuU2V0dXBfXzQ1QUJD VGVzdEJhc2VfX3BzX18xMl9aMVpYQ2JMXzFfMF9fdG1fXzdfNUJyaWNrRnZfdiBbOV0KICAg ICAgICAgICAgICAgIDcuNTMgICAgMC4wMCAgICAzMDEwLzYzMjEgICAgICAgIHJ1bl9fMzBB QkNJblAyX190bV9fMTVfNUJyaWNrWENiTF8xXzBGdl92IFs1XQpbOF0gICAgICA0LjIgICAx NS44MSAgICAwLjAwICAgIDYzMjEgICAgICAgICBldmFsdWF0ZV9fdG1fXzg4XzMzQXJyYXlf X3RtX18yMF9YQ2lMXzFfMmQ5QnJpY2tWaWV3NDFBcnJheV9fdG1fXzI4X1hDaUxfMV8yZDE2 Q29uc3RhbnRGdW5jdGlvbjhPcEFzc2lnbl9fNDZFdmFsdWF0b3JfX3RtX18yNl8yM1Npbmds ZVBhdGNoRXZhbHVhdG9yVGFnX19TQ0ZSQ1oxWlJDWjNaUkNaMlpfdiBbOF0KICAgICAgICAg ICAgICAgIDAuMDAgICAgMC4wMCAgICA2MzIxLzY2NTIxICAgICAgIFBvb21hOjppbmNyZW1l bnROdW1JbmxpbmVFdmFsdWF0aW9ucyhsb25nKSBbMTJdCi0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAgICAwLjAwICAgIDcu NTMgICAgMzAxMC8zMDEwICAgICAgICBCZW5jaG1hcms6OnJ1bkltcGxlbWVudGF0aW9uKElt cGxlbWVudGF0aW9uICosIGludCkgWzNdCls5XSAgICAgIDIuMCAgICAwLjAwICAgIDcuNTMg ICAgMzAxMCAgICAgICAgIHJ1blNldHVwX180NUFCQ1Rlc3RCYXNlX19wc19fMTJfWjFaWENi TF8xXzBfX3RtX183XzVCcmlja0Z2X3YgWzldCiAgICAgICAgICAgICAgICA3LjUzICAgIDAu MDAgICAgMzAxMC82MzIxICAgICAgICBldmFsdWF0ZV9fdG1fXzg4XzMzQXJyYXlfX3RtX18y MF9YQ2lMXzFfMmQ5QnJpY2tWaWV3NDFBcnJheV9fdG1fXzI4X1hDaUxfMV8yZDE2Q29uc3Rh bnRGdW5jdGlvbjhPcEFzc2lnbl9fNDZFdmFsdWF0b3JfX3RtX18yNl8yM1NpbmdsZVBhdGNo RXZhbHVhdG9yVGFnX19TQ0ZSQ1oxWlJDWjNaUkNaMlpfdiBbOF0KICAgICAgICAgICAgICAg IDAuMDAgICAgMC4wMCAgICAzMDEwLzE4NjkyMSAgICAgIEVuZ2luZV9fcHNfXzE4X1haMVpa Mlo5QnJpY2tWaWV3X190bV9fMTBfWENpTF8xXzJkOjpfX2R0KHZvaWQpIFsxMV0KICAgICAg ICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAzMDEwLzE4NjkyMSAgICAgIFBvb21hOjpCcmlj a1ZpZXdCYXNlX190bV9fOV9YQ2lMXzFfMjo6X19jdCggKFBvb21hOjpCcmlja0Jhc2VfX3Rt X181X1haMVogY29uc3QgJiwgSW50ZXJ2YWxfX3RtX181X1haMVogY29uc3QgJikpIFsxNV0K ICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICA2MDIwLzEzMzA0MiAgICAgIFBvb21h OjpzY2hlZHVsZXIodm9pZCkgWzIzXQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAg IDMwMTAvMzMxMSAgICAgICAgX19jdF9fdG1fXzI3XzI0SW50ZXJ2YWxfX3RtX185X1hDaUxf MV8yX180MUFycmF5X190bV9fMjhfWENpTF8xXzJkMTZDb25zdGFudEZ1bmN0aW9uRlJDWjFf MlogWzIxM10KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAzMDEwLzY2NTIxICAg ICAgIERhdGFCbG9ja1B0cl9fdG1fXzEwX2RYQ2JMXzFfMDo6X19jdChEYXRhQmxvY2tQdHJf X3RtX184X1oxWlhaMlogY29uc3QgJiwgaW50KSBbMjEyXQogICAgICAgICAgICAgICAgMC4w MCAgICAwLjAwICAgIDMwMTAvNjY1MjEgICAgICAgUG9vbWE6OmJsb2NraW5nRXhwcmVzc2lv bnModm9pZCkgWzI0XQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgIDMwMTAvNjY1 MjEgICAgICAgUG9vbWE6OmluY3JlbWVudE51bUV4cHJlc3Npb25zKGxvbmcpIFsyNV0KICAg ICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAzMDEwLzkzMzEgICAgICAgIFBvb21hOjpi bG9ja0FuZEV2YWx1YXRlKHZvaWQpIFsyNl0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC43NSAgICAg MzAxLzMwMSAgICAgICAgIEJlbmNobWFyazo6cnVuSW1wbGVtZW50YXRpb24oSW1wbGVtZW50 YXRpb24gKiwgaW50KSBbM10KWzEwXSAgICAgMC4yICAgIDAuMDAgICAgMC43NSAgICAgMzAx ICAgICAgICAgaW5pdGlhbGl6ZV9fNDVBQkNUZXN0QmFzZV9fcHNfXzEyX1oxWlhDYkxfMV8w X190bV9fN181QnJpY2tGaV92IFsxMF0KICAgICAgICAgICAgICAgIDAuNzUgICAgMC4wMCAg ICAgMzAxLzYzMjEgICAgICAgIGV2YWx1YXRlX190bV9fODhfMzNBcnJheV9fdG1fXzIwX1hD aUxfMV8yZDlCcmlja1ZpZXc0MUFycmF5X190bV9fMjhfWENpTF8xXzJkMTZDb25zdGFudEZ1 bmN0aW9uOE9wQXNzaWduX180NkV2YWx1YXRvcl9fdG1fXzI2XzIzU2luZ2xlUGF0Y2hFdmFs dWF0b3JUYWdfX1NDRlJDWjFaUkNaM1pSQ1oyWl92IFs4XQogICAgICAgICAgICAgICAgMC4w MCAgICAwLjAwICAgICAzMDEvMTg2OTIxICAgICAgRW5naW5lX19wc19fMThfWFoxWloyWjlC cmlja1ZpZXdfX3RtX18xMF9YQ2lMXzFfMmQ6Ol9fZHQodm9pZCkgWzExXQogICAgICAgICAg ICAgICAgMC4wMCAgICAwLjAwICAgICAzMDEvMTg2OTIxICAgICAgUG9vbWE6OkJyaWNrVmll d0Jhc2VfX3RtX185X1hDaUxfMV8yOjpfX2N0KCAoUG9vbWE6OkJyaWNrQmFzZV9fdG1fXzVf WFoxWiBjb25zdCAmLCBJbnRlcnZhbF9fdG1fXzVfWFoxWiBjb25zdCAmKSkgWzE1XQogICAg ICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICA5MDMvOTAzICAgICAgICAgRW5naW5lX19w c19fMTRfWFoxWloyWjVCcmlja19fdG1fXzEwX1hDaUxfMV8yZDo6X19jdChQb29tYTo6QnJp Y2tCYXNlX190bV9fNV9YWjFaOjpEb21haW5fdCBjb25zdCAmKSBbMjIzXQogICAgICAgICAg ICAgICAgMC4wMCAgICAwLjAwICAgICA5MDMvOTAzICAgICAgICAgX19DUFIxMTlfX19fYXNf XzQ2RW5naW5lX19wc19fMTRfWFoxWloyWjVCcmlja19fdG1fXzEwX1hDaUxfMV8yZEZSQzI4 RW5naW5lX190bV9fSjIwSl9SSjU3SiBbMjIxXQogICAgICAgICAgICAgICAgMC4wMCAgICAw LjAwICAgICA5MDMvOTEyICAgICAgICAgRW5naW5lX19wc19fMTRfWFoxWloyWjVCcmlja19f dG1fXzEwX1hDaUxfMV8yZDo6X19kdCh2b2lkKSBbMjE4XQogICAgICAgICAgICAgICAgMC4w MCAgICAwLjAwICAgICA2MDIvMTMzMDQyICAgICAgUG9vbWE6OnNjaGVkdWxlcih2b2lkKSBb MjNdCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgIDMwMS8zMzExICAgICAgICBf X2N0X190bV9fMjdfMjRJbnRlcnZhbF9fdG1fXzlfWENpTF8xXzJfXzQxQXJyYXlfX3RtX18y OF9YQ2lMXzFfMmQxNkNvbnN0YW50RnVuY3Rpb25GUkNaMV8yWiBbMjEzXQogICAgICAgICAg ICAgICAgMC4wMCAgICAwLjAwICAgICAzMDEvNjY1MjEgICAgICAgRGF0YUJsb2NrUHRyX190 bV9fMTBfZFhDYkxfMV8wOjpfX2N0KERhdGFCbG9ja1B0cl9fdG1fXzhfWjFaWFoyWiBjb25z dCAmLCBpbnQpIFsyMTJdCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgIDMwMS82 NjUyMSAgICAgICBQb29tYTo6YmxvY2tpbmdFeHByZXNzaW9ucyh2b2lkKSBbMjRdCiAgICAg ICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgIDMwMS82NjUyMSAgICAgICBQb29tYTo6aW5j cmVtZW50TnVtRXhwcmVzc2lvbnMobG9uZykgWzI1XQogICAgICAgICAgICAgICAgMC4wMCAg ICAwLjAwICAgICAzMDEvOTMzMSAgICAgICAgUG9vbWE6OmJsb2NrQW5kRXZhbHVhdGUodm9p ZCkgWzI2XQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAzMDEvMTg2OTIxICAgICAgaW5p dGlhbGl6ZV9fNDVBQkNUZXN0QmFzZV9fcHNfXzEyX1oxWlhDYkxfMV8wX190bV9fN181QnJp Y2tGaV92IFsxMF0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAzMDEwLzE4Njky MSAgICAgIHJ1blNldHVwX180NUFCQ1Rlc3RCYXNlX19wc19fMTJfWjFaWENiTF8xXzBfX3Rt X183XzVCcmlja0Z2X3YgWzldCiAgICAgICAgICAgICAgICAwLjA0ICAgIDAuMDIgIDE4MzYx MC8xODY5MjEgICAgICBydW5fXzMwQUJDSW5QMl9fdG1fXzE1XzVCcmlja1hDYkxfMV8wRnZf diBbNV0KWzExXSAgICAgMC4wICAgIDAuMDQgICAgMC4wMiAgMTg2OTIxICAgICAgICAgRW5n aW5lX19wc19fMThfWFoxWloyWjlCcmlja1ZpZXdfX3RtX18xMF9YQ2lMXzFfMmQ6Ol9fZHQo dm9pZCkgWzExXQogICAgICAgICAgICAgICAgMC4wMiAgICAwLjAwICAxODY5MjEvMTg2OTIx ICAgICAgUG9vbWE6OkJyaWNrVmlld0Jhc2VfX3RtX185X1hDaUxfMV8yOjpfX2R0KCAodm9p ZCkpIFsxM10KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICA2MzIxLzY2NTIxICAgICAgIGV2 YWx1YXRlX190bV9fODhfMzNBcnJheV9fdG1fXzIwX1hDaUxfMV8yZDlCcmlja1ZpZXc0MUFy cmF5X190bV9fMjhfWENpTF8xXzJkMTZDb25zdGFudEZ1bmN0aW9uOE9wQXNzaWduX180NkV2 YWx1YXRvcl9fdG1fXzI2XzIzU2luZ2xlUGF0Y2hFdmFsdWF0b3JUYWdfX1NDRlJDWjFaUkNa M1pSQ1oyWl92IFs4XQogICAgICAgICAgICAgICAgMC4wMSAgICAwLjAwICAgMzAxMDAvNjY1 MjEgICAgICAgX19DUFIzMzNfX2V2YWx1YXRlX190bV9fMjQ3XzMzQXJyYXlfX3RtX18yMF9Y Q2lMXzFfMmQ5QnJpY2tWaWV3MTk5QXJyYXlfX3RtX18xODVfWENpTF8xXzJkMTcyRXhwcmVz c2lvblRhZ19fdG1fXzE1MF8xNDZCaW5hcnlOb2RlX190bV9fMTI3XzVPcEFkZEoxOEo4M0Jp bmFyeU5vZGVfX3RtX182NV8xME9wTXVsdGlwbHkxNVNjYWxhcl9fdG1fXzJfZEoxOEo4T3BB c3NpZ25fXzQ2RXZhbHVhdG9yX190bV9fMjZfMjNTaW5nbGVQYXRjaEV2YWx1YXRvclRhZ19f U0NGUkNaMVpSQ1ozWlJDWjJaX3YgWzddCiAgICAgICAgICAgICAgICAwLjAxICAgIDAuMDAg ICAzMDEwMC82NjUyMSAgICAgICBfX0NQUjM0MF9fZXZhbHVhdGVfX3RtX18yNTRfMzNBcnJh eV9fdG1fXzIwX1hDaUxfMV8yZDlCcmlja1ZpZXcyMDZBcnJheV9fdG1fXzE5Ml9YQ2lMXzFf MmQxNzlFeHByZXNzaW9uVGFnX190bV9fMTU3XzE1M0JpbmFyeU5vZGVfX3RtX18xMzRfMTBP cE11bHRpcGx5MTVTY2FsYXJfX3RtX18yX2QxMDFCaW5hcnlOb2RlX190bV9fODNfMTBPcFN1 YnRyYWN0SjE4SkoxOEo4T3BBc3NpZ25fXzQ2RXZhbHVhdG9yX190bV9fMjZfMjNTaW5nbGVQ YXRjaEV2YWx1YXRvclRhZ19fU0NGUkNaMVpSQ1ozWlJDWjJaX3YgWzZdClsxMl0gICAgIDAu MCAgICAwLjAyICAgIDAuMDAgICA2NjUyMSAgICAgICAgIFBvb21hOjppbmNyZW1lbnROdW1J bmxpbmVFdmFsdWF0aW9ucyhsb25nKSBbMTJdCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAgICAwLjAyICAgIDAuMDAgIDE4 NjkyMS8xODY5MjEgICAgICBFbmdpbmVfX3BzX18xOF9YWjFaWjJaOUJyaWNrVmlld19fdG1f XzEwX1hDaUxfMV8yZDo6X19kdCh2b2lkKSBbMTFdClsxM10gICAgIDAuMCAgICAwLjAyICAg IDAuMDAgIDE4NjkyMSAgICAgICAgIFBvb21hOjpCcmlja1ZpZXdCYXNlX190bV9fOV9YQ2lM XzFfMjo6X19kdCggKHZvaWQpKSBbMTNdCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAg NS8zOTQ0ICAgICAgICBCZW5jaG1hcms6OnJ1bih2b2lkKSBbMV0KICAgICAgICAgICAgICAg IDAuMDAgICAgMC4wMCAgICAgNjEwLzM5NDQgICAgICAgIEJlbmNobWFyazo6cHJpbnRSZXN1 bHRzKHZvaWQpIFsyMF0KICAgICAgICAgICAgICAgIDAuMDEgICAgMC4wMCAgICAxNTExLzM5 NDQgICAgICAgIEJlbmNobWFyazo6cnVuSW1wbGVtZW50YXRpb24oSW1wbGVtZW50YXRpb24g KiwgaW50KSBbM10KICAgICAgICAgICAgICAgIDAuMDEgICAgMC4wMCAgICAxODE4LzM5NDQg ICAgICAgIEluZm9ybTo6Zmx1c2godm9pZCkgWzE2XQpbMTRdICAgICAwLjAgICAgMC4wMiAg ICAwLjAwICAgIDM5NDQgICAgICAgICBfX0NQUjEyM19fX19sc19fdG1fXzMwX1EyXzNzdGQy MGNoYXJfdHJhaXRzX190bV9fMl9jX18zc3RkRlJRMl8zc3RkMjViYXNpY19vc3RyZWFtX190 bV9fNV9jWjFaUENjX1JRMl8zc3RkSjU3SiBbMTRdCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAg ICAgIDMwMS8xODY5MjEgICAgICBpbml0aWFsaXplX180NUFCQ1Rlc3RCYXNlX19wc19fMTJf WjFaWENiTF8xXzBfX3RtX183XzVCcmlja0ZpX3YgWzEwXQogICAgICAgICAgICAgICAgMC4w MCAgICAwLjAwICAgIDMwMTAvMTg2OTIxICAgICAgcnVuU2V0dXBfXzQ1QUJDVGVzdEJhc2Vf X3BzX18xMl9aMVpYQ2JMXzFfMF9fdG1fXzdfNUJyaWNrRnZfdiBbOV0KICAgICAgICAgICAg ICAgIDAuMDAgICAgMC4wMCAgIDYwMjAwLzE4NjkyMSAgICAgIFZpZXcwX19wc19fSjIwSl9f dG1fX0ozNkpPWjJaUTNfOTROZXdFbmdpbmVfX3RtX183N19RMl9KMjNKOjpfX0NQUjUxN19f bWFrZV9fMjY2VmlldzBfX3BzX18yN18yNEFycmF5X190bV9fMTFfWFoxWloyWlozWl9fdG1f XzIxN19YQ2lMXzFfMmQyMDRFeHByZXNzaW9uVGFnX190bV9fMTgyXzE3OEJpbmFyeU5vZGVf X3RtX18xNTlfNU9wQWRkNDlSZWZlcmVuY2VfX3RtX18zMl8yOUFycmF5X190bV9fMTZfWENp TF8xXzJkNUJyaWNrOTlCaW5hcnlOb2RlX190bV9fODFfMTBPcE11bHRpcGx5MTVTY2FsYXJf X3RtX18yX2RKMTIzSlNGUkNKMjNKXzIwOEFycmF5X190bV9fMTk0X1hPY3NpMTY5bmV3RGlt KEVuZ2luZV90LCBfX2NvbXBsZXggSjhEb21haW5fdDZUeXBlX3Q1VGFnX3Q6OikgWzE4XQog ICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgNjAyMDAvMTg2OTIxICAgICAgVmlldzBf X3BzX19KMjBKX190bV9fSjM2Sk9aMlpRM185NE5ld0VuZ2luZV9fdG1fXzc3X1EyX0oyM0o6 Ol9fQ1BSNTI1X19tYWtlX18yNzRWaWV3MF9fcHNfXzI3XzI0QXJyYXlfX3RtX18xMV9YWjFa WjJaWjNaX190bV9fMjI1X1hDaUxfMV8yZDIxMkV4cHJlc3Npb25UYWdfX3RtX18xOTBfMTg2 QmluYXJ5Tm9kZV9fdG1fXzE2N18xME9wTXVsdGlwbHkxNVNjYWxhcl9fdG1fXzJfZDEzNEJp bmFyeU5vZGVfX3RtX18xMTVfMTBPcFN1YnRyYWN0NDlSZWZlcmVuY2VfX3RtX18zMl8yOUFy cmF5X190bV9fMTZfWENpTF8xXzJkNUJyaWNrSjE4MUpTRlJDSjIzSl8yMDhBcnJheV9fdG1f XzE5NF9YT2NzaTE2OW5ld0RpbShFbmdpbmVfdCwgX19jb21wbGV4IEo4RG9tYWluX3Q2VHlw ZV90NVRhZ190OjopIFsxOV0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgIDYzMjEw LzE4NjkyMSAgICAgIHJ1bl9fMzBBQkNJblAyX190bV9fMTVfNUJyaWNrWENiTF8xXzBGdl92 IFs1XQpbMTVdICAgICAwLjAgICAgMC4wMSAgICAwLjAwICAxODY5MjEgICAgICAgICBQb29t YTo6QnJpY2tWaWV3QmFzZV9fdG1fXzlfWENpTF8xXzI6Ol9fY3QoIChQb29tYTo6QnJpY2tC YXNlX190bV9fNV9YWjFaIGNvbnN0ICYsIEludGVydmFsX190bV9fNV9YWjFaIGNvbnN0ICYp KSBbMTVdCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t CiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgMS82MDUgICAgICAgICBzdGQ6 OmZsdXNoKEluZm9ybSAmKSBbMjFdCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDEgICAg IDYwNC82MDUgICAgICAgICBzdGQ6OmVuZGwoSW5mb3JtICYpIFsxN10KWzE2XSAgICAgMC4w ICAgIDAuMDAgICAgMC4wMSAgICAgNjA1ICAgICAgICAgSW5mb3JtOjpmbHVzaCh2b2lkKSBb MTZdCiAgICAgICAgICAgICAgICAwLjAxICAgIDAuMDAgICAgMTgxOC8zOTQ0ICAgICAgICBf X0NQUjEyM19fX19sc19fdG1fXzMwX1EyXzNzdGQyMGNoYXJfdHJhaXRzX190bV9fMl9jX18z c3RkRlJRMl8zc3RkMjViYXNpY19vc3RyZWFtX190bV9fNV9jWjFaUENjX1JRMl8zc3RkSjU3 SiBbMTRdCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgMTIxMC8xMjU4ICAgICAg ICBzdGQ6OmJhc2ljX3N0cmluZ19fdG1fXzU4X2NRMl8zc3RkMjBjaGFyX3RyYWl0c19fdG1f XzJfY1EyXzNzdGQxOGFsbG9jYXRvcl9fdG1fXzJfYzo6X19kdCggKHZvaWQpKSBbMjE0XQog ICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICA5MDkvOTA5ICAgICAgICAgc3RkOjpi YXNpY19vc3RyZWFtX190bV9fMzFfY1EyXzNzdGQyMGNoYXJfdHJhaXRzX190bV9fMl9jOjpm bHVzaChzdGQ6OmJhc2ljX29zdHJlYW1fX3RtX183X1oxWloyWiAmKHZvaWQpKSA8Y3ljbGUg MT4gWzI3XQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAgIDEvNjA0ICAgICAgICAgQmVu Y2htYXJrOjpydW4odm9pZCkgWzFdCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDEgICAg IDYwMy82MDQgICAgICAgICBCZW5jaG1hcms6OnJ1bkltcGxlbWVudGF0aW9uKEltcGxlbWVu dGF0aW9uICosIGludCkgWzNdClsxN10gICAgIDAuMCAgICAwLjAwICAgIDAuMDEgICAgIDYw NCAgICAgICAgIHN0ZDo6ZW5kbChJbmZvcm0gJikgWzE3XQogICAgICAgICAgICAgICAgMC4w MCAgICAwLjAxICAgICA2MDQvNjA1ICAgICAgICAgSW5mb3JtOjpmbHVzaCh2b2lkKSBbMTZd Ci0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAg ICAgICAgICAgICAwLjAwICAgIDAuMDAgICAzMDEwMC8zMDEwMCAgICAgICBydW5fXzMwQUJD SW5QMl9fdG1fXzE1XzVCcmlja1hDYkxfMV8wRnZfdiBbNV0KWzE4XSAgICAgMC4wICAgIDAu MDAgICAgMC4wMCAgIDMwMTAwICAgICAgICAgVmlldzBfX3BzX19KMjBKX190bV9fSjM2Sk9a MlpRM185NE5ld0VuZ2luZV9fdG1fXzc3X1EyX0oyM0o6Ol9fQ1BSNTE3X19tYWtlX18yNjZW aWV3MF9fcHNfXzI3XzI0QXJyYXlfX3RtX18xMV9YWjFaWjJaWjNaX190bV9fMjE3X1hDaUxf MV8yZDIwNEV4cHJlc3Npb25UYWdfX3RtX18xODJfMTc4QmluYXJ5Tm9kZV9fdG1fXzE1OV81 T3BBZGQ0OVJlZmVyZW5jZV9fdG1fXzMyXzI5QXJyYXlfX3RtX18xNl9YQ2lMXzFfMmQ1QnJp Y2s5OUJpbmFyeU5vZGVfX3RtX184MV8xME9wTXVsdGlwbHkxNVNjYWxhcl9fdG1fXzJfZEox MjNKU0ZSQ0oyM0pfMjA4QXJyYXlfX3RtX18xOTRfWE9jc2kxNjluZXdEaW0oRW5naW5lX3Qs IF9fY29tcGxleCBKOERvbWFpbl90NlR5cGVfdDVUYWdfdDo6KSBbMThdCiAgICAgICAgICAg ICAgICAwLjAwICAgIDAuMDAgICA2MDIwMC8xODY5MjEgICAgICBQb29tYTo6QnJpY2tWaWV3 QmFzZV9fdG1fXzlfWENpTF8xXzI6Ol9fY3QoIChQb29tYTo6QnJpY2tCYXNlX190bV9fNV9Y WjFaIGNvbnN0ICYsIEludGVydmFsX190bV9fNV9YWjFaIGNvbnN0ICYpKSBbMTVdCi0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAg ICAgICAwLjAwICAgIDAuMDAgICAzMDEwMC8zMDEwMCAgICAgICBydW5fXzMwQUJDSW5QMl9f dG1fXzE1XzVCcmlja1hDYkxfMV8wRnZfdiBbNV0KWzE5XSAgICAgMC4wICAgIDAuMDAgICAg MC4wMCAgIDMwMTAwICAgICAgICAgVmlldzBfX3BzX19KMjBKX190bV9fSjM2Sk9aMlpRM185 NE5ld0VuZ2luZV9fdG1fXzc3X1EyX0oyM0o6Ol9fQ1BSNTI1X19tYWtlX18yNzRWaWV3MF9f cHNfXzI3XzI0QXJyYXlfX3RtX18xMV9YWjFaWjJaWjNaX190bV9fMjI1X1hDaUxfMV8yZDIx MkV4cHJlc3Npb25UYWdfX3RtX18xOTBfMTg2QmluYXJ5Tm9kZV9fdG1fXzE2N18xME9wTXVs dGlwbHkxNVNjYWxhcl9fdG1fXzJfZDEzNEJpbmFyeU5vZGVfX3RtX18xMTVfMTBPcFN1YnRy YWN0NDlSZWZlcmVuY2VfX3RtX18zMl8yOUFycmF5X190bV9fMTZfWENpTF8xXzJkNUJyaWNr SjE4MUpTRlJDSjIzSl8yMDhBcnJheV9fdG1fXzE5NF9YT2NzaTE2OW5ld0RpbShFbmdpbmVf dCwgX19jb21wbGV4IEo4RG9tYWluX3Q2VHlwZV90NVRhZ190OjopIFsxOV0KICAgICAgICAg ICAgICAgIDAuMDAgICAgMC4wMCAgIDYwMjAwLzE4NjkyMSAgICAgIFBvb21hOjpCcmlja1Zp ZXdCYXNlX190bV9fOV9YQ2lMXzFfMjo6X19jdCggKFBvb21hOjpCcmlja0Jhc2VfX3RtX181 X1haMVogY29uc3QgJiwgSW50ZXJ2YWxfX3RtX181X1haMVogY29uc3QgJikpIFsxNV0KLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAg ICAgICAgIDAuMDAgICAgMC4wMCAgICAgICAxLzEgICAgICAgICAgIEJlbmNobWFyazo6cnVu KHZvaWQpIFsxXQpbMjBdICAgICAwLjAgICAgMC4wMCAgICAwLjAwICAgICAgIDEgICAgICAg ICBCZW5jaG1hcms6OnByaW50UmVzdWx0cyh2b2lkKSBbMjBdCiAgICAgICAgICAgICAgICAw LjAwICAgIDAuMDAgICAgIDYxMC8zOTQ0ICAgICAgICBfX0NQUjEyM19fX19sc19fdG1fXzMw X1EyXzNzdGQyMGNoYXJfdHJhaXRzX190bV9fMl9jX18zc3RkRlJRMl8zc3RkMjViYXNpY19v c3RyZWFtX190bV9fNV9jWjFaUENjX1JRMl8zc3RkSjU3SiBbMTRdCiAgICAgICAgICAgICAg ICAwLjAwICAgIDAuMDAgICAgICAgMS8xICAgICAgICAgICBzdGQ6OmZsdXNoKEluZm9ybSAm KSBbMjFdCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgIDMwMS8zMDIgICAgICAg ICBfaW5pdGlhbGl6ZV9zdG9yYWdlX19RMl8zc3RkNDN2ZWN0b3JfX3RtX18yOV9kUTJfM3N0 ZDE4YWxsb2NhdG9yX190bV9fMl9kRlEyX1oyWjlzaXplX3R5cGVSQ1oxWl92IFsyMjZdCiAg ICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgIDMwMS8zMDEgICAgICAgICBzdGQ6Omxl ZnQoc3RkOjppb3NfYmFzZSAmKSBbMzBdCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAg ICAgIDMwMS85MDQgICAgICAgICBzdGQ6OmJhc2ljX29zdHJlYW1fX3RtX18zMV9jUTJfM3N0 ZDIwY2hhcl90cmFpdHNfX3RtX18yX2M6Om9wZXJhdG9yPDwoc3RkOjpiYXNpY19vc3RyZWFt X190bV9fN19aMVpaMlogJihsb25nKSkgWzIxOV0KICAgICAgICAgICAgICAgIDAuMDAgICAg MC4wMCAgICAgMzAxLzMwMSAgICAgICAgIHN0ZDo6cmlnaHQoc3RkOjppb3NfYmFzZSAmKSBb MzNdCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgIDMwMS8zMDEgICAgICAgICBz dGQ6OmZpeGVkKHN0ZDo6aW9zX2Jhc2UgJikgWzI4XQogICAgICAgICAgICAgICAgMC4wMCAg ICAwLjAwICAgICAzMDEvMzAzICAgICAgICAgc3RkOjp2ZWN0b3JfX3RtX18yOV9kUTJfM3N0 ZDE4YWxsb2NhdG9yX190bV9fMl9kOjpfX2R0KCAodm9pZCkpIFsyMjVdCiAgICAgICAgICAg ICAgICAwLjAwICAgIDAuMDAgICAgICAgNy8xMjU4ICAgICAgICBzdGQ6OmJhc2ljX3N0cmlu Z19fdG1fXzU4X2NRMl8zc3RkMjBjaGFyX3RyYWl0c19fdG1fXzJfY1EyXzNzdGQxOGFsbG9j YXRvcl9fdG1fXzJfYzo6X19kdCggKHZvaWQpKSBbMjE0XQogICAgICAgICAgICAgICAgMC4w MCAgICAwLjAwICAgICAgIDIvNCAgICAgICAgICAgQUJDSW5QMl9fdG1fXzE1XzVCcmlja1hD YkxfMV8wOjpxdWFsaWZpY2F0aW9uKGNoYXIgY29uc3QgKmNvbnN0KHZvaWQpKSBbNDFdCiAg ICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgMi8yNyAgICAgICAgICBfX2N0X19R Ml8zc3RkNzhiYXNpY19zdHJpbmdfX3RtX181OF9jUTJfM3N0ZDIwY2hhcl90cmFpdHNfX3Rt X18yX2NRMl8zc3RkMThhbGxvY2F0b3JfX3RtX18yX2NGUENaMVpSQ1ozWiBbMjI3XQogICAg ICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAgIDEvMiAgICAgICAgICAgQUJDSW5QMl9f dG1fXzE1XzVCcmlja1hDYkxfMV8wOjp0eXBlKGNoYXIgY29uc3QgKmNvbnN0KHZvaWQpKSBb NDldCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAg ICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgMS8xICAgICAgICAgICBCZW5jaG1h cms6OnByaW50UmVzdWx0cyh2b2lkKSBbMjBdClsyMV0gICAgIDAuMCAgICAwLjAwICAgIDAu MDAgICAgICAgMSAgICAgICAgIHN0ZDo6Zmx1c2goSW5mb3JtICYpIFsyMV0KICAgICAgICAg ICAgICAgIDAuMDAgICAgMC4wMCAgICAgICAxLzYwNSAgICAgICAgIEluZm9ybTo6Zmx1c2go dm9pZCkgWzE2XQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLQpbMjJdICAgICAwLjAgICAgMC4wMCAgICAwLjAwICAgICA5MDkrOTE2ICAgICA8Y3lj bGUgMSBhcyBhIHdob2xlPiBbMjJdCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAg IDkxMSAgICAgICAgICAgICBzdGQ6OmJhc2ljX29zdHJlYW1fX3RtX18zMV9jUTJfM3N0ZDIw Y2hhcl90cmFpdHNfX3RtX18yX2M6OmZsdXNoKHN0ZDo6YmFzaWNfb3N0cmVhbV9fdG1fXzdf WjFaWjJaICYodm9pZCkpIDxjeWNsZSAxPiBbMjddCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAg ICAgIDYwMi8xMzMwNDIgICAgICBpbml0aWFsaXplX180NUFCQ1Rlc3RCYXNlX19wc19fMTJf WjFaWENiTF8xXzBfX3RtX183XzVCcmlja0ZpX3YgWzEwXQogICAgICAgICAgICAgICAgMC4w MCAgICAwLjAwICAgIDYwMjAvMTMzMDQyICAgICAgcnVuU2V0dXBfXzQ1QUJDVGVzdEJhc2Vf X3BzX18xMl9aMVpYQ2JMXzFfMF9fdG1fXzdfNUJyaWNrRnZfdiBbOV0KICAgICAgICAgICAg ICAgIDAuMDAgICAgMC4wMCAgMTI2NDIwLzEzMzA0MiAgICAgIHJ1bl9fMzBBQkNJblAyX190 bV9fMTVfNUJyaWNrWENiTF8xXzBGdl92IFs1XQpbMjNdICAgICAwLjAgICAgMC4wMCAgICAw LjAwICAxMzMwNDIgICAgICAgICBQb29tYTo6c2NoZWR1bGVyKHZvaWQpIFsyM10KLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAgICAg ICAgIDAuMDAgICAgMC4wMCAgICAgMzAxLzY2NTIxICAgICAgIGluaXRpYWxpemVfXzQ1QUJD VGVzdEJhc2VfX3BzX18xMl9aMVpYQ2JMXzFfMF9fdG1fXzdfNUJyaWNrRmlfdiBbMTBdCiAg ICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgMzAxMC82NjUyMSAgICAgICBydW5TZXR1 cF9fNDVBQkNUZXN0QmFzZV9fcHNfXzEyX1oxWlhDYkxfMV8wX190bV9fN181QnJpY2tGdl92 IFs5XQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgNjMyMTAvNjY1MjEgICAgICAg cnVuX18zMEFCQ0luUDJfX3RtX18xNV81QnJpY2tYQ2JMXzFfMEZ2X3YgWzVdClsyNF0gICAg IDAuMCAgICAwLjAwICAgIDAuMDAgICA2NjUyMSAgICAgICAgIFBvb21hOjpibG9ja2luZ0V4 cHJlc3Npb25zKHZvaWQpIFsyNF0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgMzAxLzY2 NTIxICAgICAgIGluaXRpYWxpemVfXzQ1QUJDVGVzdEJhc2VfX3BzX18xMl9aMVpYQ2JMXzFf MF9fdG1fXzdfNUJyaWNrRmlfdiBbMTBdCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAg ICAgMzAxMC82NjUyMSAgICAgICBydW5TZXR1cF9fNDVBQkNUZXN0QmFzZV9fcHNfXzEyX1ox WlhDYkxfMV8wX190bV9fN181QnJpY2tGdl92IFs5XQogICAgICAgICAgICAgICAgMC4wMCAg ICAwLjAwICAgNjMyMTAvNjY1MjEgICAgICAgcnVuX18zMEFCQ0luUDJfX3RtX18xNV81QnJp Y2tYQ2JMXzFfMEZ2X3YgWzVdClsyNV0gICAgIDAuMCAgICAwLjAwICAgIDAuMDAgICA2NjUy MSAgICAgICAgIFBvb21hOjppbmNyZW1lbnROdW1FeHByZXNzaW9ucyhsb25nKSBbMjVdCi0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAg ICAgICAgICAwLjAwICAgIDAuMDAgICAgIDMwMS85MzMxICAgICAgICBpbml0aWFsaXplX180 NUFCQ1Rlc3RCYXNlX19wc19fMTJfWjFaWENiTF8xXzBfX3RtX183XzVCcmlja0ZpX3YgWzEw XQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgIDMwMTAvOTMzMSAgICAgICAgcnVu U2V0dXBfXzQ1QUJDVGVzdEJhc2VfX3BzX18xMl9aMVpYQ2JMXzFfMF9fdG1fXzdfNUJyaWNr RnZfdiBbOV0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICA2MDIwLzkzMzEgICAg ICAgIHJ1bl9fMzBBQkNJblAyX190bV9fMTVfNUJyaWNrWENiTF8xXzBGdl92IFs1XQpbMjZd ICAgICAwLjAgICAgMC4wMCAgICAwLjAwICAgIDkzMzEgICAgICAgICBQb29tYTo6YmxvY2tB bmRFdmFsdWF0ZSh2b2lkKSBbMjZdCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMiAg ICAgICAgICAgICBzdGQ6OmJhc2ljX29zdHJlYW1fX3RtX18zMV9jUTJfM3N0ZDIwY2hhcl90 cmFpdHNfX3RtX18yX2M6OnNlbnRyeTo6X19jdCggKHN0ZDo6YmFzaWNfb3N0cmVhbV9fdG1f XzdfWjFaWjJaICYpKSA8Y3ljbGUgMT4gWzIxNl0KICAgICAgICAgICAgICAgIDAuMDAgICAg MC4wMCAgICAgOTA5LzkwOSAgICAgICAgIEluZm9ybTo6Zmx1c2godm9pZCkgWzE2XQpbMjdd ICAgICAwLjAgICAgMC4wMCAgICAwLjAwICAgICA5MTEgICAgICAgICBzdGQ6OmJhc2ljX29z dHJlYW1fX3RtX18zMV9jUTJfM3N0ZDIwY2hhcl90cmFpdHNfX3RtX18yX2M6OmZsdXNoKHN0 ZDo6YmFzaWNfb3N0cmVhbV9fdG1fXzdfWjFaWjJaICYodm9pZCkpIDxjeWNsZSAxPiBbMjdd CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDkxNCAgICAgICAgICAgICBzdGQ6 OmJhc2ljX29zdHJlYW1fX3RtX18zMV9jUTJfM3N0ZDIwY2hhcl90cmFpdHNfX3RtX18yX2M6 OnNlbnRyeTo6X19jdCggKHN0ZDo6YmFzaWNfb3N0cmVhbV9fdG1fXzdfWjFaWjJaICYpKSA8 Y3ljbGUgMT4gWzIxNl0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgMzAxLzMwMSAgICAg ICAgIEJlbmNobWFyazo6cHJpbnRSZXN1bHRzKHZvaWQpIFsyMF0KWzI4XSAgICAgMC4wICAg IDAuMDAgICAgMC4wMCAgICAgMzAxICAgICAgICAgc3RkOjpmaXhlZChzdGQ6Omlvc19iYXNl ICYpIFsyOF0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgMzAxLzMwMSAgICAgICAgIEJl bmNobWFyazo6cnVuSW1wbGVtZW50YXRpb24oSW1wbGVtZW50YXRpb24gKiwgaW50KSBbM10K WzI5XSAgICAgMC4wICAgIDAuMDAgICAgMC4wMCAgICAgMzAxICAgICAgICAgSW1wbGVtZW50 YXRpb246OmludGVybmFsQ2xvY2tDYWxscyggY29uc3Qodm9pZCkpIFsyOV0KLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAgICAgICAg IDAuMDAgICAgMC4wMCAgICAgMzAxLzMwMSAgICAgICAgIEJlbmNobWFyazo6cHJpbnRSZXN1 bHRzKHZvaWQpIFsyMF0KWzMwXSAgICAgMC4wICAgIDAuMDAgICAgMC4wMCAgICAgMzAxICAg ICAgICAgc3RkOjpsZWZ0KHN0ZDo6aW9zX2Jhc2UgJikgWzMwXQotLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgICAgICAgICAgMC4wMCAg ICAwLjAwICAgICAzMDEvMzAxICAgICAgICAgQmVuY2htYXJrOjpydW5JbXBsZW1lbnRhdGlv bihJbXBsZW1lbnRhdGlvbiAqLCBpbnQpIFszXQpbMzFdICAgICAwLjAgICAgMC4wMCAgICAw LjAwICAgICAzMDEgICAgICAgICBBQkNUZXN0QmFzZV9fcHNfXzEyX1oxWlhDYkxfMV8wX190 bV9fN181QnJpY2s6Om9wQ291bnQoZG91YmxlIGNvbnN0KHZvaWQpKSBbMzFdCi0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAg ICAwLjAwICAgIDAuMDAgICAgIDMwMS8zMDEgICAgICAgICBCZW5jaG1hcms6OnJ1bkltcGxl bWVudGF0aW9uKEltcGxlbWVudGF0aW9uICosIGludCkgWzNdClszMl0gICAgIDAuMCAgICAw LjAwICAgIDAuMDAgICAgIDMwMSAgICAgICAgIEFCQ1Rlc3RCYXNlX19wc19fMTJfWjFaWENi TF8xXzBfX3RtX183XzVCcmljazo6cmVzdWx0Q2hlY2soZG91YmxlIGNvbnN0KHZvaWQpKSBb MzJdCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAg ICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgIDMwMS8zMDEgICAgICAgICBCZW5jaG1h cms6OnByaW50UmVzdWx0cyh2b2lkKSBbMjBdClszM10gICAgIDAuMCAgICAwLjAwICAgIDAu MDAgICAgIDMwMSAgICAgICAgIHN0ZDo6cmlnaHQoc3RkOjppb3NfYmFzZSAmKSBbMzNdCi0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAg ICAgICAgICAwLjAwICAgIDAuMDAgICAgICAxMi8xMiAgICAgICAgICByZXNpemVfX1EyXzVf X2thaTM5bHdfdmVjdG9yX190bV9fMjJfUFEzXzNzdGQ2bG9jYWxlNWZhY2V0RlVpUkNaMVpf diBbMTcxXQpbMzRdICAgICAwLjAgICAgMC4wMCAgICAwLjAwICAgICAgMTIgICAgICAgICBf X2thaTo6bHdfdmVjdG9yX190bV9fMjJfUFEzXzNzdGQ2bG9jYWxlNWZhY2V0Ojphc3NpZ24o dm9pZCAoX19rYWk6Omx3X3ZlY3Rvcl9fdG1fXzRfWjFaIGNvbnN0ICYsIHVuc2lnbmVkIGlu dCkpIFszNF0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICAyLzggICAgICAgICAgIFBv b21hOjppbmZvTWVzc2FnZXMoYm9vbCkgWzQ1XQogICAgICAgICAgICAgICAgMC4wMCAgICAw LjAwICAgICAgIDIvOCAgICAgICAgICAgUG9vbWE6Ondhcm5NZXNzYWdlcyhib29sKSBbNTBd CiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgMi84ICAgICAgICAgICBQb29t YTo6ZXJyb3JNZXNzYWdlcyhib29sKSBbNDRdCiAgICAgICAgICAgICAgICAwLjAwICAgIDAu MDAgICAgICAgMi84ICAgICAgICAgICBQb29tYTo6ZGVidWdMZXZlbChpbnQpIFs0M10KWzM1 XSAgICAgMC4wICAgIDAuMDAgICAgMC4wMCAgICAgICA4ICAgICAgICAgSW5mb3JtOjpzZXRP dXRwdXRMZXZlbChpbnQpIFszNV0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICA2LzYg ICAgICAgICAgIG1haW4gWzJdClszNl0gICAgIDAuMCAgICAwLjAwICAgIDAuMDAgICAgICAg NiAgICAgICAgIEJlbmNobWFyazo6YWRkSW1wbGVtZW50YXRpb24oSW1wbGVtZW50YXRpb24g KikgWzM2XQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAgIDIvMyAgICAgICAg ICAgX19DUFIxMTlfX2luc2VydF9hdXhfX1EyXzNzdGQ3NnZlY3Rvcl9fdG1fXzYyX1AxNElt cGxlbWVudGF0aW9uUTJfM3N0ZDM1YWxsb2NhdG9yX190bV9fMThfUEozN0pGUTJfWjJaN3Bv aW50ZXJSQ1oxWl92IFsyMzJdCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgNS81ICAg ICAgICAgICBJbmZvcm06OnNldHVwKGNoYXIgY29uc3QgKikgWzM4XQpbMzddICAgICAwLjAg ICAgMC4wMCAgICAwLjAwICAgICAgIDUgICAgICAgICBJbmZvcm06OnNldFByZWZpeChjaGFy IGNvbnN0ICopIFszN10KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICAyLzUgICAgICAg ICAgIEluZm9ybTo6X19jdChjaGFyIGNvbnN0ICosIGludCkgWzIzOF0KICAgICAgICAgICAg ICAgIDAuMDAgICAgMC4wMCAgICAgICAzLzUgICAgICAgICAgIEluZm9ybTo6X19jdChjaGFy IGNvbnN0ICosIHN0ZDo6YmFzaWNfb3N0cmVhbV9fdG1fXzMxX2NRMl8zc3RkMjBjaGFyX3Ry YWl0c19fdG1fXzJfYyAmLCBpbnQpIFsyMzRdClszOF0gICAgIDAuMCAgICAwLjAwICAgIDAu MDAgICAgICAgNSAgICAgICAgIEluZm9ybTo6c2V0dXAoY2hhciBjb25zdCAqKSBbMzhdCiAg ICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgNS81ICAgICAgICAgICBJbmZvcm06 OnNldFByZWZpeChjaGFyIGNvbnN0ICopIFszN10KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAg ICAgICA0LzQgICAgICAgICAgIEluZm9ybTo6X19kdCh2b2lkKSBbMzg3XQpbMzldICAgICAw LjAgICAgMC4wMCAgICAwLjAwICAgICAgIDQgICAgICAgICBJbmZvcm06OmNsb3NlKHZvaWQp IFszOV0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0K ICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICA0LzQgICAgICAgICAgIEJlbmNo bWFyazo6X19jdChpbnQsIGNoYXIgKiosIGNoYXIgY29uc3QgKiwgaW50KSBbMjQ4XQpbNDBd ICAgICAwLjAgICAgMC4wMCAgICAwLjAwICAgICAgIDQgICAgICAgICBQb29tYTo6aW50QXJn dW1lbnQoaW50LCBjaGFyICoqLCBpbnQsIGludCAmKSBbNDBdCi0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAgICAwLjAwICAg IDAuMDAgICAgICAgMi80ICAgICAgICAgICBCZW5jaG1hcms6OnByaW50UmVzdWx0cyh2b2lk KSBbMjBdCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgMi80ICAgICAgICAg ICBCZW5jaG1hcms6OnJ1bkltcGxlbWVudGF0aW9uKEltcGxlbWVudGF0aW9uICosIGludCkg WzNdCls0MV0gICAgIDAuMCAgICAwLjAwICAgIDAuMDAgICAgICAgNCAgICAgICAgIEFCQ0lu UDJfX3RtX18xNV81QnJpY2tYQ2JMXzFfMDo6cXVhbGlmaWNhdGlvbihjaGFyIGNvbnN0ICpj b25zdCh2b2lkKSkgWzQxXQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAgIDMvMyAgICAg ICAgICAgSW5mb3JtOjpfX2N0KGNoYXIgY29uc3QgKiwgc3RkOjpiYXNpY19vc3RyZWFtX190 bV9fMzFfY1EyXzNzdGQyMGNoYXJfdHJhaXRzX190bV9fMl9jICYsIGludCkgWzIzNF0KWzQy XSAgICAgMC4wICAgIDAuMDAgICAgMC4wMCAgICAgICAzICAgICAgICAgSW5mb3JtOjpvcGVu KHN0ZDo6YmFzaWNfb3N0cmVhbV9fdG1fXzMxX2NRMl8zc3RkMjBjaGFyX3RyYWl0c19fdG1f XzJfYyAmLCBpbnQpIFs0Ml0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICAz LzUgICAgICAgICAgIF9fbW9kaWZ5X19RMl81X19rYWk0OXJiX3RyZWVfX3RtX18zNF9pUTJf M3N0ZDEzbGVzc19fdG1fXzJfaVhDVWlMXzJfMTZGUkNaMVpQYlEzXzVfX2thaTEycmJfdHJl ZV9iYXNlMTFtb2RpZnlfbW9kZV9QUTJfNV9fa2FpMTdyYl90cmVlX25vZGVfYmFzZSBbMjMx XQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAg ICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAgIDEvMiAgICAgICAgICAgUG9vbWE6Ol9f TlBvb21hX2NtcGxfY3BwX2YwMDk0NTBkOjpjbGVhbnVwX3MoICh2b2lkKSkgWzUxXQogICAg ICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAgIDEvMiAgICAgICAgICAgUG9vbWE6Omlu aXRpYWxpemUoUG9vbWE6Ok9wdGlvbnMgJiwgYm9vbCwgYm9vbCkgWzU1XQpbNDNdICAgICAw LjAgICAgMC4wMCAgICAwLjAwICAgICAgIDIgICAgICAgICBQb29tYTo6ZGVidWdMZXZlbChp bnQpIFs0M10KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICAyLzggICAgICAg ICAgIEluZm9ybTo6c2V0T3V0cHV0TGV2ZWwoaW50KSBbMzVdCi0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAgICAwLjAwICAg IDAuMDAgICAgICAgMS8yICAgICAgICAgICBQb29tYTo6X19OUG9vbWFfY21wbF9jcHBfZjAw OTQ1MGQ6OmNsZWFudXBfcyggKHZvaWQpKSBbNTFdCiAgICAgICAgICAgICAgICAwLjAwICAg IDAuMDAgICAgICAgMS8yICAgICAgICAgICBQb29tYTo6aW5pdGlhbGl6ZShQb29tYTo6T3B0 aW9ucyAmLCBib29sLCBib29sKSBbNTVdCls0NF0gICAgIDAuMCAgICAwLjAwICAgIDAuMDAg ICAgICAgMiAgICAgICAgIFBvb21hOjplcnJvck1lc3NhZ2VzKGJvb2wpIFs0NF0KICAgICAg ICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICAyLzggICAgICAgICAgIEluZm9ybTo6c2V0 T3V0cHV0TGV2ZWwoaW50KSBbMzVdCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgMS8y ICAgICAgICAgICBQb29tYTo6X19OUG9vbWFfY21wbF9jcHBfZjAwOTQ1MGQ6OmNsZWFudXBf cyggKHZvaWQpKSBbNTFdCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgMS8y ICAgICAgICAgICBQb29tYTo6aW5pdGlhbGl6ZShQb29tYTo6T3B0aW9ucyAmLCBib29sLCBi b29sKSBbNTVdCls0NV0gICAgIDAuMCAgICAwLjAwICAgIDAuMDAgICAgICAgMiAgICAgICAg IFBvb21hOjppbmZvTWVzc2FnZXMoYm9vbCkgWzQ1XQogICAgICAgICAgICAgICAgMC4wMCAg ICAwLjAwICAgICAgIDIvOCAgICAgICAgICAgSW5mb3JtOjpzZXRPdXRwdXRMZXZlbChpbnQp IFszNV0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0K ICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICAxLzIgICAgICAgICAgIFBvb21h OjpfX05Qb29tYV9jbXBsX2NwcF9mMDA5NDUwZDo6Y2xlYW51cF9zKCAodm9pZCkpIFs1MV0K ICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICAxLzIgICAgICAgICAgIFBvb21h Ojppbml0aWFsaXplKFBvb21hOjpPcHRpb25zICYsIGJvb2wsIGJvb2wpIFs1NV0KWzQ2XSAg ICAgMC4wICAgIDAuMDAgICAgMC4wMCAgICAgICAyICAgICAgICAgUG9vbWE6OmxvZ01lc3Nh Z2VzKGNoYXIgY29uc3QgKikgWzQ2XQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAgIDIv MiAgICAgICAgICAgSW5mb3JtOjpfX2N0KGNoYXIgY29uc3QgKiwgaW50KSBbMjM4XQpbNDdd ICAgICAwLjAgICAgMC4wMCAgICAwLjAwICAgICAgIDIgICAgICAgICBJbmZvcm06Om9wZW4o aW50KSBbNDddCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgMi81ICAgICAg ICAgICBfX21vZGlmeV9fUTJfNV9fa2FpNDlyYl90cmVlX190bV9fMzRfaVEyXzNzdGQxM2xl c3NfX3RtX18yX2lYQ1VpTF8yXzE2RlJDWjFaUGJRM181X19rYWkxMnJiX3RyZWVfYmFzZTEx bW9kaWZ5X21vZGVfUFEyXzVfX2thaTE3cmJfdHJlZV9ub2RlX2Jhc2UgWzIzMV0KLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAgICAg ICAgIDAuMDAgICAgMC4wMCAgICAgICAxLzIgICAgICAgICAgIFBvb21hOjpPcHRpb25zOjpf X2N0KCAodm9pZCkpIFsyNTJdCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAg MS8yICAgICAgICAgICBQb29tYTo6T3B0aW9uczo6X19jdCggKGludCAmLCBjaGFyICoqKSkg WzI1MV0KWzQ4XSAgICAgMC4wICAgIDAuMDAgICAgMC4wMCAgICAgICAyICAgICAgICAgUG9v bWE6Ok9wdGlvbnM6OnJlc2V0KCAodm9pZCkpIFs0OF0KLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4w MCAgICAgICAxLzIgICAgICAgICAgIEJlbmNobWFyazo6cHJpbnRSZXN1bHRzKHZvaWQpIFsy MF0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICAxLzIgICAgICAgICAgIEJl bmNobWFyazo6cnVuSW1wbGVtZW50YXRpb24oSW1wbGVtZW50YXRpb24gKiwgaW50KSBbM10K WzQ5XSAgICAgMC4wICAgIDAuMDAgICAgMC4wMCAgICAgICAyICAgICAgICAgQUJDSW5QMl9f dG1fXzE1XzVCcmlja1hDYkxfMV8wOjp0eXBlKGNoYXIgY29uc3QgKmNvbnN0KHZvaWQpKSBb NDldCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAg ICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgMS8yICAgICAgICAgICBQb29tYTo6 X19OUG9vbWFfY21wbF9jcHBfZjAwOTQ1MGQ6OmNsZWFudXBfcyggKHZvaWQpKSBbNTFdCiAg ICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgMS8yICAgICAgICAgICBQb29tYTo6 aW5pdGlhbGl6ZShQb29tYTo6T3B0aW9ucyAmLCBib29sLCBib29sKSBbNTVdCls1MF0gICAg IDAuMCAgICAwLjAwICAgIDAuMDAgICAgICAgMiAgICAgICAgIFBvb21hOjp3YXJuTWVzc2Fn ZXMoYm9vbCkgWzUwXQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAgIDIvOCAg ICAgICAgICAgSW5mb3JtOjpzZXRPdXRwdXRMZXZlbChpbnQpIFszNV0KLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAgICAgICAgIDAu MDAgICAgMC4wMCAgICAgICAxLzEgICAgICAgICAgIFBvb21hOjpmaW5hbGl6ZShib29sLCBi b29sKSBbNTJdCls1MV0gICAgIDAuMCAgICAwLjAwICAgIDAuMDAgICAgICAgMSAgICAgICAg IFBvb21hOjpfX05Qb29tYV9jbXBsX2NwcF9mMDA5NDUwZDo6Y2xlYW51cF9zKCAodm9pZCkp IFs1MV0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICAxLzEgICAgICAgICAg IFBvb21hOjpwcmludFN0YXRzKHZvaWQpIFs2MF0KICAgICAgICAgICAgICAgIDAuMDAgICAg MC4wMCAgICAgICAxLzIgICAgICAgICAgIFBvb21hOjpsb2dNZXNzYWdlcyhjaGFyIGNvbnN0 ICopIFs0Nl0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICAxLzIgICAgICAg ICAgIFBvb21hOjppbmZvTWVzc2FnZXMoYm9vbCkgWzQ1XQogICAgICAgICAgICAgICAgMC4w MCAgICAwLjAwICAgICAgIDEvMiAgICAgICAgICAgUG9vbWE6Ondhcm5NZXNzYWdlcyhib29s KSBbNTBdCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgMS8yICAgICAgICAg ICBQb29tYTo6ZXJyb3JNZXNzYWdlcyhib29sKSBbNDRdCiAgICAgICAgICAgICAgICAwLjAw ICAgIDAuMDAgICAgICAgMS8yICAgICAgICAgICBQb29tYTo6ZGVidWdMZXZlbChpbnQpIFs0 M10KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAg ICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICAxLzEgICAgICAgICAgIFBvb21hOjpm aW5hbGl6ZSh2b2lkKSBbNTNdCls1Ml0gICAgIDAuMCAgICAwLjAwICAgIDAuMDAgICAgICAg MSAgICAgICAgIFBvb21hOjpmaW5hbGl6ZShib29sLCBib29sKSBbNTJdCiAgICAgICAgICAg ICAgICAwLjAwICAgIDAuMDAgICAgICAgMS8xICAgICAgICAgICBQb29tYTo6X19OUG9vbWFf Y21wbF9jcHBfZjAwOTQ1MGQ6OmNsZWFudXBfcyggKHZvaWQpKSBbNTFdCi0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAgICAw LjAwICAgIDAuMDAgICAgICAgMS8xICAgICAgICAgICBtYWluIFsyXQpbNTNdICAgICAwLjAg ICAgMC4wMCAgICAwLjAwICAgICAgIDEgICAgICAgICBQb29tYTo6ZmluYWxpemUodm9pZCkg WzUzXQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAgIDEvMSAgICAgICAgICAg UG9vbWE6OmZpbmFsaXplKGJvb2wsIGJvb2wpIFs1Ml0KLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4w MCAgICAgICAxLzEgICAgICAgICAgIEJlbmNobWFyazo6cnVuKHZvaWQpIFsxXQpbNTRdICAg ICAwLjAgICAgMC4wMCAgICAwLjAwICAgICAgIDEgICAgICAgICBCZW5jaG1hcms6OmdldFJl YWR5VG9SdW4odm9pZCkgWzU0XQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAgIDEvMSAg ICAgICAgICAgUG9vbWE6OmluaXRpYWxpemUoaW50ICYsIGNoYXIgKiomLCBib29sLCBib29s LCBib29sKSBbNTZdCls1NV0gICAgIDAuMCAgICAwLjAwICAgIDAuMDAgICAgICAgMSAgICAg ICAgIFBvb21hOjppbml0aWFsaXplKFBvb21hOjpPcHRpb25zICYsIGJvb2wsIGJvb2wpIFs1 NV0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICAxLzIgICAgICAgICAgIFBv b21hOjpkZWJ1Z0xldmVsKGludCkgWzQzXQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAw ICAgICAgIDEvMSAgICAgICAgICAgUG9vbWE6Ok9wdGlvbnM6Om9wZXJhdG9yPSggKFBvb21h OjpPcHRpb25zIGNvbnN0ICYpKSBbMjQ1XQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAw ICAgICAgIDEvMiAgICAgICAgICAgUG9vbWE6OmxvZ01lc3NhZ2VzKGNoYXIgY29uc3QgKikg WzQ2XQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAgIDEvMiAgICAgICAgICAg UG9vbWE6OmluZm9NZXNzYWdlcyhib29sKSBbNDVdCiAgICAgICAgICAgICAgICAwLjAwICAg IDAuMDAgICAgICAgMS8yICAgICAgICAgICBQb29tYTo6d2Fybk1lc3NhZ2VzKGJvb2wpIFs1 MF0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICAxLzIgICAgICAgICAgIFBv b21hOjplcnJvck1lc3NhZ2VzKGJvb2wpIFs0NF0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAg ICAgICAxLzEgICAgICAgICAgIG1haW4gWzJdCls1Nl0gICAgIDAuMCAgICAwLjAwICAgIDAu MDAgICAgICAgMSAgICAgICAgIFBvb21hOjppbml0aWFsaXplKGludCAmLCBjaGFyICoqJiwg Ym9vbCwgYm9vbCwgYm9vbCkgWzU2XQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAg ICAgIDEvMSAgICAgICAgICAgUG9vbWE6Ok9wdGlvbnM6Ol9fY3QoIChpbnQgJiwgY2hhciAq KikpIFsyNTFdCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgMS8xICAgICAg ICAgICBQb29tYTo6aW5pdGlhbGl6ZShQb29tYTo6T3B0aW9ucyAmLCBib29sLCBib29sKSBb NTVdCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgMS8xICAgICAgICAgICBQ b29tYTo6T3B0aW9uczo6X19kdCggKHZvaWQpKSBbMjYyXQotLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgICAgICAgICAgMC4wMCAgICAw LjAwICAgICAgIDEvMSAgICAgICAgICAgQmVuY2htYXJrOjpfX2N0KGludCwgY2hhciAqKiwg Y2hhciBjb25zdCAqLCBpbnQpIFsyNDhdCls1N10gICAgIDAuMCAgICAwLjAwICAgIDAuMDAg ICAgICAgMSAgICAgICAgIGluc2VydF9hdXhfX1EyXzNzdGQ0M3ZlY3Rvcl9fdG1fXzI5X2lR Ml8zc3RkMThhbGxvY2F0b3JfX3RtX18yX2lGUTJfWjJaN3BvaW50ZXJSQ1oxWl92IFs1N10K LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAg ICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICAxLzEgICAgICAgICAgIHN0ZDo6YmFzaWNf b3N0cmVhbV9fdG1fXzMxX2NRMl8zc3RkMjBjaGFyX3RyYWl0c19fdG1fXzJfYzo6b3BlcmF0 b3I8PChzdGQ6OmJhc2ljX29zdHJlYW1fX3RtX183X1oxWloyWiAmKGxvbmcpKSBbMjE5XQpb NThdICAgICAwLjAgICAgMC4wMCAgICAwLjAwICAgICAgIDEgICAgICAgICBzdGQ6OmJhc2lj X2lvc19fdG1fXzMxX2NRMl8zc3RkMjBjaGFyX3RyYWl0c19fdG1fXzJfYzo6bG9hZF9udW1f cHV0X2ZhY2V0KHZvaWQgY29uc3Qodm9pZCkpIFs1OF0KLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4w MCAgICAgICAxLzEgICAgICAgICAgIFBvb21hOjpPcHRpb25zOjpfX2N0KCAoaW50ICYsIGNo YXIgKiopKSBbMjUxXQpbNTldICAgICAwLjAgICAgMC4wMCAgICAwLjAwICAgICAgIDEgICAg ICAgICBQb29tYTo6T3B0aW9uczo6cGFyc2UoIChpbnQgJiwgY2hhciAqKiYpKSBbNTldCiAg ICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgNi8yNyAgICAgICAgICBfX2N0X19R Ml8zc3RkNzhiYXNpY19zdHJpbmdfX3RtX181OF9jUTJfM3N0ZDIwY2hhcl90cmFpdHNfX3Rt X18yX2NRMl8zc3RkMThhbGxvY2F0b3JfX3RtX18yX2NGUENaMVpSQ1ozWiBbMjI3XQogICAg ICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAgIDYvMTI1OCAgICAgICAgc3RkOjpiYXNp Y19zdHJpbmdfX3RtX181OF9jUTJfM3N0ZDIwY2hhcl90cmFpdHNfX3RtX18yX2NRMl8zc3Rk MThhbGxvY2F0b3JfX3RtX18yX2M6Ol9fZHQoICh2b2lkKSkgWzIxNF0KLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAgICAgICAgIDAu MDAgICAgMC4wMCAgICAgICAxLzEgICAgICAgICAgIFBvb21hOjpfX05Qb29tYV9jbXBsX2Nw cF9mMDA5NDUwZDo6Y2xlYW51cF9zKCAodm9pZCkpIFs1MV0KWzYwXSAgICAgMC4wICAgIDAu MDAgICAgMC4wMCAgICAgICAxICAgICAgICAgUG9vbWE6OnByaW50U3RhdHModm9pZCkgWzYw XQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAg ICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAgIDEvMSAgICAgICAgICAgbWFpbiBbMl0K WzYxXSAgICAgMC4wICAgIDAuMDAgICAgMC4wMCAgICAgICAxICAgICAgICAgQmVuY2htYXJr OjpzZXRTYW1wbGluZ1BhcmFtZXRlcnMoaW50LCBpbnQsIGludCkgWzYxXQotLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgICAgICAgICAg MC4wMCAgICAwLjAwICAgICAzMDEvNjY1MjEgICAgICAgaW5pdGlhbGl6ZV9fNDVBQkNUZXN0 QmFzZV9fcHNfXzEyX1oxWlhDYkxfMV8wX190bV9fN181QnJpY2tGaV92IFsxMF0KICAgICAg ICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAzMDEwLzY2NTIxICAgICAgIHJ1blNldHVwX180 NUFCQ1Rlc3RCYXNlX19wc19fMTJfWjFaWENiTF8xXzBfX3RtX183XzVCcmlja0Z2X3YgWzld CiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICA2MzIxMC82NjUyMSAgICAgICBydW5f XzMwQUJDSW5QMl9fdG1fXzE1XzVCcmlja1hDYkxfMV8wRnZfdiBbNV0KWzIxMl0gICAgMC4w ICAgIDAuMDAgICAgMC4wMCAgIDY2NTIxICAgICAgICAgRGF0YUJsb2NrUHRyX190bV9fMTBf ZFhDYkxfMV8wOjpfX2N0KERhdGFCbG9ja1B0cl9fdG1fXzhfWjFaWFoyWiBjb25zdCAmLCBp bnQpIFsyMTJdCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgIDMwMS8zMzExICAgICAgICBp bml0aWFsaXplX180NUFCQ1Rlc3RCYXNlX19wc19fMTJfWjFaWENiTF8xXzBfX3RtX183XzVC cmlja0ZpX3YgWzEwXQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgIDMwMTAvMzMx MSAgICAgICAgcnVuU2V0dXBfXzQ1QUJDVGVzdEJhc2VfX3BzX18xMl9aMVpYQ2JMXzFfMF9f dG1fXzdfNUJyaWNrRnZfdiBbOV0KWzIxM10gICAgMC4wICAgIDAuMDAgICAgMC4wMCAgICAz MzExICAgICAgICAgX19jdF9fdG1fXzI3XzI0SW50ZXJ2YWxfX3RtX185X1hDaUxfMV8yX180 MUFycmF5X190bV9fMjhfWENpTF8xXzJkMTZDb25zdGFudEZ1bmN0aW9uRlJDWjFfMlogWzIx M10KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAg ICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICAyLzEyNTggICAgICAgIEJlbmNobWFy azo6X19kdCh2b2lkKSBbMjU5XQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAg IDIvMTI1OCAgICAgICAgUG9vbWE6Ok9wdGlvbnM6Ol9fZHQoICh2b2lkKSkgWzI2Ml0KICAg ICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICAzLzEyNTggICAgICAgIEJlbmNobWFy azo6cnVuKHZvaWQpIFsxXQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAgIDQv MTI1OCAgICAgICAgSW5mb3JtOjpfX2R0KHZvaWQpIFszODddCiAgICAgICAgICAgICAgICAw LjAwICAgIDAuMDAgICAgICAgNi8xMjU4ICAgICAgICBQb29tYTo6T3B0aW9uczo6cGFyc2Uo IChpbnQgJiwgY2hhciAqKiYpKSBbNTldCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAg ICAgICAgNy8xMjU4ICAgICAgICBCZW5jaG1hcms6OnByaW50UmVzdWx0cyh2b2lkKSBbMjBd CiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAxMi8xMjU4ICAgICAgICBfX3N0 aV9fUG9vbWFfY21wbF9jcHBfZjAwOTQ1MGQgWzI2OF0KICAgICAgICAgICAgICAgIDAuMDAg ICAgMC4wMCAgICAgIDEyLzEyNTggICAgICAgIFBvb21hOjpTdGF0aXN0aWNzOjpfX2R0KCAo dm9pZCkpIFszOTNdCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgMTIxMC8xMjU4 ICAgICAgICBJbmZvcm06OmZsdXNoKHZvaWQpIFsxNl0KWzIxNF0gICAgMC4wICAgIDAuMDAg ICAgMC4wMCAgICAxMjU4ICAgICAgICAgc3RkOjpiYXNpY19zdHJpbmdfX3RtX181OF9jUTJf M3N0ZDIwY2hhcl90cmFpdHNfX3RtX18yX2NRMl8zc3RkMThhbGxvY2F0b3JfX3RtX18yX2M6 Ol9fZHQoICh2b2lkKSkgWzIxNF0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICAzLzkx NSAgICAgICAgIEVuZ2luZV9fcHNfXzI3X1haMVpaMloxN0NvbXByZXNzaWJsZUJyaWNrX190 bV9fMTBfWENpTF8xXzJkOjpfX2R0KHZvaWQpIFsyMzVdCiAgICAgICAgICAgICAgICAwLjAw ICAgIDAuMDAgICAgIDkxMi85MTUgICAgICAgICBFbmdpbmVfX3BzX18xNF9YWjFaWjJaNUJy aWNrX190bV9fMTBfWENpTF8xXzJkOjpfX2R0KHZvaWQpIFsyMThdClsyMTVdICAgIDAuMCAg ICAwLjAwICAgIDAuMDAgICAgIDkxNSAgICAgICAgIFBvb21hOjpCcmlja0Jhc2VfX3RtX185 X1hDaUxfMV8yOjpfX2R0KCAodm9pZCkpIFsyMTVdCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgIDkxNCAgICAgICAgICAgICBzdGQ6OmJhc2ljX29zdHJlYW1fX3RtX18zMV9jUTJfM3N0 ZDIwY2hhcl90cmFpdHNfX3RtX18yX2M6OmZsdXNoKHN0ZDo6YmFzaWNfb3N0cmVhbV9fdG1f XzdfWjFaWjJaICYodm9pZCkpIDxjeWNsZSAxPiBbMjddClsyMTZdICAgIDAuMCAgICAwLjAw ICAgIDAuMDAgICAgIDkxNCAgICAgICAgIHN0ZDo6YmFzaWNfb3N0cmVhbV9fdG1fXzMxX2NR Ml8zc3RkMjBjaGFyX3RyYWl0c19fdG1fXzJfYzo6c2VudHJ5OjpfX2N0KCAoc3RkOjpiYXNp Y19vc3RyZWFtX190bV9fN19aMVpaMlogJikpIDxjeWNsZSAxPiBbMjE2XQogICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgIDIgICAgICAgICAgICAgc3RkOjpiYXNpY19vc3Ry ZWFtX190bV9fMzFfY1EyXzNzdGQyMGNoYXJfdHJhaXRzX190bV9fMl9jOjpmbHVzaChzdGQ6 OmJhc2ljX29zdHJlYW1fX3RtX183X1oxWloyWiAmKHZvaWQpKSA8Y3ljbGUgMT4gWzI3XQot LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAg ICAgICAgICAgMC4wMCAgICAwLjAwICAgICA5MTIvOTEyICAgICAgICAgRW5naW5lX19wc19f MTRfWFoxWloyWjVCcmlja19fdG1fXzEwX1hDaUxfMV8yZDo6X19kdCh2b2lkKSBbMjE4XQpb MjE3XSAgICAwLjAgICAgMC4wMCAgICAwLjAwICAgICA5MTIgICAgICAgICBEYXRhQmxvY2tQ dHJfX3RtX18xMF9kWENiTF8xXzA6Ol9fZHQodm9pZCkgWzIxN10KLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAgICAgICAgIDAuMDAg ICAgMC4wMCAgICAgICAzLzkxMiAgICAgICAgIEFCQ0luQzo6X19kdCh2b2lkKSBbMjU4XQog ICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAgIDMvOTEyICAgICAgICAgQUJDSW5D cHBUcmFuX190bV9fMTVfNUJyaWNrWENiTF8xXzA6Ol9fZHQodm9pZCkgWzI1NV0KICAgICAg ICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICAzLzkxMiAgICAgICAgIEFCQ0luUDJfX3Rt X18xNV81QnJpY2tYQ2JMXzFfMDo6X19kdCh2b2lkKSBbMjUzXQogICAgICAgICAgICAgICAg MC4wMCAgICAwLjAwICAgICA5MDMvOTEyICAgICAgICAgaW5pdGlhbGl6ZV9fNDVBQkNUZXN0 QmFzZV9fcHNfXzEyX1oxWlhDYkxfMV8wX190bV9fN181QnJpY2tGaV92IFsxMF0KWzIxOF0g ICAgMC4wICAgIDAuMDAgICAgMC4wMCAgICAgOTEyICAgICAgICAgRW5naW5lX19wc19fMTRf WFoxWloyWjVCcmlja19fdG1fXzEwX1hDaUxfMV8yZDo6X19kdCh2b2lkKSBbMjE4XQogICAg ICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICA5MTIvOTEyICAgICAgICAgRGF0YUJsb2Nr UHRyX190bV9fMTBfZFhDYkxfMV8wOjpfX2R0KHZvaWQpIFsyMTddCiAgICAgICAgICAgICAg ICAwLjAwICAgIDAuMDAgICAgIDkxMi85MTUgICAgICAgICBQb29tYTo6QnJpY2tCYXNlX190 bV9fOV9YQ2lMXzFfMjo6X19kdCggKHZvaWQpKSBbMjE1XQotLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgICAgICAgICAgMC4wMCAgICAw LjAwICAgICAzMDEvOTA0ICAgICAgICAgQmVuY2htYXJrOjpwcmludFJlc3VsdHModm9pZCkg WzIwXQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICA2MDMvOTA0ICAgICAgICAg QmVuY2htYXJrOjpydW5JbXBsZW1lbnRhdGlvbihJbXBsZW1lbnRhdGlvbiAqLCBpbnQpIFsz XQpbMjE5XSAgICAwLjAgICAgMC4wMCAgICAwLjAwICAgICA5MDQgICAgICAgICBzdGQ6OmJh c2ljX29zdHJlYW1fX3RtX18zMV9jUTJfM3N0ZDIwY2hhcl90cmFpdHNfX3RtX18yX2M6Om9w ZXJhdG9yPDwoc3RkOjpiYXNpY19vc3RyZWFtX190bV9fN19aMVpaMlogJihsb25nKSkgWzIx OV0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICAxLzEgICAgICAgICAgIHN0 ZDo6YmFzaWNfaW9zX190bV9fMzFfY1EyXzNzdGQyMGNoYXJfdHJhaXRzX190bV9fMl9jOjps b2FkX251bV9wdXRfZmFjZXQodm9pZCBjb25zdCh2b2lkKSkgWzU4XQotLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgICAgICAgICAgMC4w MCAgICAwLjAwICAgICA5MDMvOTAzICAgICAgICAgX19DUFIxMTlfX19fYXNfXzQ2RW5naW5l X19wc19fMTRfWFoxWloyWjVCcmlja19fdG1fXzEwX1hDaUxfMV8yZEZSQzI4RW5naW5lX190 bV9fSjIwSl9SSjU3SiBbMjIxXQpbMjIwXSAgICAwLjAgICAgMC4wMCAgICAwLjAwICAgICA5 MDMgICAgICAgICBfX0NQUjEwMV9fX19hc19fMzBEYXRhQmxvY2tQdHJfX3RtX18xMF9kWENi TF8xXzBGUkMyN0RhdGFCbG9ja1B0cl9fdG1fXzhfWjFaWFoyWl9SSjQxSiBbMjIwXQotLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgICAg ICAgICAgMC4wMCAgICAwLjAwICAgICA5MDMvOTAzICAgICAgICAgaW5pdGlhbGl6ZV9fNDVB QkNUZXN0QmFzZV9fcHNfXzEyX1oxWlhDYkxfMV8wX190bV9fN181QnJpY2tGaV92IFsxMF0K WzIyMV0gICAgMC4wICAgIDAuMDAgICAgMC4wMCAgICAgOTAzICAgICAgICAgX19DUFIxMTlf X19fYXNfXzQ2RW5naW5lX19wc19fMTRfWFoxWloyWjVCcmlja19fdG1fXzEwX1hDaUxfMV8y ZEZSQzI4RW5naW5lX190bV9fSjIwSl9SSjU3SiBbMjIxXQogICAgICAgICAgICAgICAgMC4w MCAgICAwLjAwICAgICA5MDMvOTAzICAgICAgICAgX19DUFIxMDFfX19fYXNfXzMwRGF0YUJs b2NrUHRyX190bV9fMTBfZFhDYkxfMV8wRlJDMjdEYXRhQmxvY2tQdHJfX3RtX184X1oxWlha MlpfUko0MUogWzIyMF0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgOTAzLzkwMyAgICAg ICAgIEVuZ2luZV9fcHNfXzE0X1haMVpaMlo1QnJpY2tfX3RtX18xMF9YQ2lMXzFfMmQ6Ol9f Y3QoUG9vbWE6OkJyaWNrQmFzZV9fdG1fXzVfWFoxWjo6RG9tYWluX3QgY29uc3QgJikgWzIy M10KWzIyMl0gICAgMC4wICAgIDAuMDAgICAgMC4wMCAgICAgOTAzICAgICAgICAgRGF0YUJs b2NrUHRyX190bV9fMTBfZFhDYkxfMV8wOjpfX2N0KHVuc2lnbmVkIGludCkgWzIyMl0KLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAg ICAgICAgIDAuMDAgICAgMC4wMCAgICAgOTAzLzkwMyAgICAgICAgIGluaXRpYWxpemVfXzQ1 QUJDVGVzdEJhc2VfX3BzX18xMl9aMVpYQ2JMXzFfMF9fdG1fXzdfNUJyaWNrRmlfdiBbMTBd ClsyMjNdICAgIDAuMCAgICAwLjAwICAgIDAuMDAgICAgIDkwMyAgICAgICAgIEVuZ2luZV9f cHNfXzE0X1haMVpaMlo1QnJpY2tfX3RtX18xMF9YQ2lMXzFfMmQ6Ol9fY3QoUG9vbWE6OkJy aWNrQmFzZV9fdG1fXzVfWFoxWjo6RG9tYWluX3QgY29uc3QgJikgWzIyM10KICAgICAgICAg ICAgICAgIDAuMDAgICAgMC4wMCAgICAgOTAzLzkwMyAgICAgICAgIFBvb21hOjpCcmlja0Jh c2VfX3RtX185X1hDaUxfMV8yOjpfX2N0KCAoSW50ZXJ2YWxfX3RtX181X1haMVogY29uc3Qg JiwgYm9vbCkpIFsyMjRdCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgIDkwMy85 MDMgICAgICAgICBEYXRhQmxvY2tQdHJfX3RtX18xMF9kWENiTF8xXzA6Ol9fY3QodW5zaWdu ZWQgaW50KSBbMjIyXQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICA5MDMvOTAzICAgICAg ICAgRW5naW5lX19wc19fMTRfWFoxWloyWjVCcmlja19fdG1fXzEwX1hDaUxfMV8yZDo6X19j dChQb29tYTo6QnJpY2tCYXNlX190bV9fNV9YWjFaOjpEb21haW5fdCBjb25zdCAmKSBbMjIz XQpbMjI0XSAgICAwLjAgICAgMC4wMCAgICAwLjAwICAgICA5MDMgICAgICAgICBQb29tYTo6 QnJpY2tCYXNlX190bV9fOV9YQ2lMXzFfMjo6X19jdCggKEludGVydmFsX190bV9fNV9YWjFa IGNvbnN0ICYsIGJvb2wpKSBbMjI0XQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAgIDEv MzAzICAgICAgICAgQmVuY2htYXJrOjpydW5JbXBsZW1lbnRhdGlvbihJbXBsZW1lbnRhdGlv biAqLCBpbnQpIFszXQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAgIDEvMzAz ICAgICAgICAgX19DUFIxNjVfX19fZHRfX1EyXzNzdGQxNDd2ZWN0b3JfX3RtX18xMzJfUTJf M3N0ZDQzdmVjdG9yX190bV9fMjlfZFEyXzNzdGQxOGFsbG9jYXRvcl9fdG1fXzJfZFEyXzNz dGQ3MGFsbG9jYXRvcl9fdG1fXzUzX1EyXzNzdGRKMzlKRnYgWzI0MV0KICAgICAgICAgICAg ICAgIDAuMDAgICAgMC4wMCAgICAgMzAxLzMwMyAgICAgICAgIEJlbmNobWFyazo6cHJpbnRS ZXN1bHRzKHZvaWQpIFsyMF0KWzIyNV0gICAgMC4wICAgIDAuMDAgICAgMC4wMCAgICAgMzAz ICAgICAgICAgc3RkOjp2ZWN0b3JfX3RtX18yOV9kUTJfM3N0ZDE4YWxsb2NhdG9yX190bV9f Ml9kOjpfX2R0KCAodm9pZCkpIFsyMjVdCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAg MS8zMDIgICAgICAgICBCZW5jaG1hcms6OnJ1bkltcGxlbWVudGF0aW9uKEltcGxlbWVudGF0 aW9uICosIGludCkgWzNdCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgIDMwMS8z MDIgICAgICAgICBCZW5jaG1hcms6OnByaW50UmVzdWx0cyh2b2lkKSBbMjBdClsyMjZdICAg IDAuMCAgICAwLjAwICAgIDAuMDAgICAgIDMwMiAgICAgICAgIF9pbml0aWFsaXplX3N0b3Jh Z2VfX1EyXzNzdGQ0M3ZlY3Rvcl9fdG1fXzI5X2RRMl8zc3RkMThhbGxvY2F0b3JfX3RtX18y X2RGUTJfWjJaOXNpemVfdHlwZVJDWjFaX3YgWzIyNl0KLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4w MCAgICAgICAyLzI3ICAgICAgICAgIEJlbmNobWFyazo6cnVuKHZvaWQpIFsxXQogICAgICAg ICAgICAgICAgMC4wMCAgICAwLjAwICAgICAgIDIvMjcgICAgICAgICAgQmVuY2htYXJrOjpw cmludFJlc3VsdHModm9pZCkgWzIwXQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAg ICAgIDIvMjcgICAgICAgICAgSW5mb3JtOjpfX2N0KGNoYXIgY29uc3QgKiwgaW50KSBbMjM4 XQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAgIDMvMjcgICAgICAgICAgSW5m b3JtOjpfX2N0KGNoYXIgY29uc3QgKiwgc3RkOjpiYXNpY19vc3RyZWFtX190bV9fMzFfY1Ey XzNzdGQyMGNoYXJfdHJhaXRzX190bV9fMl9jICYsIGludCkgWzIzNF0KICAgICAgICAgICAg ICAgIDAuMDAgICAgMC4wMCAgICAgICA2LzI3ICAgICAgICAgIFBvb21hOjpPcHRpb25zOjpw YXJzZSggKGludCAmLCBjaGFyICoqJikpIFs1OV0KICAgICAgICAgICAgICAgIDAuMDAgICAg MC4wMCAgICAgIDEyLzI3ICAgICAgICAgIF9fc3RpX19Qb29tYV9jbXBsX2NwcF9mMDA5NDUw ZCBbMjY4XQpbMjI3XSAgICAwLjAgICAgMC4wMCAgICAwLjAwICAgICAgMjcgICAgICAgICBf X2N0X19RMl8zc3RkNzhiYXNpY19zdHJpbmdfX3RtX181OF9jUTJfM3N0ZDIwY2hhcl90cmFp dHNfX3RtX18yX2NRMl8zc3RkMThhbGxvY2F0b3JfX3RtX18yX2NGUENaMVpSQ1ozWiBbMjI3 XQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAg ICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAgMTIvMTIgICAgICAgICAgX19zdGlfX1Bv b21hX2NtcGxfY3BwX2YwMDk0NTBkIFsyNjhdClsyMjhdICAgIDAuMCAgICAwLjAwICAgIDAu MDAgICAgICAxMiAgICAgICAgIF9fY3RfX1EyXzNzdGQ3OGJhc2ljX3N0cmluZ19fdG1fXzU4 X2NRMl8zc3RkMjBjaGFyX3RyYWl0c19fdG1fXzJfY1EyXzNzdGQxOGFsbG9jYXRvcl9fdG1f XzJfY0ZSQ1EyXzNzdGQzMGJhc2ljX3N0cmluZ19fdG1fXzEwX1oxWloyWlozWlEyX1ozWjlz aXplX3R5cGVUMlJDWjNaIFsyMjhdCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgMy8x MiAgICAgICAgICBBQkNJbkM6Ol9fY3Qodm9pZCkgWzI0N10KICAgICAgICAgICAgICAgIDAu MDAgICAgMC4wMCAgICAgICAzLzEyICAgICAgICAgIEFCQ1Rlc3RCYXNlX19wc19fMTJfWjFa WENiTF8xXzBfX3RtX18yMF8xN0NvbXByZXNzaWJsZUJyaWNrOjpfX2N0KGludCkgWzI0Nl0K ICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICA2LzEyICAgICAgICAgIG1haW4g WzJdClsyMjldICAgIDAuMCAgICAwLjAwICAgIDAuMDAgICAgICAxMiAgICAgICAgIFBvb21h OjpCcmlja0Jhc2VfX3RtX185X1hDaUxfMV8yOjpfX2N0KCAoYm9vbCkpIFsyMjldCi0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAg ICAgICAwLjAwICAgIDAuMDAgICAgICAgNS81ICAgICAgICAgICBfX21vZGlmeV9fUTJfNV9f a2FpNDlyYl90cmVlX190bV9fMzRfaVEyXzNzdGQxM2xlc3NfX3RtX18yX2lYQ1VpTF8yXzE2 RlJDWjFaUGJRM181X19rYWkxMnJiX3RyZWVfYmFzZTExbW9kaWZ5X21vZGVfUFEyXzVfX2th aTE3cmJfdHJlZV9ub2RlX2Jhc2UgWzIzMV0KWzIzMF0gICAgMC4wICAgIDAuMDAgICAgMC4w MCAgICAgICA1ICAgICAgICAgX19DUFIxNzlfX21ha2Vfbm9kZV9fUTJfNV9fa2FpMTIybWFw X2Jhc2VfX3RtX18xMDVfaVAxMkluZm9ybVN0cmVhbVEyXzNzdGQxM2xlc3NfX3RtX18yX2lR Ml8zc3RkNTdhbGxvY2F0b3JfX3RtX180MF9RMl8zc3RkMzBwYWlyX190bV9fMThfQ2lQSjQz SkZQQ3ZfUFEyX0oxNEoxN3JiX3RyZWVfbm9kZV9iYXNlIFsyMzBdCi0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAgICAwLjAw ICAgIDAuMDAgICAgICAgMi81ICAgICAgICAgICBJbmZvcm06Om9wZW4oaW50KSBbNDddCiAg ICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgMy81ICAgICAgICAgICBJbmZvcm06 Om9wZW4oc3RkOjpiYXNpY19vc3RyZWFtX190bV9fMzFfY1EyXzNzdGQyMGNoYXJfdHJhaXRz X190bV9fMl9jICYsIGludCkgWzQyXQpbMjMxXSAgICAwLjAgICAgMC4wMCAgICAwLjAwICAg ICAgIDUgICAgICAgICBfX21vZGlmeV9fUTJfNV9fa2FpNDlyYl90cmVlX190bV9fMzRfaVEy XzNzdGQxM2xlc3NfX3RtX18yX2lYQ1VpTF8yXzE2RlJDWjFaUGJRM181X19rYWkxMnJiX3Ry ZWVfYmFzZTExbW9kaWZ5X21vZGVfUFEyXzVfX2thaTE3cmJfdHJlZV9ub2RlX2Jhc2UgWzIz MV0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICA1LzUgICAgICAgICAgIF9f Q1BSMTc5X19tYWtlX25vZGVfX1EyXzVfX2thaTEyMm1hcF9iYXNlX190bV9fMTA1X2lQMTJJ bmZvcm1TdHJlYW1RMl8zc3RkMTNsZXNzX190bV9fMl9pUTJfM3N0ZDU3YWxsb2NhdG9yX190 bV9fNDBfUTJfM3N0ZDMwcGFpcl9fdG1fXzE4X0NpUEo0M0pGUEN2X1BRMl9KMTRKMTdyYl90 cmVlX25vZGVfYmFzZSBbMjMwXQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAgIDEvMyAg ICAgICAgICAgQmVuY2htYXJrOjpydW5JdCh2b2lkKSBbNF0KICAgICAgICAgICAgICAgIDAu MDAgICAgMC4wMCAgICAgICAyLzMgICAgICAgICAgIEJlbmNobWFyazo6YWRkSW1wbGVtZW50 YXRpb24oSW1wbGVtZW50YXRpb24gKikgWzM2XQpbMjMyXSAgICAwLjAgICAgMC4wMCAgICAw LjAwICAgICAgIDMgICAgICAgICBfX0NQUjExOV9faW5zZXJ0X2F1eF9fUTJfM3N0ZDc2dmVj dG9yX190bV9fNjJfUDE0SW1wbGVtZW50YXRpb25RMl8zc3RkMzVhbGxvY2F0b3JfX3RtX18x OF9QSjM3SkZRMl9aMlo3cG9pbnRlclJDWjFaX3YgWzIzMl0KLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAgICAgICAgIDAuMDAgICAg MC4wMCAgICAgICAzLzMgICAgICAgICAgIF9fc3RpX19Qb29tYV9jbXBsX2NwcF9mMDA5NDUw ZCBbMjY4XQpbMjMzXSAgICAwLjAgICAgMC4wMCAgICAwLjAwICAgICAgIDMgICAgICAgICBf X0NQUjEzN19faW5zZXJ0X2F1eF9fUTJfM3N0ZDk0dmVjdG9yX190bV9fODBfUFEyXzVQb29t YTE0U3RhdGlzdGljc0RhdGFRMl8zc3RkNDRhbGxvY2F0b3JfX3RtX18yN19QUTJfSjQwSko0 NkpGUTJfWjJaN3BvaW50ZXJSQ1oxWl92IFsyMzNdCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAg ICAgICAgMy8zICAgICAgICAgICBfX3N0aV9fUG9vbWFfY21wbF9jcHBfZjAwOTQ1MGQgWzI2 OF0KWzIzNF0gICAgMC4wICAgIDAuMDAgICAgMC4wMCAgICAgICAzICAgICAgICAgSW5mb3Jt OjpfX2N0KGNoYXIgY29uc3QgKiwgc3RkOjpiYXNpY19vc3RyZWFtX190bV9fMzFfY1EyXzNz dGQyMGNoYXJfdHJhaXRzX190bV9fMl9jICYsIGludCkgWzIzNF0KICAgICAgICAgICAgICAg IDAuMDAgICAgMC4wMCAgICAgICAzLzI3ICAgICAgICAgIF9fY3RfX1EyXzNzdGQ3OGJhc2lj X3N0cmluZ19fdG1fXzU4X2NRMl8zc3RkMjBjaGFyX3RyYWl0c19fdG1fXzJfY1EyXzNzdGQx OGFsbG9jYXRvcl9fdG1fXzJfY0ZQQ1oxWlJDWjNaIFsyMjddCiAgICAgICAgICAgICAgICAw LjAwICAgIDAuMDAgICAgICAgMy8zICAgICAgICAgICBJbmZvcm06Om9wZW4oc3RkOjpiYXNp Y19vc3RyZWFtX190bV9fMzFfY1EyXzNzdGQyMGNoYXJfdHJhaXRzX190bV9fMl9jICYsIGlu dCkgWzQyXQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAgIDMvNSAgICAgICAg ICAgSW5mb3JtOjpzZXR1cChjaGFyIGNvbnN0ICopIFszOF0KLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAgICAgICAgIDAuMDAgICAg MC4wMCAgICAgICAzLzMgICAgICAgICAgIEFCQ0luUDJfX3RtX18yOF8xN0NvbXByZXNzaWJs ZUJyaWNrWENiTF8xXzA6Ol9fZHQodm9pZCkgWzI1Nl0KWzIzNV0gICAgMC4wICAgIDAuMDAg ICAgMC4wMCAgICAgICAzICAgICAgICAgRW5naW5lX19wc19fMjdfWFoxWloyWjE3Q29tcHJl c3NpYmxlQnJpY2tfX3RtX18xMF9YQ2lMXzFfMmQ6Ol9fZHQodm9pZCkgWzIzNV0KICAgICAg ICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICAzLzkxNSAgICAgICAgIFBvb21hOjpCcmlj a0Jhc2VfX3RtX185X1hDaUxfMV8yOjpfX2R0KCAodm9pZCkpIFsyMTVdCi0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAgICAw LjAwICAgIDAuMDAgICAgICAgMi8yICAgICAgICAgICBCZW5jaG1hcms6Ol9fZHQodm9pZCkg WzI1OV0KWzIzNl0gICAgMC4wICAgIDAuMDAgICAgMC4wMCAgICAgICAyICAgICAgICAgX19D UFI5M19fX19kdF9fUTJfM3N0ZDc2dmVjdG9yX190bV9fNjJfUDE0SW1wbGVtZW50YXRpb25R Ml8zc3RkMzVhbGxvY2F0b3JfX3RtX18xOF9QSjMxSkZ2IFsyMzZdCi0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAgICAwLjAw ICAgIDAuMDAgICAgICAgMi8yICAgICAgICAgICBfX3N0aV9fQUJDX2NwcF9tYWluIFsyNjNd ClsyMzddICAgIDAuMCAgICAwLjAwICAgIDAuMDAgICAgICAgMiAgICAgICAgIFBvb2w6Ol9f Y3QodW5zaWduZWQgaW50KSBbMjM3XQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAgIDEv MiAgICAgICAgICAgX19zdGlfX1Bvb21hX2NtcGxfY3BwX2YwMDk0NTBkIFsyNjhdCiAgICAg ICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgMS8yICAgICAgICAgICBCZW5jaG1hcms6 Ol9fY3QoaW50LCBjaGFyICoqLCBjaGFyIGNvbnN0ICosIGludCkgWzI0OF0KWzIzOF0gICAg MC4wICAgIDAuMDAgICAgMC4wMCAgICAgICAyICAgICAgICAgSW5mb3JtOjpfX2N0KGNoYXIg Y29uc3QgKiwgaW50KSBbMjM4XQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAg IDIvMjcgICAgICAgICAgX19jdF9fUTJfM3N0ZDc4YmFzaWNfc3RyaW5nX190bV9fNThfY1Ey XzNzdGQyMGNoYXJfdHJhaXRzX190bV9fMl9jUTJfM3N0ZDE4YWxsb2NhdG9yX190bV9fMl9j RlBDWjFaUkNaM1ogWzIyN10KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICAy LzIgICAgICAgICAgIEluZm9ybTo6b3BlbihpbnQpIFs0N10KICAgICAgICAgICAgICAgIDAu MDAgICAgMC4wMCAgICAgICAyLzUgICAgICAgICAgIEluZm9ybTo6c2V0dXAoY2hhciBjb25z dCAqKSBbMzhdCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgMi8yICAgICAgICAgICBQ b29sOjpfX2R0KHZvaWQpIFszODFdClsyMzldICAgIDAuMCAgICAwLjAwICAgIDAuMDAgICAg ICAgMiAgICAgICAgIHN0ZDo6dmVjdG9yX190bV9fMzFfUGNRMl8zc3RkMTlhbGxvY2F0b3Jf X3RtX18zX1BjOjpfX2R0KCAodm9pZCkpIFsyMzldCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAg ICAgICAgMS8xICAgICAgICAgICBQb29tYTo6U3RhdGlzdGljczo6X19kdCggKHZvaWQpKSBb MzkzXQpbMjQwXSAgICAwLjAgICAgMC4wMCAgICAwLjAwICAgICAgIDEgICAgICAgICBfX0NQ UjExMV9fX19kdF9fUTJfM3N0ZDk0dmVjdG9yX190bV9fODBfUFEyXzVQb29tYTE0U3RhdGlz dGljc0RhdGFRMl8zc3RkNDRhbGxvY2F0b3JfX3RtX18yN19QUTJfSjM0Sko0MEpGdiBbMjQw XQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAg ICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAgIDEvMSAgICAgICAgICAgQmVuY2htYXJr OjpfX2R0KHZvaWQpIFsyNTldClsyNDFdICAgIDAuMCAgICAwLjAwICAgIDAuMDAgICAgICAg MSAgICAgICAgIF9fQ1BSMTY1X19fX2R0X19RMl8zc3RkMTQ3dmVjdG9yX190bV9fMTMyX1Ey XzNzdGQ0M3ZlY3Rvcl9fdG1fXzI5X2RRMl8zc3RkMThhbGxvY2F0b3JfX3RtX18yX2RRMl8z c3RkNzBhbGxvY2F0b3JfX3RtX181M19RMl8zc3RkSjM5SkZ2IFsyNDFdCiAgICAgICAgICAg ICAgICAwLjAwICAgIDAuMDAgICAgICAgMS8zMDMgICAgICAgICBzdGQ6OnZlY3Rvcl9fdG1f XzI5X2RRMl8zc3RkMThhbGxvY2F0b3JfX3RtX18yX2Q6Ol9fZHQoICh2b2lkKSkgWzIyNV0K LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAg ICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICAxLzEgICAgICAgICAgIFBvb21hOjpPcHRp b25zOjpvcGVyYXRvcj0oIChQb29tYTo6T3B0aW9ucyBjb25zdCAmKSkgWzI0NV0KWzI0Ml0g ICAgMC4wICAgIDAuMDAgICAgMC4wMCAgICAgICAxICAgICAgICAgX19DUFIxNzZfX19fYXNf X1EyXzNzdGQ3OGJhc2ljX3N0cmluZ19fdG1fXzU4X2NRMl8zc3RkMjBjaGFyX3RyYWl0c19f dG1fXzJfY1EyXzNzdGQxOGFsbG9jYXRvcl9fdG1fXzJfY0ZSQ1EyXzNzdGQzMGJhc2ljX3N0 cmluZ19fdG1fXzEwX1oxWloyWlozWl9SUTJfM3N0ZEoxMDNKIFsyNDJdCi0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAgICAw LjAwICAgIDAuMDAgICAgICAgMS8xICAgICAgICAgICBCZW5jaG1hcms6OnJ1bkltcGxlbWVu dGF0aW9uKEltcGxlbWVudGF0aW9uICosIGludCkgWzNdClsyNDNdICAgIDAuMCAgICAwLjAw ICAgIDAuMDAgICAgICAgMSAgICAgICAgIF9fQ1BSMTkxX19pbnNlcnRfYXV4X19RMl8zc3Rk MTQ3dmVjdG9yX190bV9fMTMyX1EyXzNzdGQ0M3ZlY3Rvcl9fdG1fXzI5X2RRMl8zc3RkMThh bGxvY2F0b3JfX3RtX18yX2RRMl8zc3RkNzBhbGxvY2F0b3JfX3RtX181M19RMl8zc3RkSjQ1 SkZRMl9aMlo3cG9pbnRlclJDWjFaX3YgWzI0M10KICAgICAgICAgICAgICAgIDAuMDAgICAg MC4wMCAgICAgICAxLzEgICAgICAgICAgIHN0ZDo6dmVjdG9yX190bV9fMjlfZFEyXzNzdGQx OGFsbG9jYXRvcl9fdG1fXzJfZDo6X19jdCggKHN0ZDo6dmVjdG9yX190bV9fN19aMVpaMlog Y29uc3QgJikpIFsyNDldCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgMS8xICAgICAg ICAgICBCZW5jaG1hcms6Ol9fZHQodm9pZCkgWzI1OV0KWzI0NF0gICAgMC4wICAgIDAuMDAg ICAgMC4wMCAgICAgICAxICAgICAgICAgX19DUFIyMzZfX19fZHRfX1EyXzNzdGQyMTh2ZWN0 b3JfX3RtX18yMDNfUTJfM3N0ZDc4YmFzaWNfc3RyaW5nX190bV9fNThfY1EyXzNzdGQyMGNo YXJfdHJhaXRzX190bV9fMl9jUTJfM3N0ZDE4YWxsb2NhdG9yX190bV9fMl9jUTJfM3N0ZDEw NWFsbG9jYXRvcl9fdG1fXzg4X1EyXzNzdGRKMzlKRnYgWzI0NF0KLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAgICAgICAgIDAuMDAg ICAgMC4wMCAgICAgICAxLzEgICAgICAgICAgIFBvb21hOjppbml0aWFsaXplKFBvb21hOjpP cHRpb25zICYsIGJvb2wsIGJvb2wpIFs1NV0KWzI0NV0gICAgMC4wICAgIDAuMDAgICAgMC4w MCAgICAgICAxICAgICAgICAgUG9vbWE6Ok9wdGlvbnM6Om9wZXJhdG9yPSggKFBvb21hOjpP cHRpb25zIGNvbnN0ICYpKSBbMjQ1XQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAg ICAgIDEvMSAgICAgICAgICAgX19DUFIxNzZfX19fYXNfX1EyXzNzdGQ3OGJhc2ljX3N0cmlu Z19fdG1fXzU4X2NRMl8zc3RkMjBjaGFyX3RyYWl0c19fdG1fXzJfY1EyXzNzdGQxOGFsbG9j YXRvcl9fdG1fXzJfY0ZSQ1EyXzNzdGQzMGJhc2ljX3N0cmluZ19fdG1fXzEwX1oxWloyWloz Wl9SUTJfM3N0ZEoxMDNKIFsyNDJdCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgMS8x ICAgICAgICAgICBtYWluIFsyXQpbMjQ2XSAgICAwLjAgICAgMC4wMCAgICAwLjAwICAgICAg IDEgICAgICAgICBBQkNUZXN0QmFzZV9fcHNfXzEyX1oxWlhDYkxfMV8wX190bV9fMjBfMTdD b21wcmVzc2libGVCcmljazo6X19jdChpbnQpIFsyNDZdCiAgICAgICAgICAgICAgICAwLjAw ICAgIDAuMDAgICAgICAgMy8xMiAgICAgICAgICBQb29tYTo6QnJpY2tCYXNlX190bV9fOV9Y Q2lMXzFfMjo6X19jdCggKGJvb2wpKSBbMjI5XQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAg ICAgIDEvMSAgICAgICAgICAgbWFpbiBbMl0KWzI0N10gICAgMC4wICAgIDAuMDAgICAgMC4w MCAgICAgICAxICAgICAgICAgQUJDSW5DOjpfX2N0KHZvaWQpIFsyNDddCiAgICAgICAgICAg ICAgICAwLjAwICAgIDAuMDAgICAgICAgMy8xMiAgICAgICAgICBQb29tYTo6QnJpY2tCYXNl X190bV9fOV9YQ2lMXzFfMjo6X19jdCggKGJvb2wpKSBbMjI5XQotLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgICAgICAgICAgMC4wMCAg ICAwLjAwICAgICAgIDEvMSAgICAgICAgICAgbWFpbiBbMl0KWzI0OF0gICAgMC4wICAgIDAu MDAgICAgMC4wMCAgICAgICAxICAgICAgICAgQmVuY2htYXJrOjpfX2N0KGludCwgY2hhciAq KiwgY2hhciBjb25zdCAqLCBpbnQpIFsyNDhdCiAgICAgICAgICAgICAgICAwLjAwICAgIDAu MDAgICAgICAgNC80ICAgICAgICAgICBQb29tYTo6aW50QXJndW1lbnQoaW50LCBjaGFyICoq LCBpbnQsIGludCAmKSBbNDBdCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAg MS8yICAgICAgICAgICBJbmZvcm06Ol9fY3QoY2hhciBjb25zdCAqLCBpbnQpIFsyMzhdCiAg ICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgMS8xICAgICAgICAgICBpbnNlcnRf YXV4X19RMl8zc3RkNDN2ZWN0b3JfX3RtX18yOV9pUTJfM3N0ZDE4YWxsb2NhdG9yX190bV9f Ml9pRlEyX1oyWjdwb2ludGVyUkNaMVpfdiBbNTddCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAg ICAgICAgMS8xICAgICAgICAgICBfX0NQUjE5MV9faW5zZXJ0X2F1eF9fUTJfM3N0ZDE0N3Zl Y3Rvcl9fdG1fXzEzMl9RMl8zc3RkNDN2ZWN0b3JfX3RtX18yOV9kUTJfM3N0ZDE4YWxsb2Nh dG9yX190bV9fMl9kUTJfM3N0ZDcwYWxsb2NhdG9yX190bV9fNTNfUTJfM3N0ZEo0NUpGUTJf WjJaN3BvaW50ZXJSQ1oxWl92IFsyNDNdClsyNDldICAgIDAuMCAgICAwLjAwICAgIDAuMDAg ICAgICAgMSAgICAgICAgIHN0ZDo6dmVjdG9yX190bV9fMjlfZFEyXzNzdGQxOGFsbG9jYXRv cl9fdG1fXzJfZDo6X19jdCggKHN0ZDo6dmVjdG9yX190bV9fN19aMVpaMlogY29uc3QgJikp IFsyNDldCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t CiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgMS8xICAgICAgICAgICBfX3N0 aV9fUG9vbWFfY21wbF9jcHBfZjAwOTQ1MGQgWzI2OF0KWzI1MF0gICAgMC4wICAgIDAuMDAg ICAgMC4wMCAgICAgICAxICAgICAgICAgUG9vbWE6OlN0YXRpc3RpY3M6Ol9fY3QoICh2b2lk KSkgWzI1MF0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICAxLzEgICAgICAgICAgIFBv b21hOjppbml0aWFsaXplKGludCAmLCBjaGFyICoqJiwgYm9vbCwgYm9vbCwgYm9vbCkgWzU2 XQpbMjUxXSAgICAwLjAgICAgMC4wMCAgICAwLjAwICAgICAgIDEgICAgICAgICBQb29tYTo6 T3B0aW9uczo6X19jdCggKGludCAmLCBjaGFyICoqKSkgWzI1MV0KICAgICAgICAgICAgICAg IDAuMDAgICAgMC4wMCAgICAgICAxLzIgICAgICAgICAgIFBvb21hOjpPcHRpb25zOjpyZXNl dCggKHZvaWQpKSBbNDhdCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgMS8x ICAgICAgICAgICBQb29tYTo6T3B0aW9uczo6cGFyc2UoIChpbnQgJiwgY2hhciAqKiYpKSBb NTldCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAg ICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgMS8xICAgICAgICAgICBfX3N0aV9f UG9vbWFfY21wbF9jcHBfZjAwOTQ1MGQgWzI2OF0KWzI1Ml0gICAgMC4wICAgIDAuMDAgICAg MC4wMCAgICAgICAxICAgICAgICAgUG9vbWE6Ok9wdGlvbnM6Ol9fY3QoICh2b2lkKSkgWzI1 Ml0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICAxLzIgICAgICAgICAgIFBv b21hOjpPcHRpb25zOjpyZXNldCggKHZvaWQpKSBbNDhdCi0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAgICAwLjAwICAgIDAu MDAgICAgICAgMS8xICAgICAgICAgICBCZW5jaG1hcms6Ol9fZHQodm9pZCkgWzI1OV0KWzI1 M10gICAgMC4wICAgIDAuMDAgICAgMC4wMCAgICAgICAxICAgICAgICAgQUJDSW5QMl9fdG1f XzE1XzVCcmlja1hDYkxfMV8wOjpfX2R0KHZvaWQpIFsyNTNdCiAgICAgICAgICAgICAgICAw LjAwICAgIDAuMDAgICAgICAgMy85MTIgICAgICAgICBFbmdpbmVfX3BzX18xNF9YWjFaWjJa NUJyaWNrX190bV9fMTBfWENpTF8xXzJkOjpfX2R0KHZvaWQpIFsyMThdCi0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAgICAw LjAwICAgIDAuMDAgICAgICAgMS8xICAgICAgICAgICBCZW5jaG1hcms6Ol9fZHQodm9pZCkg WzI1OV0KWzI1NF0gICAgMC4wICAgIDAuMDAgICAgMC4wMCAgICAgICAxICAgICAgICAgQUJD SW5QMl9fdG1fXzE1XzVCcmlja1hDYkxfMV8xOjpfX2R0KHZvaWQpIFsyNTRdCi0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAg ICAwLjAwICAgIDAuMDAgICAgICAgMS8xICAgICAgICAgICBCZW5jaG1hcms6Ol9fZHQodm9p ZCkgWzI1OV0KWzI1NV0gICAgMC4wICAgIDAuMDAgICAgMC4wMCAgICAgICAxICAgICAgICAg QUJDSW5DcHBUcmFuX190bV9fMTVfNUJyaWNrWENiTF8xXzA6Ol9fZHQodm9pZCkgWzI1NV0K ICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICAzLzkxMiAgICAgICAgIEVuZ2lu ZV9fcHNfXzE0X1haMVpaMlo1QnJpY2tfX3RtX18xMF9YQ2lMXzFfMmQ6Ol9fZHQodm9pZCkg WzIxOF0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0K ICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICAxLzEgICAgICAgICAgIEJlbmNo bWFyazo6X19kdCh2b2lkKSBbMjU5XQpbMjU2XSAgICAwLjAgICAgMC4wMCAgICAwLjAwICAg ICAgIDEgICAgICAgICBBQkNJblAyX190bV9fMjhfMTdDb21wcmVzc2libGVCcmlja1hDYkxf MV8wOjpfX2R0KHZvaWQpIFsyNTZdCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAg ICAgMy8zICAgICAgICAgICBFbmdpbmVfX3BzX18yN19YWjFaWjJaMTdDb21wcmVzc2libGVC cmlja19fdG1fXzEwX1hDaUxfMV8yZDo6X19kdCh2b2lkKSBbMjM1XQotLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgICAgICAgICAgMC4w MCAgICAwLjAwICAgICAgIDEvMSAgICAgICAgICAgQmVuY2htYXJrOjpfX2R0KHZvaWQpIFsy NTldClsyNTddICAgIDAuMCAgICAwLjAwICAgIDAuMDAgICAgICAgMSAgICAgICAgIEFCQ0lu UDJfX3RtX18yOF8xN0NvbXByZXNzaWJsZUJyaWNrWENiTF8xXzE6Ol9fZHQodm9pZCkgWzI1 N10KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAg ICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICAxLzEgICAgICAgICAgIEJlbmNobWFy azo6X19kdCh2b2lkKSBbMjU5XQpbMjU4XSAgICAwLjAgICAgMC4wMCAgICAwLjAwICAgICAg IDEgICAgICAgICBBQkNJbkM6Ol9fZHQodm9pZCkgWzI1OF0KICAgICAgICAgICAgICAgIDAu MDAgICAgMC4wMCAgICAgICAzLzkxMiAgICAgICAgIEVuZ2luZV9fcHNfXzE0X1haMVpaMlo1 QnJpY2tfX3RtX18xMF9YQ2lMXzFfMmQ6Ol9fZHQodm9pZCkgWzIxOF0KLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAgICAgICAgIDAu MDAgICAgMC4wMCAgICAgICAxLzEgICAgICAgICAgIG1haW4gWzJdClsyNTldICAgIDAuMCAg ICAwLjAwICAgIDAuMDAgICAgICAgMSAgICAgICAgIEJlbmNobWFyazo6X19kdCh2b2lkKSBb MjU5XQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAgIDIvMiAgICAgICAgICAg X19DUFI5M19fX19kdF9fUTJfM3N0ZDc2dmVjdG9yX190bV9fNjJfUDE0SW1wbGVtZW50YXRp b25RMl8zc3RkMzVhbGxvY2F0b3JfX3RtX18xOF9QSjMxSkZ2IFsyMzZdCiAgICAgICAgICAg ICAgICAwLjAwICAgIDAuMDAgICAgICAgMi8xMjU4ICAgICAgICBzdGQ6OmJhc2ljX3N0cmlu Z19fdG1fXzU4X2NRMl8zc3RkMjBjaGFyX3RyYWl0c19fdG1fXzJfY1EyXzNzdGQxOGFsbG9j YXRvcl9fdG1fXzJfYzo6X19kdCggKHZvaWQpKSBbMjE0XQogICAgICAgICAgICAgICAgMC4w MCAgICAwLjAwICAgICAgIDEvMSAgICAgICAgICAgQUJDSW5QMl9fdG1fXzI4XzE3Q29tcHJl c3NpYmxlQnJpY2tYQ2JMXzFfMTo6X19kdCh2b2lkKSBbMjU3XQogICAgICAgICAgICAgICAg MC4wMCAgICAwLjAwICAgICAgIDEvMSAgICAgICAgICAgQUJDSW5QMl9fdG1fXzE1XzVCcmlj a1hDYkxfMV8xOjpfX2R0KHZvaWQpIFsyNTRdCiAgICAgICAgICAgICAgICAwLjAwICAgIDAu MDAgICAgICAgMS8xICAgICAgICAgICBBQkNJblAyX190bV9fMjhfMTdDb21wcmVzc2libGVC cmlja1hDYkxfMV8wOjpfX2R0KHZvaWQpIFsyNTZdCiAgICAgICAgICAgICAgICAwLjAwICAg IDAuMDAgICAgICAgMS8xICAgICAgICAgICBBQkNJblAyX190bV9fMTVfNUJyaWNrWENiTF8x XzA6Ol9fZHQodm9pZCkgWzI1M10KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAg ICAxLzEgICAgICAgICAgIEFCQ0luQ3BwVHJhbl9fdG1fXzE1XzVCcmlja1hDYkxfMV8wOjpf X2R0KHZvaWQpIFsyNTVdCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgMS8x ICAgICAgICAgICBBQkNJbkM6Ol9fZHQodm9pZCkgWzI1OF0KICAgICAgICAgICAgICAgIDAu MDAgICAgMC4wMCAgICAgICAxLzEgICAgICAgICAgIF9fQ1BSMTY1X19fX2R0X19RMl8zc3Rk MTQ3dmVjdG9yX190bV9fMTMyX1EyXzNzdGQ0M3ZlY3Rvcl9fdG1fXzI5X2RRMl8zc3RkMThh bGxvY2F0b3JfX3RtX18yX2RRMl8zc3RkNzBhbGxvY2F0b3JfX3RtX181M19RMl8zc3RkSjM5 SkZ2IFsyNDFdCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgMS8xICAgICAg ICAgICBfX0NQUjIzNl9fX19kdF9fUTJfM3N0ZDIxOHZlY3Rvcl9fdG1fXzIwM19RMl8zc3Rk NzhiYXNpY19zdHJpbmdfX3RtX181OF9jUTJfM3N0ZDIwY2hhcl90cmFpdHNfX3RtX18yX2NR Ml8zc3RkMThhbGxvY2F0b3JfX3RtX18yX2NRMl8zc3RkMTA1YWxsb2NhdG9yX190bV9fODhf UTJfM3N0ZEozOUpGdiBbMjQ0XQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAg IDEvMSAgICAgICAgICAgc3RkOjp2ZWN0b3JfX3RtX18yOV9pUTJfM3N0ZDE4YWxsb2NhdG9y X190bV9fMl9pOjpfX2R0KCAodm9pZCkpIFsyNjBdCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAg ICAgICAgMS8xICAgICAgICAgICBCZW5jaG1hcms6Ol9fZHQodm9pZCkgWzI1OV0KWzI2MF0g ICAgMC4wICAgIDAuMDAgICAgMC4wMCAgICAgICAxICAgICAgICAgc3RkOjp2ZWN0b3JfX3Rt X18yOV9pUTJfM3N0ZDE4YWxsb2NhdG9yX190bV9fMl9pOjpfX2R0KCAodm9pZCkpIFsyNjBd Ci0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAg ICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgMS8xICAgICAgICAgICBCZW5jaG1hcms6 OnJ1bkltcGxlbWVudGF0aW9uKEltcGxlbWVudGF0aW9uICosIGludCkgWzNdClsyNjFdICAg IDAuMCAgICAwLjAwICAgIDAuMDAgICAgICAgMSAgICAgICAgIHN0ZDo6dmVjdG9yX19wc19f NV9iWjFaX190bV9fMjhfUTJfM3N0ZDE4YWxsb2NhdG9yX190bV9fMl9iOjpfX2R0KCAodm9p ZCkpIFsyNjFdCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgMS8xICAgICAgICAgICBQ b29tYTo6aW5pdGlhbGl6ZShpbnQgJiwgY2hhciAqKiYsIGJvb2wsIGJvb2wsIGJvb2wpIFs1 Nl0KWzI2Ml0gICAgMC4wICAgIDAuMDAgICAgMC4wMCAgICAgICAxICAgICAgICAgUG9vbWE6 Ok9wdGlvbnM6Ol9fZHQoICh2b2lkKSkgWzI2Ml0KICAgICAgICAgICAgICAgIDAuMDAgICAg MC4wMCAgICAgICAyLzEyNTggICAgICAgIHN0ZDo6YmFzaWNfc3RyaW5nX190bV9fNThfY1Ey XzNzdGQyMGNoYXJfdHJhaXRzX190bV9fMl9jUTJfM3N0ZDE4YWxsb2NhdG9yX190bV9fMl9j OjpfX2R0KCAodm9pZCkpIFsyMTRdCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgMS8x ICAgICAgICAgICBfX2RvX2dsb2JhbF9jdG9yc19hdXggWzM3MF0KWzI2M10gICAgMC4wICAg IDAuMDAgICAgMC4wMCAgICAgICAxICAgICAgICAgX19zdGlfX0FCQ19jcHBfbWFpbiBbMjYz XQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAgIDIvMiAgICAgICAgICAgUG9v bDo6X19jdCh1bnNpZ25lZCBpbnQpIFsyMzddCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAg ICAgMS8xICAgICAgICAgICBfX2RvX2dsb2JhbF9jdG9yc19hdXggWzM3MF0KWzI2NF0gICAg MC4wICAgIDAuMDAgICAgMC4wMCAgICAgICAxICAgICAgICAgX19zdGlfX0JlbmNobWFya19j bXBsX2NwcF8yZWVjN2E3NyBbMjY0XQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAgIDEv MSAgICAgICAgICAgX19kb19nbG9iYWxfY3RvcnNfYXV4IFszNzBdClsyNjVdICAgIDAuMCAg ICAwLjAwICAgIDAuMDAgICAgICAgMSAgICAgICAgIF9fc3RpX19JbmZvcm1fY21wbF9jcHBf YWVhMWM0MTIgWzI2NV0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICAxLzEgICAgICAg ICAgIF9fZG9fZ2xvYmFsX2N0b3JzX2F1eCBbMzcwXQpbMjY2XSAgICAwLjAgICAgMC4wMCAg ICAwLjAwICAgICAgIDEgICAgICAgICBfX3N0aV9fT3B0aW9uc19jbXBsX2NwcF9lOGM1ZDc4 OCBbMjY2XQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAgIDEvMSAgICAgICAgICAgX19k b19nbG9iYWxfY3RvcnNfYXV4IFszNzBdClsyNjddICAgIDAuMCAgICAwLjAwICAgIDAuMDAg ICAgICAgMSAgICAgICAgIF9fc3RpX19QQXNzZXJ0X2NtcGxfY3BwXzY0ODE1OTU3IFsyNjdd Ci0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAg ICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAgMS8xICAgICAgICAgICBfX2RvX2dsb2Jh bF9jdG9yc19hdXggWzM3MF0KWzI2OF0gICAgMC4wICAgIDAuMDAgICAgMC4wMCAgICAgICAx ICAgICAgICAgX19zdGlfX1Bvb21hX2NtcGxfY3BwX2YwMDk0NTBkIFsyNjhdCiAgICAgICAg ICAgICAgICAwLjAwICAgIDAuMDAgICAgICAxMi8yNyAgICAgICAgICBfX2N0X19RMl8zc3Rk NzhiYXNpY19zdHJpbmdfX3RtX181OF9jUTJfM3N0ZDIwY2hhcl90cmFpdHNfX3RtX18yX2NR Ml8zc3RkMThhbGxvY2F0b3JfX3RtX18yX2NGUENaMVpSQ1ozWiBbMjI3XQogICAgICAgICAg ICAgICAgMC4wMCAgICAwLjAwICAgICAgMTIvMTIgICAgICAgICAgX19jdF9fUTJfM3N0ZDc4 YmFzaWNfc3RyaW5nX190bV9fNThfY1EyXzNzdGQyMGNoYXJfdHJhaXRzX190bV9fMl9jUTJf M3N0ZDE4YWxsb2NhdG9yX190bV9fMl9jRlJDUTJfM3N0ZDMwYmFzaWNfc3RyaW5nX190bV9f MTBfWjFaWjJaWjNaUTJfWjNaOXNpemVfdHlwZVQyUkNaM1ogWzIyOF0KICAgICAgICAgICAg ICAgIDAuMDAgICAgMC4wMCAgICAgIDEyLzEyNTggICAgICAgIHN0ZDo6YmFzaWNfc3RyaW5n X190bV9fNThfY1EyXzNzdGQyMGNoYXJfdHJhaXRzX190bV9fMl9jUTJfM3N0ZDE4YWxsb2Nh dG9yX190bV9fMl9jOjpfX2R0KCAodm9pZCkpIFsyMTRdCiAgICAgICAgICAgICAgICAwLjAw ICAgIDAuMDAgICAgICAgMy8zICAgICAgICAgICBJbmZvcm06Ol9fY3QoY2hhciBjb25zdCAq LCBzdGQ6OmJhc2ljX29zdHJlYW1fX3RtX18zMV9jUTJfM3N0ZDIwY2hhcl90cmFpdHNfX3Rt X18yX2MgJiwgaW50KSBbMjM0XQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAwICAgICAg IDMvMyAgICAgICAgICAgX19DUFIxMzdfX2luc2VydF9hdXhfX1EyXzNzdGQ5NHZlY3Rvcl9f dG1fXzgwX1BRMl81UG9vbWExNFN0YXRpc3RpY3NEYXRhUTJfM3N0ZDQ0YWxsb2NhdG9yX190 bV9fMjdfUFEyX0o0MEpKNDZKRlEyX1oyWjdwb2ludGVyUkNaMVpfdiBbMjMzXQogICAgICAg ICAgICAgICAgMC4wMCAgICAwLjAwICAgICAgIDEvMiAgICAgICAgICAgSW5mb3JtOjpfX2N0 KGNoYXIgY29uc3QgKiwgaW50KSBbMjM4XQogICAgICAgICAgICAgICAgMC4wMCAgICAwLjAw ICAgICAgIDEvMSAgICAgICAgICAgUG9vbWE6Ok9wdGlvbnM6Ol9fY3QoICh2b2lkKSkgWzI1 Ml0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4wMCAgICAgICAxLzEgICAgICAgICAgIFBv b21hOjpTdGF0aXN0aWNzOjpfX2N0KCAodm9pZCkpIFsyNTBdCi0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAgICAwLjAwICAg IDAuMDAgICAgICAgMS8xICAgICAgICAgICBfX2RvX2dsb2JhbF9jdG9yc19hdXggWzM3MF0K WzI2OV0gICAgMC4wICAgIDAuMDAgICAgMC4wMCAgICAgICAxICAgICAgICAgX19zdGlfX1N0 YXRpc3RpY3NfY21wbF9jcHBfOGE1MDBhMWIgWzI2OV0KLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAgICAgICAgIDAuMDAgICAgMC4w MCAgICAgICAxLzEgICAgICAgICAgIF9fZG9fZ2xvYmFsX2N0b3JzX2F1eCBbMzcwXQpbMjcw XSAgICAwLjAgICAgMC4wMCAgICAwLjAwICAgICAgIDEgICAgICAgICBfX3N0aV9fVGVzdGVy X2NtcGxfY3BwX2FmMTAxZjNjIFsyNzBdCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAgICAwLjAwICAgIDAuMDAgICAgICAg MS8xICAgICAgICAgICBfX2RvX2dsb2JhbF9jdG9yc19hdXggWzM3MF0KWzI3MV0gICAgMC4w ICAgIDAuMDAgICAgMC4wMCAgICAgICAxICAgICAgICAgX19zdGlfX1VuaXF1ZV9jbXBsX2Nw cF9hZGYxYjA2OSBbMjcxXQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLQoKIFRoaXMgdGFibGUgZGVzY3JpYmVzIHRoZSBjYWxsIHRyZWUgb2YgdGhl IHByb2dyYW0sIGFuZCB3YXMgc29ydGVkIGJ5CiB0aGUgdG90YWwgYW1vdW50IG9mIHRpbWUg c3BlbnQgaW4gZWFjaCBmdW5jdGlvbiBhbmQgaXRzIGNoaWxkcmVuLgoKIEVhY2ggZW50cnkg aW4gdGhpcyB0YWJsZSBjb25zaXN0cyBvZiBzZXZlcmFsIGxpbmVzLiAgVGhlIGxpbmUgd2l0 aCB0aGUKIGluZGV4IG51bWJlciBhdCB0aGUgbGVmdCBoYW5kIG1hcmdpbiBsaXN0cyB0aGUg Y3VycmVudCBmdW5jdGlvbi4KIFRoZSBsaW5lcyBhYm92ZSBpdCBsaXN0IHRoZSBmdW5jdGlv bnMgdGhhdCBjYWxsZWQgdGhpcyBmdW5jdGlvbiwKIGFuZCB0aGUgbGluZXMgYmVsb3cgaXQg bGlzdCB0aGUgZnVuY3Rpb25zIHRoaXMgb25lIGNhbGxlZC4KIFRoaXMgbGluZSBsaXN0czoK ICAgICBpbmRleAlBIHVuaXF1ZSBudW1iZXIgZ2l2ZW4gdG8gZWFjaCBlbGVtZW50IG9mIHRo ZSB0YWJsZS4KCQlJbmRleCBudW1iZXJzIGFyZSBzb3J0ZWQgbnVtZXJpY2FsbHkuCgkJVGhl IGluZGV4IG51bWJlciBpcyBwcmludGVkIG5leHQgdG8gZXZlcnkgZnVuY3Rpb24gbmFtZSBz bwoJCWl0IGlzIGVhc2llciB0byBsb29rIHVwIHdoZXJlIHRoZSBmdW5jdGlvbiBpbiB0aGUg dGFibGUuCgogICAgICUgdGltZQlUaGlzIGlzIHRoZSBwZXJjZW50YWdlIG9mIHRoZSBgdG90 YWwnIHRpbWUgdGhhdCB3YXMgc3BlbnQKCQlpbiB0aGlzIGZ1bmN0aW9uIGFuZCBpdHMgY2hp bGRyZW4uICBOb3RlIHRoYXQgZHVlIHRvCgkJZGlmZmVyZW50IHZpZXdwb2ludHMsIGZ1bmN0 aW9ucyBleGNsdWRlZCBieSBvcHRpb25zLCBldGMsCgkJdGhlc2UgbnVtYmVycyB3aWxsIE5P VCBhZGQgdXAgdG8gMTAwJS4KCiAgICAgc2VsZglUaGlzIGlzIHRoZSB0b3RhbCBhbW91bnQg b2YgdGltZSBzcGVudCBpbiB0aGlzIGZ1bmN0aW9uLgoKICAgICBjaGlsZHJlbglUaGlzIGlz IHRoZSB0b3RhbCBhbW91bnQgb2YgdGltZSBwcm9wYWdhdGVkIGludG8gdGhpcwoJCWZ1bmN0 aW9uIGJ5IGl0cyBjaGlsZHJlbi4KCiAgICAgY2FsbGVkCVRoaXMgaXMgdGhlIG51bWJlciBv ZiB0aW1lcyB0aGUgZnVuY3Rpb24gd2FzIGNhbGxlZC4KCQlJZiB0aGUgZnVuY3Rpb24gY2Fs bGVkIGl0c2VsZiByZWN1cnNpdmVseSwgdGhlIG51bWJlcgoJCW9ubHkgaW5jbHVkZXMgbm9u LXJlY3Vyc2l2ZSBjYWxscywgYW5kIGlzIGZvbGxvd2VkIGJ5CgkJYSBgKycgYW5kIHRoZSBu dW1iZXIgb2YgcmVjdXJzaXZlIGNhbGxzLgoKICAgICBuYW1lCVRoZSBuYW1lIG9mIHRoZSBj dXJyZW50IGZ1bmN0aW9uLiAgVGhlIGluZGV4IG51bWJlciBpcwoJCXByaW50ZWQgYWZ0ZXIg aXQuICBJZiB0aGUgZnVuY3Rpb24gaXMgYSBtZW1iZXIgb2YgYQoJCWN5Y2xlLCB0aGUgY3lj bGUgbnVtYmVyIGlzIHByaW50ZWQgYmV0d2VlbiB0aGUKCQlmdW5jdGlvbidzIG5hbWUgYW5k From JimC at proximation.com Fri Aug 24 23:15:40 2001 From: JimC at proximation.com (James Crotinger) Date: Fri, 24 Aug 2001 17:15:40 -0600 Subject: [pooma-dev] Profiling POOMA: How to? (1/3) Message-ID: Gaby, Microsoft Outlook has no idea what your attachments were. Here is a snippet of what I received: ---------------------------------------------------------------------- Hmm, I'm embarrased because I don't (yet) have any idea of why you're seeing that behaviour. Which parameters did you run the ABC test with? I tried the following to see whether I'll get a core dump ./ABC --run-impls 2 --sim-params 1 3 100 and the test completed fine, but I strongly suspect I must be testing with the wrong parameters (the "nan" part is a bit intriguing). The output is in ABC.out and the profiling information (flat profile and call graph) is in ABC.prof, all attached. I'm using GNU gprof-2.10.91 on a linux box. Thanks, -- Gaby --Multipart_Fri_Aug_24_02:46:57_2001-1 Content-Type: application/octet-stream Content-Disposition: attachment; filename="ABC.out" Content-Transfer-Encoding: base64 Ci4vQUJDIEJlbmNobWFyawotLS0tLS0tLS0tLS0tLS0KUnVubmluZyBzYW1wbGUgIzEgZm9y IFBvb21hSUkgQnJpY2sgSW1wbGVtZW50YXRpb246CiAgTiA9IDEuLi4KICAgIENvcnJlY3Ru ZXNzIHRlc3QgdmFsdWUgZm9yIE4gPSAxIGlzIG5hbi4KICBOID0gMS4uLgogICAgQ29ycmVj ------------------------------------------------------------------------- Regarding your questions, it wasn't ABC that crashed, it was gprof when I ran it on ABC's gmon.out file (or whatever it is called). The nan's you're seeing for the above args are probably related to the input parameters indirectly - the "correctness value" that is printed out for this test is the value at the point "N/2,N/2". For reasons that escape me, the domain for the arrays in this test is [1..N]x[1..N]. So if N == 1, N/2 give 0 and this results in the correctness calculation trying to read a(0,0), which is out-of-bounds. (This would be caught with bounds checking on, if we still have such a thing 8-). The upshot is that N == 1 is a bad value. Also, anything less than N == 10 will not work with the default number of patches for the UMP tests since they try to decompose into npatch x npatch patches, which will fail if N < npatch. Anyway, I just ran % ABC --run-impls 2 --sim-params 100 0 1 % gprof ABC >&gprof.out and gprof has now used up 4 minutes of CPU time and its image size is 1.5 GB. I suspect it will crash soon. 8-) I'm using GNU gprof 2.10.91 as well. I did compile with KCC and full optimization - does gprof now work in that situation? Oh, yes, gprof finally died after 10+ minutes of CPU time - "Cannot allocate 3087007742 bytes...". Jim > -----Original Message----- > From: Gabriel Dos Reis [mailto:gdr at codesourcery.com] > Sent: Thursday, August 23, 2001 6:47 PM > To: pooma-dev at pooma.codesourcery.com > Subject: Re: [pooma-dev] Profiling POOMA: How to? (1/3) > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From oldham at codesourcery.com Mon Aug 27 19:49:19 2001 From: oldham at codesourcery.com (Jeffrey Oldham) Date: Mon, 27 Aug 2001 12:49:19 -0700 Subject: Tips for Using Irix and KCC Message-ID: <200108271949.MAA12272@oz.codesourcery.com> Here are some tips I learned when working with Pooma on LANL's n02's Irix6.5 machine. 1) Because of KCC's template instantiation implementation, do not link in parallel in the same directory. Because instantiation uses similarly named files, parallel linking conflicts. 2) To debug KCC, use gdb patched for KCC. See http://www.kai.com/C_plus_plus/download/gdb-download.html. Also be sure to add set demangle-style edg to your ~/.gdbinit to ensure that variables can be referenced without using mangled names. Thanks, Jeffrey D. Oldham oldham at codesourcery.com From wdn at lanl.gov Tue Aug 28 17:09:52 2001 From: wdn at lanl.gov (Dave Nystrom) Date: Tue, 28 Aug 2001 11:09:52 -0600 Subject: [pooma-dev] Tips for Using Irix and KCC In-Reply-To: <200108271949.MAA12272@oz.codesourcery.com> References: <200108271949.MAA12272@oz.codesourcery.com> Message-ID: <15243.53344.747426.724704@saltydog.lanl.gov> Jeffrey Oldham writes: > > Here are some tips I learned when working with Pooma on LANL's n02's > Irix6.5 machine. > > 1) Because of KCC's template instantiation implementation, do not link > in parallel in the same directory. Because instantiation uses > similarly named files, parallel linking conflicts. What version of KCC are you using? KCC-4.0f is available and is supposed to fix this problem - if it does not, then we need to report this so Kuck can continue working on the problem. Dave > 2) To debug KCC, use gdb patched for KCC. See > http://www.kai.com/C_plus_plus/download/gdb-download.html. Also be > sure to add > set demangle-style edg > to your ~/.gdbinit to ensure that variables can be referenced > without using mangled names. > > Thanks, > Jeffrey D. Oldham > oldham at codesourcery.com > From scotth at proximation.com Tue Aug 28 19:52:13 2001 From: scotth at proximation.com (Scott Haney) Date: Tue, 28 Aug 2001 13:52:13 -0600 Subject: Merging newfield_revision Message-ID: Hi everyone, Those working on the newfield_revision branch - please get check-in whatever outstanding changes you have by NOON PST on 8/29. I would like to merge this branch into the main trunk ASAP. Here is what is going to happen specifically: (1) Jeffrey* creates a new branch for the Blanca team to work with through 10/1. This will allow them to get bug-fixes without having to buy into the entire newfield_revision. This branch will not be merged. We'll just be sure to make changes (2) Jeffrey* will merge newfield_revision branch back to the main trunk (3) We will remove the BConds, Geometry, and Meshes. Then, we move the NewField files to Field and remove NewField. (4) In the Pooma directory, NewFields.h -> Fields.h. (5) All tests, examples, and benchmarks are changed to use NewField. (6) For good measure, I'd like to remove the IO directory since it isn't going to be used or further developed. Let me know ASAP if there are any strenuous objections to this plan. Scott *Jeffrey bravely volunteered to do this. :-) -- Scott W. Haney Development Manager Proximation LLC 2960 Rodeo Park Drive West Santa Fe, NM 87505 Voice: 505-424-3809 x101 FAX: 505-438-4161 From JimC at proximation.com Tue Aug 28 20:25:14 2001 From: JimC at proximation.com (James Crotinger) Date: Tue, 28 Aug 2001 14:25:14 -0600 Subject: [pooma-dev] Merging newfield_revision Message-ID: > -----Original Message----- > From: Scott Haney [mailto:scotth at proximation.com] > Sent: Tuesday, August 28, 2001 1:52 PM > To: pooma-dev at pooma.codesourcery.com > Subject: [pooma-dev] Merging newfield_revision > > (3) We will remove the BConds, Geometry, and Meshes. Then, we > move the > NewField files to Field and remove NewField. It would probably be best to do this in the repository itself - i.e. to move the ,v files from the NewField directory to the Field directory. Otherwise we'll lose the CVS history. Jim -------------- next part -------------- An HTML attachment was scrubbed... URL: From stephens at proximation.com Tue Aug 28 21:43:06 2001 From: stephens at proximation.com (Stephen Smith) Date: Tue, 28 Aug 2001 15:43:06 -0600 Subject: field engine patch Message-ID: This patch implements the subField(m,c) material(m) center(c) functions for fields with expressions. Stephen <<28Aug.fieldengine.1.patch>> -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: 28Aug.fieldengine.1.patch Type: application/octet-stream Size: 11091 bytes Desc: not available URL: From oldham at codesourcery.com Wed Aug 29 16:31:10 2001 From: oldham at codesourcery.com (Jeffrey Oldham) Date: Wed, 29 Aug 2001 09:31:10 -0700 Subject: [newfield_revision Patch] Finish FieldOffset.h Comment Message-ID: <20010829093110.A9601@codesourcery.com> Fix a comment that ended in the middle of the senten 2001-08-29 Jeffrey D. Oldham * FieldOffset.h: Finish comment. Applied to newfield_revision branch Approved by Stephen Smith Tested: not since it is in a comment Thanks, Jeffrey D. Oldham oldham at codesourcery.com -------------- next part -------------- Index: FieldOffset.h =================================================================== RCS file: /home/pooma/Repository/r2/src/NewField/Attic/FieldOffset.h,v retrieving revision 1.1.2.5 diff -c -p -r1.1.2.5 FieldOffset.h *** FieldOffset.h 2001/08/16 18:26:40 1.1.2.5 --- FieldOffset.h 2001/08/29 02:52:43 *************** class FieldOffsetList; *** 82,88 **** // // Given a field f, a Loc loc, and a field offset (offset,num), a // field value can be obtained. Since each value specified by the ! // field's centering is stored in a separate subfield, the notation // //----------------------------------------------------------------------------- --- 82,89 ---- // // Given a field f, a Loc loc, and a field offset (offset,num), a // field value can be obtained. Since each value specified by the ! // field's centering is stored in a separate subfield, the offset is ! // used to specify the appropriate subfield. // //----------------------------------------------------------------------------- From oldham at codesourcery.com Wed Aug 29 16:34:45 2001 From: oldham at codesourcery.com (Jeffrey Oldham) Date: Wed, 29 Aug 2001 09:34:45 -0700 Subject: [newfield_revision Patch] Add MultiArg4 to Functions/MultiArg.h Message-ID: <20010829093445.B9601@codesourcery.com> Apparently, MultiArg4 was inadvertently omitted from src/Functions/MultiArg.h. 2001-08-29 Jeffrey D. Oldham * MultiArg.h (MultiArg4): New structure analogous to MultiArg5. (applyMultiArg(MultiArg4, ...)): New function corresponding to MultiArg4. Tested: compiled StatigraphicFlow.cpp with Linux gcc 3.0.1 using this Approved by: Stephen Smith Applied to: newfield_revision branch Thanks, Jeffrey D. Oldham oldham at codesourcery.com -------------- next part -------------- Index: MultiArg.h =================================================================== RCS file: /home/pooma/Repository/r2/src/Functions/MultiArg.h,v retrieving revision 1.5 diff -c -p -r1.5 MultiArg.h *** MultiArg.h 2001/03/28 22:33:16 1.5 --- MultiArg.h 2001/08/29 02:47:38 *************** struct MultiArg3 *** 270,275 **** --- 270,299 ---- A3 a3_m; }; + template + struct MultiArg4 + { + enum { size = 4 }; + + MultiArg4(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4) + : a1_m(a1), a2_m(a2), a3_m(a3), a4_m(a4) + { + } + + template + typename View1, Dom>::Type_t + operator()(Dom &dom) const + { + typedef typename View1, Dom>::Type_t Ret_t; + return Ret_t(a1_m(dom), a2_m(dom), a3_m(dom), a4_m(dom)); + } + + A1 a1_m; + A2 a2_m; + A3 a3_m; + A4 a4_m; + }; + template struct MultiArg5 { *************** void applyMultiArg(const MultiArg3 + void applyMultiArg(const MultiArg4 &node, + const Function &f, + const std::vector &condition) + { + f(node.a1_m, condition[0]); + f(node.a2_m, condition[1]); + f(node.a3_m, condition[2]); + f(node.a4_m, condition[3]); } template From mark at codesourcery.com Wed Aug 29 17:00:27 2001 From: mark at codesourcery.com (Mark Mitchell) Date: Wed, 29 Aug 2001 10:00:27 -0700 Subject: POOMA1 regression test for O2K64 TEMPLATEINST OPTIMIZE (fwd) Message-ID: <79810000.999104427@warlock.codesourcery.com> Graham -- I'm not sure what to make of this message; I haven't checked in any POOMA code in a long time. Are you referring to a POOMA checkin, or a GCC checkin? POOMA development is now being coordinate on the pooma-dev at pooma.codesourcery.com mailing list to which I've forwarded your message. I think I'm not understanding what's going on. Thanks, ---------- Forwarded Message ---------- Date: Wednesday, August 29, 2001 04:03:08 AM -0600 From: "gam at acl.lanl.gov" To: "mitchell at acl.lanl.gov" Subject: POOMA1 regression test for O2K64 TEMPLATEINST OPTIMIZE The POOMA regression test failed this morning. Please inspect the codes you checked in recently and make sure they are accurate. The detailed output of this regression test is in /home/pooma/testing/pooma1/history/report.08_29_2001:03:00 and /home/pooma/testing/pooma1/history/trace.08_29_2001:03:00 files. Graham Mark CIC-12 Scientific Software Engineering Los Alamos National Laboratory (505)667-8147 ---------- End Forwarded Message ---------- -- Mark Mitchell mark at codesourcery.com CodeSourcery, LLC http://www.codesourcery.com From wdn at lanl.gov Wed Aug 29 17:01:48 2001 From: wdn at lanl.gov (Dave Nystrom) Date: Wed, 29 Aug 2001 11:01:48 -0600 Subject: [pooma-dev] POOMA1 regression test for O2K64 TEMPLATEINST OPTIMIZE (fwd) In-Reply-To: <79810000.999104427@warlock.codesourcery.com> References: <79810000.999104427@warlock.codesourcery.com> Message-ID: <15245.8188.322884.342518@saltydog.lanl.gov> Hi Mark and Graham, I wonder if this is something that Lee Ankeny would know about - it looks like we are talking about the Pooma r1 version. Could you comment on this Lee? Dave Nystrom email: wdn at lanl.gov LANL X-3 phone: 505-667-7913 fax: 505-665-3046 Mark Mitchell writes: > Graham -- > > I'm not sure what to make of this message; I haven't checked in any > POOMA code in a long time. Are you referring to a POOMA checkin, or > a GCC checkin? > > POOMA development is now being coordinate on the > pooma-dev at pooma.codesourcery.com mailing list to which I've forwarded > your message. > > I think I'm not understanding what's going on. > > Thanks, > > ---------- Forwarded Message ---------- > Date: Wednesday, August 29, 2001 04:03:08 AM -0600 > From: "gam at acl.lanl.gov" > To: "mitchell at acl.lanl.gov" > Subject: POOMA1 regression test for O2K64 TEMPLATEINST OPTIMIZE > > The POOMA regression test failed this morning. > > Please inspect the codes you checked in > recently and make sure they are accurate. The > detailed output of this regression test is in > /home/pooma/testing/pooma1/history/report.08_29_2001:03:00 > and > /home/pooma/testing/pooma1/history/trace.08_29_2001:03:00 > files. > > Graham Mark > CIC-12 > Scientific Software Engineering > Los Alamos National Laboratory > (505)667-8147 > > ---------- End Forwarded Message ---------- > > > > -- > Mark Mitchell mark at codesourcery.com > CodeSourcery, LLC http://www.codesourcery.com > From oldham at codesourcery.com Wed Aug 29 17:26:35 2001 From: oldham at codesourcery.com (Jeffrey Oldham) Date: Wed, 29 Aug 2001 10:26:35 -0700 Subject: [newfield_revision Patch] StatigraphicFlow: Linear Algebra into ScalarCode Message-ID: <20010829102635.A12013@codesourcery.com> This patch moves the statigraphic flow's linear algebra computation into a ScalarCode object, improving correctness. The code now compiles excepting two missing mesh functions. One removing pseudocode section needs rewriting using mesh functions. 2001-08-29 Jeffrey D. Oldham * StatigraphicFlow.cpp (findIndex): Moved into ComputeGradients. (ComputeGradientsInfo): New structure to support scalar flow code. (ComputeGradients): New structure for linear algebra ScalarCode. (main): Revise pressureGradient's type to a vector. Move linear algebra computation to a ScalarCode object. Remove FIXMEs for sum(). Tested: compiled using sequential Linux gcc 3.0.1 Approved by: Stephen Smith Applied to: newfield_revision branch Thanks, Jeffrey D. Oldham oldham at codesourcery.com -------------- next part -------------- Index: StatigraphicFlow.cpp =================================================================== RCS file: /home/pooma/Repository/r2/examples/NewField/StatigraphicFlow/Attic/StatigraphicFlow.cpp,v retrieving revision 1.1.2.3 diff -c -p -r1.1.2.3 StatigraphicFlow.cpp *** StatigraphicFlow.cpp 2001/08/23 23:01:20 1.1.2.3 --- StatigraphicFlow.cpp 2001/08/29 16:03:28 *************** *** 1,5 **** // Oldham, Jeffrey D. ! // 2001Jul25 // Pooma // Chevron Kernel Written Using POOMA's Proposed Field Abstraction --- 1,5 ---- // Oldham, Jeffrey D. ! // 2001Aug23 // Pooma // Chevron Kernel Written Using POOMA's Proposed Field Abstraction *************** *** 107,129 **** /** THE PROGRAM **/ ! // Return the index of the specified field offset in the given list. ! // Return a negative number if not found. template ! inline int ! findIndex(const FieldOffsetList &vec, ! const FieldOffset &fo) { ! int indx; ! for (indx = vec.size()-1; ! indx >= 0 && vec[indx] != fo; ! --indx) ! ; ! return indx; ! } int main(int argc, char *argv[]) { // Set up the Pooma library. --- 107,287 ---- /** THE PROGRAM **/ ! // Use a linear algebra computation that stores the pressure gradient ! // values in the four quadrants around the current vertex (loc). template ! struct ComputeGradientsInfo { ! void scalarCodeInfo(ScalarCodeInfo &info) const ! { ! // ComputeGradients::operator() has 4 arguments: vertices to ! // iterate over and three fields. ! ! info.arguments(5); ! ! // Only the first such argument is changed. ! ! info.write(0, false); ! info.write(1, true); ! info.write(2, false); ! info.write(3, false); ! info.write(4, false); ! ! // Does the operation index neighboring cells, i.e., do we need to ! // update the internal guard layers? ! ! info.useGuards(0, false); ! info.useGuards(1, true); ! info.useGuards(2, true); ! info.useGuards(3, true); ! info.useGuards(4, true); ! ! info.dimensions(Dim); ! ! for (int i = 0; i < Dim; ++i) { ! info.lowerExtent(i) = 1; // We access neighbors. ! info.upperExtent(i) = 0; ! } ! } ! }; ! ! ! template ! struct ComputeGradients ! : public ComputeGradientsInfo ! { ! ! ComputeGradients(const Centering &disspoke, ! const FieldOffsetList &gradients, ! const int nuFluxPoints, ! const std::vector > &disFluxPoints, ! const Centering &subcell) ! : disspoke_m(disspoke), gradients_m(gradients), ! nuFluxPoints_m(nuFluxPoints), disFluxPoints_m(disFluxPoints), ! subcell_m(subcell) ! { ! PAssert(gradients_m.size() * Dim == nuFluxPoints_m * 2); ! } ! ! // FIXME: Perhaps we want to modify ScalarCode to take a first ! // FIXME: argument of a centering. In the meantime, we just use a ! // FIXME: fake field. ! ! template ! inline ! void operator()(const F1 &vertexField, ! F2 &pressureGradient, ! const F3 &faceDistance, ! const F4 &directedPermeability, ! const F5 &pressure, ! const Loc &loc) const ! { ! const int nuRows = (1 << Dim) * Dim; ! TNT::Matrix A(nuRows, nuRows, 0.0); ! TNT::Vector rhs(nuRows, 0.0); ! TNT::Vector ipiv; // ignored ! ! // Assign values to the matrix A and vector rhs. ! ! for (int faceIndex = nuFluxPoints_m-1; faceIndex >= 0; --faceIndex) { ! // Work on the "positive" side of the face. ! FieldOffset fo = disFluxPoints_m[faceIndex][0]; ! int columnNu = ! findIndex(gradients_m, ! nearestNeighbors(pressureGradient.centering(), ! fo, disspoke_m, true)[0]); ! // The column number is the pressure gradient corresponding to the ! // "positive" side of the face. ! ! for (int i = 0; i < Dim; ++i) ! A[faceIndex][columnNu] = ! directedPermeability(nearestNeighbors(directedPermeability.centering(), ! fo, disspoke_m, true)[0], ! loc+fo.cellOffset())(i); ! A[faceIndex+nuFluxPoints_m][columnNu] = ! faceDistance(nearestNeighbors(faceDistance.centering(), ! fo, disspoke_m, true)[0], ! loc+fo.cellOffset()); ! rhs[faceIndex+nuFluxPoints_m] -= ! pressure(nearestNeighbors(pressure.centering(), ! fo, disspoke_m, true)[0], ! loc+fo.cellOffset()); ! ! // Work on the "negative" side of the face. ! fo = disFluxPoints_m[faceIndex][1]; ! columnNu = ! findIndex(gradients_m, ! nearestNeighbors(pressureGradient.centering(), ! fo, disspoke_m, true)[0]); ! // The column number is the pressure gradient corresponding to the ! // "positive" side of the face. ! ! for (int i = 0; i < Dim; ++i) ! A[faceIndex][columnNu] = ! -directedPermeability(nearestNeighbors(directedPermeability.centering(), ! fo, disspoke_m, true)[0], ! loc+fo.cellOffset())(i); ! A[faceIndex+nuFluxPoints_m][columnNu] = ! -faceDistance(nearestNeighbors(faceDistance.centering(), ! fo, disspoke_m, true)[0], ! loc+fo.cellOffset()); ! rhs[faceIndex+nuFluxPoints_m] -= ! -pressure(nearestNeighbors(pressure.centering(), ! fo, disspoke_m, true)[0], ! loc+fo.cellOffset()); ! } ! ! // Solve for the pressure gradients. ! ! TNT::LU_solve(A, ipiv, rhs); ! ! // Now, rhs has the pressure gradients. ! ! for (int faceIndex = nuFluxPoints_m-1; faceIndex >= 0; --faceIndex) ! for (int i = 0; i < Dim; ++i) ! pressureGradient(gradients_m[faceIndex], loc)(i) = rhs[faceIndex+i]; ! ! return; ! } ! ! // Return the index of the specified field offset in the given list. ! // Return a negative number if not found. ! ! static ! inline int ! findIndex(const FieldOffsetList &vec, ! const FieldOffset &fo) ! { ! int indx; ! for (indx = vec.size()-1; ! indx >= 0 && vec[indx] != fo; ! --indx) ! ; ! return indx; ! } ! ! private: + // Discontinuous spokes. + const Centering &disspoke_m; + // The pressure gradients. + const FieldOffsetList &gradients_m; + + // The number of flux points for a cell. + const int nuFluxPoints_m; + + // For every i, disFluxPoints_m[i] is two discontinuous positions on + // "either side" of the face represented by the flux points + // fluxPoints[i]. + const std::vector > &disFluxPoints_m; + + // One cell value in each quadrant. + const Centering &subcell_m; + }; + + int main(int argc, char *argv[]) { // Set up the Pooma library. *************** int main(int argc, char *argv[]) *** 172,178 **** position(1) = 0.75; subcell.addValue(Orientation(1), position); position(0) = 0.75; subcell.addValue(Orientation(1), position); position(1) = 0.25; subcell.addValue(Orientation(1), position); ! Fields_t pressureGradient (subcell, meshLayout, origin, spacings); // Spoke-centered Field. --- 330,336 ---- position(1) = 0.75; subcell.addValue(Orientation(1), position); position(0) = 0.75; subcell.addValue(Orientation(1), position); position(1) = 0.25; subcell.addValue(Orientation(1), position); ! Fieldv_t pressureGradient (subcell, meshLayout, origin, spacings); // Spoke-centered Field. *************** int main(int argc, char *argv[]) *** 203,211 **** Centering disFace = canonicalCentering(FaceType, Discontinuous); Fieldv_t directedPermeability (disFace, meshLayout, origin, spacings); ! // \gamma_{i,j} = K_i^t \dot \hat{n}_j Fields_t faceDistance (disFace, meshLayout, origin, spacings); ! // distance from cell center to face center /* INITIALIZATION */ --- 361,369 ---- Centering disFace = canonicalCentering(FaceType, Discontinuous); Fieldv_t directedPermeability (disFace, meshLayout, origin, spacings); ! // \gamma_{i,j} = K_i^t \dot \hat{n}_j Fields_t faceDistance (disFace, meshLayout, origin, spacings); ! // distance from cell center to face center /* INITIALIZATION */ *************** int main(int argc, char *argv[]) *** 238,325 **** faceDistance.centering()); #endif // PSEUDOCODE - const int nuRows = (1 << Dim) * Dim; - TNT::Matrix A(nuRows, nuRows, 0.0); - TNT::Vector rhs(nuRows, 0.0); - TNT::Vector ipiv; // ignored - - // FIXME: Move this code to a stencil so it can be applied across - // the entire grid. - - // Assign values to the matrix A and vector rhs. - const Centering vert = canonicalCentering(VertexType, Continuous); PInsist(vert.size() == 1, "The vertex centering has too many values."); const FieldOffsetList gradients = nearestNeighbors(pressureGradient.centering(), FieldOffset(Loc(0)) /* cell origin */, vert); ! // gradients's order of pressure gradients will be used for the ! // matrix and rhs. const FieldOffsetList fluxPoints = nearestNeighbors(spokeFlux.centering(), FieldOffset(Loc(0)) /* cell origin */, vert); ! // fluxPoints has locations for all faces incident to the vertex. ! const int size = fluxPoints.size(); ! PAssert(gradients.size() * Dim == size * 2); const std::vector > disFluxPoints = nearestNeighbors(disspoke, fluxPoints, spokeFlux.centering()); ! // For every i, disFluxPoints[i] is two discontinuous positions on ! // "either side" of the face represented by fluxPoints[i]. ! ! for (int faceIndex = size-1; faceIndex >= 0; --faceIndex) { ! // Work on the "positive" side of the face. ! FieldOffset fo = disFluxPoints[faceIndex][0]; ! int columnNu = ! findIndex(gradients, ! nearestNeighbors(pressureGradient.centering(), ! fo, disspoke, true)[0]); ! // The column number is the pressure gradient corresponding to the ! // "positive" side of the face. ! ! // FIXME: The lhs (double) and rhs (vector field) do not match. ! ! A[faceIndex][columnNu] = ! directedPermeability(nearestNeighbors(directedPermeability.centering(), ! fo, disspoke, true)[0]); ! A[faceIndex+size][columnNu] = ! faceDistance(nearestNeighbors(faceDistance.centering(), ! fo, disspoke, true)[0]); ! rhs[faceIndex+size] -= ! pressure(nearestNeighbors(pressure.centering(), ! fo, disspoke, true)[0]); ! ! fo = disFluxPoints[faceIndex][1]; ! columnNu = ! findIndex(gradients, ! nearestNeighbors(pressureGradient.centering(), ! fo, disspoke, true)[0]); ! // The column number is the pressure gradient corresponding to the ! // "positive" side of the face. ! ! A[faceIndex][columnNu] = ! -directedPermeability(nearestNeighbors(directedPermeability.centering(), ! fo, disspoke, true)[0]); ! A[faceIndex+size][columnNu] = ! -faceDistance(nearestNeighbors(faceDistance.centering(), ! fo, disspoke, true)[0]); ! rhs[faceIndex+size] -= ! -pressure(nearestNeighbors(pressure.centering(), ! fo, disspoke, true)[0]); ! } ! ! // Solve for the pressure gradients. ! ! TNT::LU_solve(A, ipiv, rhs); ! ! // Now, rhs has the pressure gradients. ! for (int faceIndex = size-1; faceIndex >= 0; --faceIndex) ! // FIXME: Is this type of assignment supported by the current code base? ! pressureGradient(gradients[faceIndex], subcell) = rhs[faceIndex]; // Compute the spoke fluxes. --- 396,433 ---- faceDistance.centering()); #endif // PSEUDOCODE const Centering vert = canonicalCentering(VertexType, Continuous); PInsist(vert.size() == 1, "The vertex centering has too many values."); const FieldOffsetList gradients = nearestNeighbors(pressureGradient.centering(), FieldOffset(Loc(0)) /* cell origin */, vert); ! // gradients's order of pressure gradients will be used for the ! // matrix and rhs. const FieldOffsetList fluxPoints = nearestNeighbors(spokeFlux.centering(), FieldOffset(Loc(0)) /* cell origin */, vert); ! // fluxPoints has locations for all faces incident to the vertex. ! ! const int nuFluxPoints = fluxPoints.size(); const std::vector > disFluxPoints = nearestNeighbors(disspoke, fluxPoints, spokeFlux.centering()); ! // For every i, disFluxPoints[i] is two discontinuous positions on ! // "either side" of the face represented by fluxPoints[i]. ! typedef ComputeGradients CG_t; ! CG_t cG(disspoke, gradients, nuFluxPoints, disFluxPoints, subcell); ! ScalarCode computeGradients(cG); ! ! // FIXME: Use an otherwise unused field for the ScalarCode ! // FIXME: iteration over vertices. ! Fields_t vertexField(canonicalCentering(VertexType, Continuous), ! meshLayout, origin, spacings); + computeGradients(vertexField, pressureGradient, + faceDistance, directedPermeability, pressure); // Compute the spoke fluxes. *************** int main(int argc, char *argv[]) *** 346,359 **** totalFlux = sum(spokeFlux.mesh().normals().signedMagnitude() * - // FIXME: This is not yet implemented. We want a - // FIXME: data-parallel sum. This is we want a function - // FIXME: Field_t sum(/* input */ Field_t, - // FIXME: std::vector, /*output */ - // FIXME: Centering). The vector's length == the output - // centering's length. The function works by using the input - // field with each FieldOffsetList to form one value in the - // output field. sum(spokeFlux, nearestNeighbors(spokeFlux.centering(), disFace), disFace), --- 454,459 ---- From scotth at proximation.com Wed Aug 29 17:55:13 2001 From: scotth at proximation.com (Scott Haney) Date: Wed, 29 Aug 2001 11:55:13 -0600 Subject: Final patch for newfield_revision Message-ID: Here is the patch describing my check-ins to finish up my work on newfield_revision. This was tested under CodeWarrior Pro 7 and approved by Stephen and Jim. There are a few problems remaining, but we're close enough to merge the branch back. Stephen is done for now as well. Scott -------------- next part -------------- Here is the patch describing my check-ins to finish up my work on newfield_revision. This was tested under CodeWarrior Pro 7 and approved by Stephen and Jim. There are a few problems remaining, but we're close enough to merge the branch back. Stephen is done for now as well. Scott -------------- next part -------------- A non-text attachment was scrubbed... Name: 082901.1.patch Type: application/applefile Size: 496 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: 082901.1.patch Type: application/octet-stream Size: 100678 bytes Desc: not available URL: From mark at codesourcery.com Wed Aug 29 18:14:57 2001 From: mark at codesourcery.com (Mark Mitchell) Date: Wed, 29 Aug 2001 11:14:57 -0700 Subject: Merging newfield_revision Message-ID: <120170000.999108897@warlock.codesourcery.com> --On Tuesday, August 28, 2001 01:52:13 PM -0600 Scott Haney wrote: > Hi everyone, > > Those working on the newfield_revision branch - please get check-in > whatever outstanding changes you have by NOON PST on 8/29. I would like > to merge this branch into the main trunk ASAP. Excellent news! -- Mark Mitchell mark at codesourcery.com CodeSourcery, LLC http://www.codesourcery.com From mark at codesourcery.com Wed Aug 29 18:17:27 2001 From: mark at codesourcery.com (Mark Mitchell) Date: Wed, 29 Aug 2001 11:17:27 -0700 Subject: [pooma-dev] Merging newfield_revision In-Reply-To: Message-ID: <120860000.999109047@warlock.codesourcery.com> > > It would probably be best to do this in the repository itself - i.e. to > move the ,v files from the NewField directory to the Field directory. > Otherwise we'll lose the CVS history. Oh, how I'm bored of this argument... :-) This comes up about every 3 weeks on some project or another. What it really highlights is that CVS is lame in this regard; you should not have to mess with the repository and yet you should still get to keep your revision history. Generally, I come down on the side of not moving the ,v files. In the presence of branches, you really don't have a choice: if we move the ,v files into the Field directory we will break the branch that Jeffrey is making -- and any previous branches/tags that applied to the old Field stuff. -- Mark Mitchell mark at codesourcery.com CodeSourcery, LLC http://www.codesourcery.com From oldham at codesourcery.com Wed Aug 29 19:23:23 2001 From: oldham at codesourcery.com (Jeffrey Oldham) Date: Wed, 29 Aug 2001 12:23:23 -0700 Subject: Pooma CVS Code Freeze Message-ID: <200108291923.MAA16529@oz.codesourcery.com> Per Scott Haney's email message of yesterday (Tuesday), we'll now 1) Copy the mainline code into a blanca_2001Oct01 branch. 2) Merge the newfield_revision branch into the mainline. While this is happening, will you please refrain from committing code changes to the Pooma CVS repository? If you have objections to any part of this, please contact me by telephone immediately. Thanks, Jeffrey D. Oldham oldham at codesourcery.com 650.968.0703 From oldham at codesourcery.com Wed Aug 29 20:37:04 2001 From: oldham at codesourcery.com (Jeffrey Oldham) Date: Wed, 29 Aug 2001 13:37:04 -0700 Subject: blanca-2001Oct01 Branch Available Message-ID: <200108292037.NAA21695@oz.codesourcery.com> The Pooma mainline was copied into the new `blanca-2001Oct01' branch. The new branch's purpose is to provide a stable code base for Blanca developers. No development will occur on the branch, but error fixes may occur if needed. The branch will disappear when Blanca migrates its code to use the new field concepts. To use the new `blanca-2001Oct01' branch: cvs update -r blanca-2001Oct01 To stop using the branch: cvs update -A For more information about cvs and branches, read the cvs info pages. Thanks, Jeffrey D. Oldham oldham at codesourcery.com From oldham at codesourcery.com Thu Aug 30 01:32:20 2001 From: oldham at codesourcery.com (Jeffrey Oldham) Date: Wed, 29 Aug 2001 18:32:20 -0700 Subject: Pooma CVS Code Thaw Message-ID: <200108300132.SAA32435@oz.codesourcery.com> The newfield_revision branch has been merged into the mainline. Feel free to add, modify, or remove any code. See my next email for a description of the merger. Thanks, Jeffrey D. Oldham oldham at codesourcery.com From oldham at codesourcery.com Thu Aug 30 01:43:26 2001 From: oldham at codesourcery.com (Jeffrey Oldham) Date: Wed, 29 Aug 2001 18:43:26 -0700 Subject: newfield_revision Merged into Mainline Message-ID: <20010829184326.A31703@codesourcery.com> The creation of a `blanca-2001Oct01' branch with the previous Field implementation was announced in my previous email. Now, the `newfield_revision' branch has been merged into the mainline, replacing the Field implementation with the revised implementation. The improvements include: 1) support for field centerings and multiple values within a cell 2) support for meshes 3) improved particles 4) support for relations Code development will now occur on the mainline. To use the mainline, cvs update -P -A where `-A' resets any sticky tags and `-P' prunes empty diretories. We appreciate your forgiveness as we resolve any remaining difficulties. **** Details of the merge **** The merger of the newfield_revision branch into the mainline basically followed Scott Haney's instructions of Tuesday, 28 August. 1. The newfield_revision branch was merged into the mainline using the `cvs update -j newfield_revision' command. This preserves any bug fixes in the mainline. 2. The BConds, Geometry, Meshes, and IO directories were removed. 3. The NewField directory replaced the Field directory. 4. All uses of "newfield" regardless of capitalization were replaced with "field". Hopefully, this text substitution does not cause any name conflicts. 5. src/Pooma/NewFields.h replaced src/Pooma/Fields.h. The Pooma library and the (now named) Field tests were compiled using gcc 3.0.1 on Linux for sequential computation. In your spare cycles while doing optimization work, please compile your favorite test code or benchmark to ensure it still works. I am working on using QMTest to automatically compile and run test code and benchmarks; changing the directory strucure broke the tests. When it is complete, we can automate this checking. Again, we appreciate your forgiveness as we resolve any remaining difficulties. Thanks, Jeffrey D. Oldham oldham at codesourcery.com -------------- next part -------------- A non-text attachment was scrubbed... Name: newfield_removal.patch.gz Type: application/x-gzip Size: 421304 bytes Desc: not available URL: From mark at codesourcery.com Thu Aug 30 02:08:04 2001 From: mark at codesourcery.com (Mark Mitchell) Date: Wed, 29 Aug 2001 19:08:04 -0700 Subject: newfield_revision Merged into Mainline In-Reply-To: <20010829184326.A31703@codesourcery.com> Message-ID: <218100000.999137284@warlock.codesourcery.com> --On Wednesday, August 29, 2001 06:43:26 PM -0700 Jeffrey Oldham wrote: > The creation of a `blanca-2001Oct01' branch with the previous Field > implementation was announced in my previous email. Now, the > `newfield_revision' branch has been merged into the mainline, > replacing the Field implementation with the revised implementation. Excellent! This represents a major milestone; congratulations to all! -- Mark Mitchell mark at codesourcery.com CodeSourcery, LLC http://www.codesourcery.com From oldham at codesourcery.com Thu Aug 30 19:04:16 2001 From: oldham at codesourcery.com (Jeffrey Oldham) Date: Thu, 30 Aug 2001 12:04:16 -0700 Subject: Patch: Make Field Centerings Table Always Dynamic Message-ID: <20010830120416.B14904@codesourcery.com> We change the implementation of canonicalCentering tables from a static object to a dynamically allocated table. This resolves a runtime execution problem for KCC/Irix and simplifies the code. Prior to this patch, gcc used the dynamic code and all other compilers used the static code, which apparently was wrong. 2001-08-30 Jeffrey D. Oldham * FieldCentering.cmpl.cpp (CanonicalCentering::CanonicalCentering): Make dynamic centering table construction unconditional. * FieldCentering.h (CanonicalCentering::~CanonicalCentering): Destroy dynamic centering table for all implementations. (CanonicalCentering::class_count_m): Always used. (CanonicalCentering::centering_table_m): Always used. Tested on Irix/KCC 4.0c and Linux gcc 3.0.1 by compiling Pooma library and the Field tests Approved by Stephen Smith Applied to mainline Thanks, Jeffrey D. Oldham oldham at codesourcery.com -------------- next part -------------- Index: FieldCentering.cmpl.cpp =================================================================== RCS file: /home/pooma/Repository/r2/src/Field/FieldCentering.cmpl.cpp,v retrieving revision 1.1 diff -c -p -r1.1 FieldCentering.cmpl.cpp *** FieldCentering.cmpl.cpp 2001/08/30 01:15:06 1.1 --- FieldCentering.cmpl.cpp 2001/08/30 16:59:13 *************** CanonicalCentering::CanonicalCenter *** 46,53 **** Centering::Positions positions[Dim][2]; enum { x = 0, y, z }; ! #if __GNUC__ ! // Avoid a gcc 3.0 and 2.96 error. if (class_count_m == 0) { centering_table_m = new Centering**[CellType+1]; for (int i = 0; i <= CellType; ++i) { --- 46,52 ---- Centering::Positions positions[Dim][2]; enum { x = 0, y, z }; ! // Create the tables if necessary. if (class_count_m == 0) { centering_table_m = new Centering**[CellType+1]; for (int i = 0; i <= CellType; ++i) { *************** CanonicalCentering::CanonicalCenter *** 57,64 **** } } ++class_count_m; - - #endif // __GNUC__ // Add the cell centerings. centering = Centering(CellType, Continuous); --- 56,61 ---- Index: FieldCentering.h =================================================================== RCS file: /home/pooma/Repository/r2/src/Field/FieldCentering.h,v retrieving revision 1.1 diff -c -p -r1.1 FieldCentering.h *** FieldCentering.h 2001/08/30 01:15:06 1.1 --- FieldCentering.h 2001/08/30 16:59:13 *************** public: *** 384,393 **** CanonicalCentering(); - #if __GNUC__ - // Avoid a gcc 3.0 and 2.96 error. //--------------------------------------------------------------------------- // Deallocate centering_table_m. ~CanonicalCentering () { if (--class_count_m == 0) { for (int i = 0; i <= CellType; ++i) { --- 384,392 ---- CanonicalCentering(); //--------------------------------------------------------------------------- // Deallocate centering_table_m. + ~CanonicalCentering () { if (--class_count_m == 0) { for (int i = 0; i <= CellType; ++i) { *************** public: *** 398,404 **** delete [] centering_table_m; } } - #endif // __GNUC__ //--------------------------------------------------------------------------- // Return the desired centering. --- 397,402 ---- *************** private: *** 440,457 **** return answer; } - #if __GNUC__ - // Avoid a gcc 3.0 and 2.96 error. // Number of extent objects. static int class_count_m; ! static Centering*** centering_table_m; ! #else // Table containing the centerings, which are the cross product of // the centering type, discontinuous xor continuous, all the // possible combinations of dimensions. We ignore illegal entries // such as centering_table_m[x][y][0]. ! static Centering centering_table_m[CellType+1][2][1<*** centering_table_m; }; //----------------------------------------------------------------------------- *************** std::ostream &operator<<(std::ostream &o *** 498,506 **** // Define CanonicalCentering's static members. //----------------------------------------------------------------------------- - #if __GNUC__ - // Avoid a gcc 3.0 and 2.96 error. // Number of extent objects. template int CanonicalCentering::class_count_m = 0; --- 494,501 ---- // Define CanonicalCentering's static members. //----------------------------------------------------------------------------- // Number of extent objects. + template int CanonicalCentering::class_count_m = 0; *************** int CanonicalCentering::class_count *** 508,519 **** // the centering type, discontinuous xor continuous, all the // possible combinations of dimensions. We ignore illegal entries // such as centering_table_m[x][y][0]. template Centering*** CanonicalCentering::centering_table_m = 0; - #else - template - Centering CanonicalCentering::centering_table_m[CellType+1][2][1< Centering*** CanonicalCentering::centering_table_m = 0; //----------------------------------------------------------------------------- From oldham at codesourcery.com Thu Aug 30 19:30:22 2001 From: oldham at codesourcery.com (Jeffrey Oldham) Date: Thu, 30 Aug 2001 12:30:22 -0700 Subject: Profiling with Irix and KCC Message-ID: <200108301930.MAA15061@oz.codesourcery.com> Here are two ways to profile executables produced by KCC on Irix6.5. 1) The X window interface method: ssrun -workshop -usertime # creates .usertime. cvperf .usertime. 2) The text-based method: ssrun -usertime # creates .usertime. prof .usertime. If anyone knows better methods, please let me know. Thanks, Jeffrey D. Oldham oldham at codesourcery.com