Commit 00014c51 authored by berenger-bramas's avatar berenger-bramas

Add and use a smart pointer for M2L precomputed array.

git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/scalfmm/scalfmm/trunk@381 2616d619-271b-44dc-8df4-d4a8f33a7222
parent 2832bb57
......@@ -81,7 +81,7 @@ public:
directPass();
}
private:
/////////////////////////////////////////////////////////////////////////////
// P2M
/////////////////////////////////////////////////////////////////////////////
......
This diff is collapsed.
......@@ -29,8 +29,8 @@ protected:
const int FF_MATRIX_COLUMN_DIM; //< The blas matrix number of columns
const int FF_MATRIX_SIZE; //< The blas matrix size
FComplexe* temporaryMultiSource; //< To perform the M2L without allocating at each call
FComplexe** preM2LTransitions; //< The pre-computation for the M2L based on the level and the 189 possibilities
FComplexe* temporaryMultiSource; //< To perform the M2L without allocating at each call
FSmartPointer<FComplexe*> preM2LTransitions; //< The pre-computation for the M2L based on the level and the 189 possibilities
/** To access te precomputed M2L transfer matrixes */
int indexM2LTransition(const int idxX,const int idxY,const int idxZ) const {
......@@ -39,15 +39,13 @@ protected:
/** Alloc and init pre-vectors*/
void allocAndInit(){
temporaryMultiSource = new FComplexe[FF_MATRIX_COLUMN_DIM];
FHarmonic blasHarmonic(Parent::devP * 2);
// M2L transfer, there is a maximum of 3 neighbors in each direction,
// so 6 in each dimension
FReal treeWidthAtLevel = Parent::boxWidth * FReal( 1 << Parent::periodicLevels);
preM2LTransitions = new FComplexe*[Parent::treeHeight + Parent::periodicLevels];
memset(preM2LTransitions, 0, sizeof(FComplexe*) * (Parent::treeHeight + Parent::periodicLevels));
memset(preM2LTransitions.getPtr(), 0, sizeof(FComplexe*) * (Parent::treeHeight + Parent::periodicLevels));
for(int idxLevel = -Parent::periodicLevels ; idxLevel < Parent::treeHeight ; ++idxLevel ){
preM2LTransitions[idxLevel + Parent::periodicLevels] = new FComplexe[(7 * 7 * 7) * FF_MATRIX_SIZE];
......@@ -99,7 +97,9 @@ public:
: Parent(inDevP, inTreeHeight, inBoxWidth, inBoxCenter, inPeriodicLevel),
FF_MATRIX_ROW_DIM(Parent::harmonic.getExpSize()), FF_MATRIX_COLUMN_DIM(Parent::harmonic.getNExpSize()),
FF_MATRIX_SIZE(FF_MATRIX_ROW_DIM * FF_MATRIX_COLUMN_DIM),
temporaryMultiSource(0), preM2LTransitions(0){
temporaryMultiSource(new FComplexe[FF_MATRIX_COLUMN_DIM]),
preM2LTransitions(0){
allocAndInit();
}
......@@ -108,15 +108,16 @@ public:
: Parent(other),
FF_MATRIX_ROW_DIM(other.FF_MATRIX_ROW_DIM), FF_MATRIX_COLUMN_DIM(other.FF_MATRIX_COLUMN_DIM),
FF_MATRIX_SIZE(other.FF_MATRIX_SIZE),
temporaryMultiSource(0), preM2LTransitions(0) {
allocAndInit();
temporaryMultiSource(new FComplexe[FF_MATRIX_COLUMN_DIM]),
preM2LTransitions(other.preM2LTransitions) {
}
/** Destructor */
~FSphericalBlasKernel(){
delete[] temporaryMultiSource;
FMemUtils::DeleteAll(preM2LTransitions, Parent::treeHeight + Parent::periodicLevels);
delete[] preM2LTransitions;
if(preM2LTransitions.isLast()){
FMemUtils::DeleteAll(preM2LTransitions.getPtr(), Parent::treeHeight + Parent::periodicLevels);
}
}
/** M2L with a cell and all the existing neighbors */
......
......@@ -29,8 +29,8 @@ protected:
const int FF_MATRIX_COLUMN_DIM; //< The blas matrix number of columns
const int FF_MATRIX_SIZE; //< The blas matrix size
FComplexe* temporaryMultiSource; //< To perform the M2L without allocating at each call
FComplexe** preM2LTransitions; //< The pre-computation for the M2L based on the level and the 189 possibilities
FComplexe* temporaryMultiSource; //< To perform the M2L without allocating at each call
FSmartPointer<FComplexe*> preM2LTransitions; //< The pre-computation for the M2L based on the level and the 189 possibilities
/** To access te precomputed M2L transfer matrixes */
int indexM2LTransition(const int idxX,const int idxY,const int idxZ) const {
......@@ -39,7 +39,6 @@ protected:
/** Alloc and init pre-vectors*/
void allocAndInit(){
temporaryMultiSource = new FComplexe[FF_MATRIX_COLUMN_DIM];
FHarmonic blasHarmonic(Parent::devP * 2);
......@@ -47,7 +46,7 @@ protected:
// so 6 in each dimension
FReal treeWidthAtLevel = Parent::boxWidth * FReal( 1 << Parent::periodicLevels);
preM2LTransitions = new FComplexe*[Parent::treeHeight + Parent::periodicLevels];
memset(preM2LTransitions, 0, sizeof(FComplexe*) * (Parent::treeHeight + Parent::periodicLevels));
memset(preM2LTransitions.getPtr(), 0, sizeof(FComplexe*) * (Parent::treeHeight + Parent::periodicLevels));
for(int idxLevel = -Parent::periodicLevels ; idxLevel < Parent::treeHeight ; ++idxLevel ){
preM2LTransitions[idxLevel + Parent::periodicLevels] = new FComplexe[(7 * 7 * 7) * FF_MATRIX_SIZE];
......@@ -99,7 +98,8 @@ public:
: Parent(inDevP, inTreeHeight, inBoxWidth, inBoxCenter, inPeriodicLevel),
FF_MATRIX_ROW_DIM(Parent::harmonic.getExpSize()), FF_MATRIX_COLUMN_DIM(Parent::harmonic.getNExpSize()),
FF_MATRIX_SIZE(FF_MATRIX_ROW_DIM * FF_MATRIX_COLUMN_DIM),
temporaryMultiSource(0), preM2LTransitions(0){
temporaryMultiSource(new FComplexe[FF_MATRIX_COLUMN_DIM]),
preM2LTransitions(0){
allocAndInit();
}
......@@ -108,15 +108,17 @@ public:
: Parent(other),
FF_MATRIX_ROW_DIM(other.FF_MATRIX_ROW_DIM), FF_MATRIX_COLUMN_DIM(other.FF_MATRIX_COLUMN_DIM),
FF_MATRIX_SIZE(other.FF_MATRIX_SIZE),
temporaryMultiSource(0), preM2LTransitions(0) {
allocAndInit();
temporaryMultiSource(new FComplexe[FF_MATRIX_COLUMN_DIM]),
preM2LTransitions(other.preM2LTransitions) {
}
/** Destructor */
~FSphericalBlockBlasKernel(){
delete[] temporaryMultiSource;
FMemUtils::DeleteAll(preM2LTransitions, Parent::treeHeight + Parent::periodicLevels);
delete[] preM2LTransitions;
if(preM2LTransitions.isLast()){
FMemUtils::DeleteAll(preM2LTransitions.getPtr(), Parent::treeHeight + Parent::periodicLevels);
}
}
/** M2L with a cell and all the existing neighbors */
......
......@@ -25,7 +25,7 @@ protected:
const int devM2lP; //< A secondary P
FComplexe** preM2LTransitions; //< The pre-computation for the M2L based on the level and the 189 possibilities
FSmartPointer<FComplexe*> preM2LTransitions; //< The pre-computation for the M2L based on the level and the 189 possibilities
/** To access te pre computed M2L transfer vector */
int indexM2LTransition(const int idxX,const int idxY,const int idxZ) const {
......@@ -37,7 +37,7 @@ protected:
// M2L transfer, there is a maximum of 3 neighbors in each direction,
// so 6 in each dimension
preM2LTransitions = new FComplexe*[Parent::treeHeight + Parent::periodicLevels];
memset(preM2LTransitions, 0, sizeof(FComplexe*) * (Parent::treeHeight + Parent::periodicLevels));
memset(preM2LTransitions.getPtr(), 0, sizeof(FComplexe*) * (Parent::treeHeight + Parent::periodicLevels));
// We start from the higher level
FReal treeWidthAtLevel = Parent::boxWidth * FReal(1 << Parent::periodicLevels);
for(int idxLevel = -Parent::periodicLevels ; idxLevel < Parent::treeHeight ; ++idxLevel ){
......@@ -70,20 +70,23 @@ public:
*/
FSphericalKernel(const int inDevP, const int inTreeHeight, const FReal inBoxWidth, const F3DPosition& inBoxCenter, const int inPeriodicLevel = 0)
: Parent(inDevP, inTreeHeight, inBoxWidth, inBoxCenter, inPeriodicLevel),
devM2lP(int(((inDevP*2)+1) * ((inDevP*2)+2) * 0.5)), preM2LTransitions(0) {
devM2lP(int(((inDevP*2)+1) * ((inDevP*2)+2) * 0.5)),
preM2LTransitions(0) {
allocAndInit();
}
/** Copy constructor */
FSphericalKernel(const FSphericalKernel& other)
: Parent(other), devM2lP(other.devM2lP), preM2LTransitions(0) {
allocAndInit();
: Parent(other), devM2lP(other.devM2lP),
preM2LTransitions(other.preM2LTransitions) {
}
/** Destructor */
~FSphericalKernel(){
FMemUtils::DeleteAll(preM2LTransitions, Parent::treeHeight + Parent::periodicLevels);
delete[] preM2LTransitions;
if( preM2LTransitions.isLast() ){
FMemUtils::DeleteAll(preM2LTransitions.getPtr(), Parent::treeHeight + Parent::periodicLevels);
}
}
/** M2L with a cell and all the existing neighbors */
......
......@@ -340,7 +340,7 @@ protected:
const int devM2lP; //< A secondary P
RotationM2LTransfer** preM2LTransitions; //< The pre-computation for the M2L based on the level and the 189 possibilities
FSmartPointer<RotationM2LTransfer*> preM2LTransitions; //< The pre-computation for the M2L based on the level and the 189 possibilities
RotationInfo rotation_Info;
/** To access te pre computed M2L transfer vector */
......@@ -353,7 +353,7 @@ protected:
// M2L transfer, there is a maximum of 3 neighbors in each direction,
// so 6 in each dimension
preM2LTransitions = new RotationM2LTransfer*[Parent::treeHeight + Parent::periodicLevels];
memset(preM2LTransitions, 0, sizeof(FComplexe*) * (Parent::treeHeight + Parent::periodicLevels));
memset(preM2LTransitions.getPtr(), 0, sizeof(FComplexe*) * (Parent::treeHeight + Parent::periodicLevels));
// We start from the higher level
FReal treeWidthAtLevel = Parent::boxWidth * FReal(1 << Parent::periodicLevels);
for(int idxLevel = -Parent::periodicLevels ; idxLevel < Parent::treeHeight ; ++idxLevel ){
......@@ -387,25 +387,30 @@ public:
*/
FSphericalRotationKernel(const int inDevP, const int inTreeHeight, const FReal inBoxWidth, const F3DPosition& inBoxCenter, const int inPeriodicLevel = 0)
: Parent(inDevP, inTreeHeight, inBoxWidth, inBoxCenter, inPeriodicLevel),
devM2lP(int(((inDevP*2)+1) * ((inDevP*2)+2) * 0.5)), preM2LTransitions(0), rotation_Info(inDevP) {
devM2lP(int(((inDevP*2)+1) * ((inDevP*2)+2) * 0.5)),
preM2LTransitions(0),
rotation_Info(inDevP) {
allocAndInit();
}
/** Copy constructor */
FSphericalRotationKernel(const FSphericalRotationKernel& other)
: Parent(other), devM2lP(other.devM2lP), preM2LTransitions(0), rotation_Info(other.devP) {
allocAndInit();
: Parent(other), devM2lP(other.devM2lP),
preM2LTransitions(other.preM2LTransitions),
rotation_Info(other.devP) {
}
/** Destructor */
~FSphericalRotationKernel(){
for(int idxLevel = -Parent::periodicLevels ; idxLevel < Parent::treeHeight ; ++idxLevel ){
for(int idx = 0 ; idx < 7*7*7 ; ++idx ){
preM2LTransitions[idxLevel + Parent::periodicLevels][idx].~RotationM2LTransfer();
if( preM2LTransitions.isLast() ){
for(int idxLevel = -Parent::periodicLevels ; idxLevel < Parent::treeHeight ; ++idxLevel ){
for(int idx = 0 ; idx < 7*7*7 ; ++idx ){
preM2LTransitions[idxLevel + Parent::periodicLevels][idx].~RotationM2LTransfer();
}
delete[] reinterpret_cast<char*>(preM2LTransitions[idxLevel + Parent::periodicLevels]);
}
delete[] reinterpret_cast<char*>(preM2LTransitions[idxLevel + Parent::periodicLevels]);
}
delete[] preM2LTransitions;
}
/** M2L with a cell and all the existing neighbors */
......
#ifndef FSMARTPOINTER_HPP
#define FSMARTPOINTER_HPP
template <class ClassType>
class FSmartPointer {
ClassType* pointer;
int* counter;
public:
typedef ClassType ValueType;
FSmartPointer() : pointer(0), counter(0) {
}
FSmartPointer(ClassType* const inPointer) : pointer(0), counter(0) {
assign(inPointer);
}
FSmartPointer(const FSmartPointer& inPointer) : pointer(0), counter(0) {
assign(inPointer);
}
~FSmartPointer(){
release();
}
void operator=(ClassType* const inPointer){
assign(inPointer);
}
void operator=(const FSmartPointer& inPointer){
assign(inPointer);
}
void assign(ClassType* const inPointer){
release();
pointer = inPointer;
counter = new int;
(*counter) = 1;
}
void assign(const FSmartPointer& inPointer){
release();
pointer = inPointer.pointer;
counter = inPointer.counter;
if(counter) (*counter) = (*counter) + 1;
}
void release(){
if(counter){
(*counter) = (*counter) - 1;
if( (*counter) == 0 ){
delete pointer;
}
pointer = 0;
counter = 0;
}
}
bool isAssigned() const{
return pointer != 0;
}
bool isLast() const{
return counter && (*counter) == 1;
}
ClassType* getPtr(){
return pointer;
}
const ClassType* getPtr() const {
return pointer;
}
ClassType& operator[](const int& index){
return pointer[index];
}
const ClassType& operator[](const int& index) const {
return pointer[index];
}
ClassType& operator*(){
return (*pointer);
}
const ClassType& operator*() const {
return (*pointer);
}
ClassType* operator->(){
return pointer;
}
const ClassType* operator->() const {
return pointer;
}
operator const ClassType*() const {
return pointer;
}
operator ClassType*() {
return pointer;
}
};
#endif // FSMARTPOINTER_HPP
This diff is collapsed.
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