Commit 99361fd6 authored by snuverink_j's avatar snuverink_j

Merge branch '570-segmentation-fault-in-unit-test-field-periodicbc' into 'master'

Resolve "segmentation fault in unit-test  Field.PeriodicBC"

Closes #570

See merge request !402
parents 10354343 a53f404e
// -*- C++ -*-
/***************************************************************************
*
* The IPPL Framework
*
***************************************************************************/
//
// Class LField
// Local Field class
//
// Copyright (c) 2003 - 2020, Paul Scherrer Institut, Villigen PSI, Switzerland
// All rights reserved
//
// This file is part of OPAL.
//
// OPAL is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// You should have received a copy of the GNU General Public License
// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
//
#ifndef LFIELD_H
#define LFIELD_H
......@@ -47,7 +57,7 @@ template<class T, unsigned Dim>
class LField
{
public:
public:
// An iterator for the contents of this LField.
typedef CompressedBrickIterator<T,Dim> iterator;
......@@ -63,14 +73,14 @@ public:
// allocated = domain of "allocated" region, which includes guards
// vnode = global vnode ID number (see below)
LField(const NDIndex<Dim>& owned,
const NDIndex<Dim>& allocated,
int vnode = -1);
const NDIndex<Dim>& allocated,
int vnode = -1);
//UL: for pinned memory allocation
LField(const NDIndex<Dim>& owned,
const NDIndex<Dim>& allocated,
int vnode,
bool p);
const NDIndex<Dim>& allocated,
int vnode,
bool p);
// Copy constructor.
LField(const LField<T,Dim>&);
......@@ -177,7 +187,7 @@ public:
void AddToOverlapCache(LField<T, Dim> *newCacheItem)
{
if (overlap.size() == 0)
if (overlap.size() == 0)
overlap.reserve(ToTheDim<Dim>::calc(3)-1);
overlap.push_back(newCacheItem);
overlapCacheInited = true;
......@@ -283,8 +293,8 @@ template<class T, unsigned Dim>
inline
std::ostream& operator<<(std::ostream& out, const LField<T,Dim>& a)
{
a.write(out);
return out;
}
......@@ -293,4 +303,4 @@ std::ostream& operator<<(std::ostream& out, const LField<T,Dim>& a)
#include "Field/LField.hpp"
#endif // LFIELD_H
#endif // LFIELD_H
\ No newline at end of file
// -*- C++ -*-
/***************************************************************************
*
* The IPPL Framework
*
* This program was prepared by PSI.
* All rights in the program are reserved by PSI.
* Neither PSI nor the author(s)
* makes any warranty, express or implied, or assumes any liability or
* responsibility for the use of this software
*
* Visit www.amas.web.psi for more details
*
***************************************************************************/
// -*- C++ -*-
/***************************************************************************
*
* The IPPL Framework
*
*
* Visit http://people.web.psi.ch/adelmann/ for more details
*
***************************************************************************/
// include files
//
// Class LField
// Local Field class
//
// Copyright (c) 2003 - 2020, Paul Scherrer Institut, Villigen PSI, Switzerland
// All rights reserved
//
// This file is part of OPAL.
//
// OPAL is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// You should have received a copy of the GNU General Public License
// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
//
#include "Field/LField.h"
#include "Utility/PAssert.h"
......@@ -92,8 +83,8 @@ MAKE_INITIALIZER(long long)
template<class T, unsigned Dim>
LField<T,Dim>::LField(const NDIndex<Dim>& owned,
const NDIndex<Dim>& allocated,
int vnode)
const NDIndex<Dim>& allocated,
int vnode)
: vnode_m(vnode),
P(0),
Pinned(false),
......@@ -121,8 +112,8 @@ LField<T,Dim>::LField(const NDIndex<Dim>& owned,
//UL: for pinned mempory allocation
template<class T, unsigned Dim>
LField<T,Dim>::LField(const NDIndex<Dim>& owned,
const NDIndex<Dim>& allocated,
int vnode, bool p)
const NDIndex<Dim>& allocated,
int vnode, bool p)
: vnode_m(vnode),
P(0),
Pinned(p),
......@@ -235,18 +226,18 @@ LField<T,Dim>::TryCompress(bool baseOnPhysicalCells)
if (baseOnPhysicalCells)
{
if (CanCompressBasedOnPhysicalCells())
{
CompressBasedOnPhysicalCells();
return true;
}
{
CompressBasedOnPhysicalCells();
return true;
}
}
else
{
if (CanCompress() )
{
Compress();
return true;
}
{
Compress();
return true;
}
}
return false;
......@@ -304,16 +295,16 @@ LField<T,Dim>::CanCompress(T val) const
ADDIPPLSTAT(incCompressionCompares, 1);
if (!(*mid1 == val))
{
LFIELDMSG(dbgmsg << "Short-cut check determined we cannot ");
LFIELDMSG(dbgmsg << "compress, by comparing " << *mid1<<" to ");
LFIELDMSG(dbgmsg << val << " at last-alloc-domain-failed index");
LFIELDMSG(dbgmsg << " of " << allocCompressIndex << endl);
// It failed the test, so we can just keep the same index to
// check next time, and return.
return false;
}
{
LFIELDMSG(dbgmsg << "Short-cut check determined we cannot ");
LFIELDMSG(dbgmsg << "compress, by comparing " << *mid1<<" to ");
LFIELDMSG(dbgmsg << val << " at last-alloc-domain-failed index");
LFIELDMSG(dbgmsg << " of " << allocCompressIndex << endl);
// It failed the test, so we can just keep the same index to
// check next time, and return.
return false;
}
}
// Check from the beginning to the last-checked-index
......@@ -328,52 +319,52 @@ LField<T,Dim>::CanCompress(T val) const
// in cache
T *checkptr = mid1 + 1;
while (checkptr != end1)
{
if (!(*checkptr++ == val))
{
LFIELDMSG(dbgmsg << "Found that we cannot compress, after ");
LFIELDMSG(dbgmsg << (checkptr - mid1) << " compares (");
LFIELDMSG(dbgmsg << *(checkptr-1) << " != " << val << ")");
LFIELDMSG(dbgmsg << endl);
ADDIPPLSTAT(incCompressionCompares, (checkptr - mid1));
allocCompressIndex = (checkptr - ptr1) - 1;
return false;
}
}
{
if (!(*checkptr++ == val))
{
LFIELDMSG(dbgmsg << "Found that we cannot compress, after ");
LFIELDMSG(dbgmsg << (checkptr - mid1) << " compares (");
LFIELDMSG(dbgmsg << *(checkptr-1) << " != " << val << ")");
LFIELDMSG(dbgmsg << endl);
ADDIPPLSTAT(incCompressionCompares, (checkptr - mid1));
allocCompressIndex = (checkptr - ptr1) - 1;
return false;
}
}
// Next, check from the first position to the last-failed-position.
checkptr = ptr1;
while (checkptr != mid1)
{
if (!(*checkptr++ == val))
{
LFIELDMSG(dbgmsg << "Found that we cannot compress, after ");
LFIELDMSG(dbgmsg << (checkptr - ptr1) + (end1 - mid1));
LFIELDMSG(dbgmsg << " compares (");
LFIELDMSG(dbgmsg << *(checkptr-1) << " != " << val << ")");
LFIELDMSG(dbgmsg << endl);
ADDIPPLSTAT(incCompressionCompares,
(checkptr - ptr1) + (end1 - mid1));
allocCompressIndex = (checkptr - ptr1) - 1;
return false;
}
}
{
if (!(*checkptr++ == val))
{
LFIELDMSG(dbgmsg << "Found that we cannot compress, after ");
LFIELDMSG(dbgmsg << (checkptr - ptr1) + (end1 - mid1));
LFIELDMSG(dbgmsg << " compares (");
LFIELDMSG(dbgmsg << *(checkptr-1) << " != " << val << ")");
LFIELDMSG(dbgmsg << endl);
ADDIPPLSTAT(incCompressionCompares,
(checkptr - ptr1) + (end1 - mid1));
allocCompressIndex = (checkptr - ptr1) - 1;
return false;
}
}
}
else
{
while (ptr1 != end1)
{
if (!(*ptr1++ == val))
{
LFIELDMSG(dbgmsg << "Found that we cannot compress, after ");
LFIELDMSG(dbgmsg << (ptr1 - P) << " compares (");
LFIELDMSG(dbgmsg << *(ptr1-1) << " != " << val << ")");
LFIELDMSG(dbgmsg << endl);
ADDIPPLSTAT(incCompressionCompares, (ptr1 - P));
allocCompressIndex = (ptr1 - P) - 1;
return false;
}
}
{
if (!(*ptr1++ == val))
{
LFIELDMSG(dbgmsg << "Found that we cannot compress, after ");
LFIELDMSG(dbgmsg << (ptr1 - P) << " compares (");
LFIELDMSG(dbgmsg << *(ptr1-1) << " != " << val << ")");
LFIELDMSG(dbgmsg << endl);
ADDIPPLSTAT(incCompressionCompares, (ptr1 - P));
allocCompressIndex = (ptr1 - P) - 1;
return false;
}
}
}
// If we are at this point, we did not find anything that did not
......@@ -403,7 +394,7 @@ bool LField<T,Dim>::CanCompressBasedOnPhysicalCells() const
// Debugging macro
LFIELDMSG(Inform dbgmsg("LField::CanCompressBasedOnPhysicalCells",
INFORM_ALL_NODES));
INFORM_ALL_NODES));
// We definitely can't do this if compression is disabled.
if (IpplInfo::noFieldCompression)
......@@ -450,15 +441,15 @@ bool LField<T,Dim>::CanCompressBasedOnPhysicalCells() const
for (int i=0; i < sz; ++i, ++p)
{
if (!(*p == val))
{
LFIELDMSG(dbgmsg << "Found that we cannot compress, after ");
LFIELDMSG(dbgmsg << i + 1 << " compares." << endl);
ADDIPPLSTAT(incCompressionCompares, i + 1);
ownedCompressIndex = (&(*p)) - P;
LFIELDMSG(dbgmsg << "changed ownedCompressIndex to ");
LFIELDMSG(dbgmsg << ownedCompressIndex << endl);
return false;
}
{
LFIELDMSG(dbgmsg << "Found that we cannot compress, after ");
LFIELDMSG(dbgmsg << i + 1 << " compares." << endl);
ADDIPPLSTAT(incCompressionCompares, i + 1);
ownedCompressIndex = (&(*p)) - P;
LFIELDMSG(dbgmsg << "changed ownedCompressIndex to ");
LFIELDMSG(dbgmsg << ownedCompressIndex << endl);
return false;
}
}
// Since we made it here, we can compress.
......@@ -500,7 +491,7 @@ LField<T,Dim>::Compress(const T& val)
if (IpplInfo::noFieldCompression)
{
for (iterator lit = begin(); lit != end(); ++lit)
*lit = val;
*lit = val;
return;
}
......@@ -586,7 +577,7 @@ void LField<T,Dim>::ReallyUncompress(bool fill_domain)
{
T val = *Begin;
for (int i=0; i<n; i++)
P[i] = val;
P[i] = val;
}
// Make the Begin iterator point to the new data.
......@@ -714,7 +705,7 @@ LField<T,Dim>::allocateStorage(int newsize)
// Allocate the storage, creating some extra to account for offset, and
// then add in the offset.
P = new T[newsize + extra];
P = new T[newsize + extra]();
P += extra;
ADDIPPLSTAT(incLFieldBytes, (newsize+extra)*sizeof(T));
......@@ -737,7 +728,7 @@ LField<T,Dim>::deallocateStorage()
// If so, move the P pointer back.
if (IpplInfo::offsetStorage)
P -= (offsetBlocks*IPPL_CACHE_LINE_SIZE / sizeof(T));
P -= (offsetBlocks*IPPL_CACHE_LINE_SIZE / sizeof(T));
delete [] P;
P = 0;
......@@ -758,11 +749,4 @@ void LField<T,Dim>::write(std::ostream& out) const
for (iterator p = begin(); p!=end(); ++p)
out << *p << " ";
}
/***************************************************************************
* $RCSfile: LField.cpp,v $ $Author: adelmann $
* $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:26 $
* IPPL_VERSION_ID: $Id: LField.cpp,v 1.1.1.1 2003/01/23 07:40:26 adelmann Exp $
***************************************************************************/
}
\ No newline at end of file
// -*- C++ -*-
/***************************************************************************
*
* The IPPL Framework
*
*
* Visit http://people.web.psi.ch/adelmann/ for more details
*
***************************************************************************/
//
// Class SubFieldIter
// Iterator for a subset of a BareField
//
// Copyright (c) 2003 - 2020, Paul Scherrer Institut, Villigen PSI, Switzerland
// All rights reserved
//
// This file is part of OPAL.
//
// OPAL is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// You should have received a copy of the GNU General Public License
// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
//
#ifndef SUB_FIELD_ITER_H
#define SUB_FIELD_ITER_H
......@@ -31,8 +38,8 @@
- two construction options, one with needed iterator args, the other
a default constructor (this is needed by PETE). You can also
define a copy constructor, or else make sure that element-wise
copying will suffice for your iterator class.
define a copy constructor, or else make sure that element-wise
copying will suffice for your iterator class.
- override the versions of all the functions in the base class which
need to be overridden, to supply the special functionality for that
......@@ -42,7 +49,7 @@
- add specialization in SubFieldTraits to indicate how this subset
object can be constructed from other subset objects, and what kind
of combinations of subset objects will work.
of combinations of subset objects will work.
- static bool matchType(int t) { return (t == Type_u); } ... return
whether the type of subset object matches the given type. Some
......@@ -56,12 +63,12 @@
- bool findIntersection() { } ... find the intersection between a
the current component and a given NDIndex, and return the intersection
as an NDIndex. Also return a boolean flag indicating if this
intersection did indeed contain some points (true). This is then used
intersection did indeed contain some points (true). This is then used
in a BrickExpression to take data from the RHS and store it into the
LHS. findIntersection is only called for an iterator which occurs
on the LHS; if something is on the RHS, then plugBase will be called
instead, with an argument of the domain as calculated by
findIntersection.
on the LHS; if something is on the RHS, then plugBase will be called
instead, with an argument of the domain as calculated by
findIntersection.
- void nextLField() { } ... for subsets which must keep track of their
current vnode (e.g., SIndex), this increments a vnode iterator.
......@@ -71,7 +78,7 @@
in to the RHS. This results in each SubBareField on the RHS setting
internal iterators to point to the proper section of data
based on any offsets it may have and on the subset from the LHS.
For some subset objects, this will not depend on the given subdomain.
For some subset objects, this will not depend on the given subdomain.
- setLFieldData(LField<T,Dim>*, NDIndex<Dim>&) ... for iterators
which occur on the LHS of an expression, the LField referred to by
......@@ -84,9 +91,9 @@
- bool CanTryCompress() ... Some subset objects cannot easily be
used on the LHS with compressed LFields. If the new one can not
(for example, if it is not possible to determine if all the points
referred to by the subset have the same value), this should return
false, and all the other compression routines can just be no-ops.
(for example, if it is not possible to determine if all the points
referred to by the subset have the same value), this should return
false, and all the other compression routines can just be no-ops.
***************************************************************************/
......@@ -96,6 +103,7 @@
#include "Index/SIndex.h"
#include "Field/BareField.h"
#include "Field/LField.h"
#include "Utility/IpplException.h"
#include "Utility/PAssert.h"
#include "PETE/IpplExpressions.h"
......@@ -120,14 +128,18 @@ public:
// Construct with a SubField and the domain to use
SubFieldIterBase(const BareField<T,Dim>& df,
const typename BareField<T,Dim>::iterator_if& ldf,
const S& s,
unsigned int B)
const typename BareField<T,Dim>::iterator_if& ldf,
const S& s,
unsigned int B)
: MyBareField(&(const_cast<BareField<T,Dim> &>(df))),
MyDomain(&(const_cast<S&>(s))),
CurrentLField(ldf),
MyBrackets(B) {
LFPtr = (*CurrentLField).second.get();
if (CurrentLField != getBareField().end_if()) {
LFPtr = (*CurrentLField).second.get();
} else {
LFPtr = nullptr;
}
}
// Default constructor
......@@ -156,9 +168,17 @@ public:
// Go to the next LField.
typename BareField<T,Dim>::iterator_if nextLField() {
++CurrentLField;
LFPtr = (*CurrentLField).second.get();
return CurrentLField;
if (CurrentLField != getBareField().end_if()) {
++CurrentLField;
} else {
throw IpplException("SubFieldIterBase::nextLField()", "Reached the container end, no next LField!");
}
if (CurrentLField != getBareField().end_if()) {
LFPtr = (*CurrentLField).second.get();
} else {
LFPtr = nullptr;
}
return CurrentLField;
}
// Return the LField pointed to by LFPtr
......@@ -171,7 +191,7 @@ public:
// Use a new LField, where we use data on the given NDIndex region
void setLFieldData(LField<T,Dim>* p, NDIndex<Dim>&) { LFPtr = p; }
/* tjw 3/3/99: try to mimic changes made in
/* tjw 3/3/99: try to mimic changes made in
IndexedBareFieldIterator::FillGCIfNecessary:
// Fill the guard cells for our field, if necessary. We punt on
......@@ -249,8 +269,8 @@ public:
// Construct with a SubField and the domain to use
SubFieldIter(const BareField<T,Dim>& df,
const typename BareField<T,Dim>::iterator_if& ldf,
const NDIndex<Dim>& s, unsigned int B)
const typename BareField<T,Dim>::iterator_if& ldf,
const NDIndex<Dim>& s, unsigned int B)
: SubFieldIterBase<T,Dim,Subset_t,Dim>(df, ldf, s, B) { }
// Default constructor
......@@ -308,9 +328,9 @@ public:
for ( ; lf_i != lf_e; ++lf_i) {
// is the search domain completely within the LField we're examining?
if ((*lf_i).second->getAllocated().contains(plugged)) {
// Found it. Make this one current and go.
setLFieldData((*lf_i).second.get(), plugged);
return true;
// Found it. Make this one current and go.
setLFieldData((*lf_i).second.get(), plugged);
return true;
}
}
......@@ -382,8 +402,8 @@ public:
// Construct with a SubField and the domain to use
SubFieldIter(const BareField<T,Dim>& df,
const typename BareField<T,Dim>::iterator_if& ldf,
const SIndex<Dim>& s, unsigned int B)
const typename BareField<T,Dim>::iterator_if& ldf,
const SIndex<Dim>& s, unsigned int B)
: SubFieldIterBase<T,Dim,Subset_t,1U>(df, ldf, s, B) {
ComponentLF = this->getDomain().begin_iv();
computeLSOffset();
......@@ -492,7 +512,7 @@ private:
if (this->getLFieldIter() != this->getBareField().end_if()) {
NDIndex<Dim> owned = this->getLField()->getOwned();
for (unsigned int d=0; d < Dim; ++d)
LFOffset[d] = (owned[d].first() - this->getDomain().getOffset()[d]);
LFOffset[d] = (owned[d].first() - this->getDomain().getOffset()[d]);
}
}
};
......@@ -502,7 +522,7 @@ private:
// A specialized versions of the SubFieldIter class for an SOffset, which
// is used to act as a single-value
// subset object. This overrides certain functions from the base class,
// and provides definitions of needed functions not available in the base.
// and provides definitions of needed functions not available in the base.
template<class T, unsigned int Dim>
class SubFieldIter<T, Dim, SOffset<Dim> >
: public SubFieldIterBase<T, Dim, SOffset<Dim>, 1U>,
......@@ -516,8 +536,8 @@ public:
// Construct with a SubField and the domain to use
SubFieldIter(const BareField<T,Dim>& df,
const typename BareField<T,Dim>::iterator_if& ldf,
const SOffset<Dim>& s, unsigned int B)
const typename BareField<T,Dim>::iterator_if& ldf,
const SOffset<Dim>& s, unsigned int B)
: SubFieldIterBase<T,Dim,Subset_t,1U>(df, ldf, s, B), SingleValPtr(0) { }
// Default constructor
......@@ -540,7 +560,7 @@ public:
SOffset<Dim> s = this->getDomain();
NDIndex<Dim> owned = p->getOwned();
for (unsigned int d=0; d < Dim; ++d)
s[d] -= owned[d].first();
s[d] -= owned[d].first();
SingleValPtr = &(p->begin().offset(s.begin()));
}
}
......@@ -620,11 +640,4 @@ private:
NDIndex<Dim> Component;
};
#endif // SUB_FIELD_ITER_H
/***************************************************************************
* $RCSfile: SubFieldIter.h,v $ $Author: adelmann $
* $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:33 $
* IPPL_VERSION_ID: $Id: SubFieldIter.h,v 1.1.1.1 2003/01/23 07:40:33 adelmann Exp $
***************************************************************************/
#endif // SUB_FIELD_ITER_H
\ No newline at end of file
......@@ -148,7 +148,7 @@ TEST_F(NDGridTest, CoordVectorTest) { // and newCoordArray
EXPECT_NEAR(coords_v[j], gridCoordinates[i][j], 1e-12);
EXPECT_NEAR(coords_a[j], gridCoordinates[i][j], 1e-12);
}
delete coords_a;
delete[] coords_a;
}
}
......
......@@ -62,7 +62,7 @@ TEST(Field, PeriodicBC)
int i,j,k;
for (j=0; j<3; j++) {
for (i=0; i<3; i++) {
for(k=0; k<3; k++) {
for (k=0; k<3; k++) {
if (i==1 && j==1 && k==1)
assign(cA[i][j][k], 1.0);
else
......@@ -71,7 +71,11 @@ TEST(Field, PeriodicBC)
}
}
// Print reference values, then assign values ofsetting across boundaries
// and print results, Cell-centered case:
// and print results.
// For printing we need to reset the output stream (needed when running multiple tests)
setInform(*IpplInfo::Info);
// Cell-centered case:
std::cout << "++++++++++cA+++++++++++" << std::endl ;
fp3(cA);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment