[Risolto] Magagna incomprensibile (per me) C++/Makefiles

david_e1
Ciao,
sto facendo un progettino in C++ è ho una magagna veramente strana. Allora sto realizzando una piccola libreria di calcolo SEM e ho creato una cartella con una serie di test e uno script che li esegue in successione e dovrebbe matchare i risultati ottenuti con dei valori di riferimento. Nel Makefile ho inserito un target check che non fa altro che lanciare tale script controllando che i file siano stati già compilati (altrimenti chiama il target di compilazione).

La cosa incredibile è che lo stesso identico codice mi calcola valori completamente diversi a seconda che io lanci lo script dal make o "a mano". Questo avviene sotto Linux, ma non sotto OS-X dove il risultato è indipendente da come ho lanciato il codice... Io non ho proprio idea del perché... su entrambi uso GNU/make, ma la versione sotto MAC è la 3.80 (ovviamente la Apple se non usa librerie ultra-antiquate...), mentre sotto Linux ho la 3.81 che veniva con Gentoo (con tutto il patchset di Gentoo).

Boh di seguito allego i file in gioco... l'intera libreria no perché sarebbe troppo.

Ecco lo script "regtest.sh", per ora non fa praticamente nulla:
#!/bin/bash

TESTS="integration polytest"

function die {
    echo "\$@"
    exit 1
}

for i in \${TESTS}; do
    ./\$i || die "\$i test failed".
done


Qui abbiamo il Makefile:
# User defined flags:
include config.mk

LIBDIR     = ./lib
LIBNAME    = spectral
LIB        = \$(LIBDIR)/lib\$(LIBNAME).a

M_CPPFLAGS = \$(CPPFLAGS) \
	     \$(HUMFPACK) \
	     \$(HBOOST) \
	     -I./src \
	     -DMPICH_IGNORE_CXX_SEEK

M_CXXFLAGS = \$(CXXFLAGS) 

M_LDFLAGS  = -L\$(LIBDIR) -l\$(LIBNAME) \
	     \$(LDFLAGS) \
	     \$(LAMD) \
	     \$(LUMFPACK) 

HDRSOBJ	   = src/adptproblem.hpp \
	     src/domain.hpp \
	     src/elementbase.hpp \
	     src/extdata.hpp \
	     src/integrator.hpp \
	     src/fem-mesh.hpp \
	     src/fem-integrator.hpp \
	     src/fem-solver.hpp \
	     src/functions.hpp \
	     src/mesh.hpp \
	     src/poly.hpp \
	     src/problem.hpp \
	     src/subproblem.hpp \
	     src/triangle.hpp

HDRSNOOBJ  = src/fem-base.hpp \
	     src/mapping.hpp \
	     src/point.hpp \
	     src/spectral \
	     src/typedefs.hpp 

TESTFILES  = test/integration.cpp \
	     test/polytest.cpp

HDRS       = \$(HDRSOBJ) \
	     \$(HDRSNOOBJ)

SRCS       = \$(HDRSOBJ:.hpp=.cpp)

OBJS	   = \$(SRCS:.cpp=.o)

TESTOBJS   = \$(TESTFILES:.cpp=.o)

TESTEXECS  = \$(TESTFILES:.cpp=)

all 	: \$(HDRS) \$(LIB) 

clean	:
	-\rm \$(OBJS)
	-\rm \$(LIB)
	-\rm \$(MAIN:.cpp=.o)
	-\rm \$(EXEC)
	-\rm \$(TESTOBJS)
	-\rm \$(TESTEXECS)
	-\cd doc && rm -rf html latex 

doc     : Doxyfile \$(SRCS) \$(HDRS) 
	doxygen Doxyfile
	cd doc/latex && \$(MAKE)

lib     : \$(LIB)

check   : test
	cd test && ./regtest.sh

test    : \$(LIB) \$(TESTOBJS) \$(TESTEXECS)

install : \$(LIB) \$(HDRS) doc
	mkdir -p \$(DESTDIR)/lib
	mkdir -p \$(DESTDIR)/share/doc
	mkdir -p \$(DESTDIR)/include/mpi-spectral
	\install -m 644 \$(HDRS) \$(DESTDIR)/include/mpi-spectral
	\install -m 644 \$(LIB) \$(DESTDIR)/lib
	cp -R doc/latex doc/html \$(DESTDIR)/share/doc

\$(LIB)  : \$(OBJS) \$(HDRS)
	ar ru \$(LIB) \$(OBJS)

\$(OBJS) : %.o: %.cpp
	\$(CXX) -c \$(M_CPPFLAGS) \$(M_CXXFLAGS) \$< -o \$@

\$(TESTOBJS) : %.o: %.cpp
	\$(CXX) -c \$(M_CPPFLAGS) \$(M_CXXFLAGS) \$< -o \$@

\$(TESTEXECS) : % : %.o
	\$(CXX) \$< \$(M_LDFLAGS) -o \$@
	\$(STRIP) \$@


e qui il config.mk per Linux (è un symlink a config.mk.linux).
# User defined flags

# ===================================================================
#  Basic Options
# ===================================================================

# -------------------------------------------------------------------
# C++ Compiler
# -------------------------------------------------------------------

CXX      = g++

# MPICH2:
#CXX      = mpicxx

# Other MPI2 implementations like OpenMPI (not tested!)
#CXX      = mpiCC

# -------------------------------------------------------------------
# Stripping options
# -------------------------------------------------------------------

# Don't strip, just touch... :)
STRIP    = touch

# Strip to remove all symbols
#STRIP    = strip

# -------------------------------------------------------------------
# C++ preprocessor options 
# -------------------------------------------------------------------

# Standard
CPPFLAGS =

# Don't Debug
#CPPFLAGS = -DNDEBUG

# -------------------------------------------------------------------
# C++ compiler options
# -------------------------------------------------------------------

# Debug
CXXFLAGS = -Wall -g -p

# Optimization:
#CXXFLAGS = -O3 -Wall -march=prescott -pipe

# Unsafe optimization:
#CXXFLAGS = -O3 -march=nocona -pipe -ffast-math

# -------------------------------------------------------------------
# C++ linker options
# -------------------------------------------------------------------

LDFLAGS  = 

# -------------------------------------------------------------------
# Install directory
# -------------------------------------------------------------------

DESTDIR  = /usr/local

# ===================================================================
#  External Libraries 
# ===================================================================

# -------------------------------------------------------------------
# AMD Library linker instruction
# -------------------------------------------------------------------

LAMD     = -lamd

# -------------------------------------------------------------------
# UMFPACK Library linker instruction
# -------------------------------------------------------------------

LUMFPACK = -lumfpack

# ===================================================================
#  External Headers 
# ===================================================================

# -------------------------------------------------------------------
# UMFPACK Headers:
# -------------------------------------------------------------------

HUMFPACK = -I/usr/include/umfpack

# -------------------------------------------------------------------
# BOOST Headers:
# -------------------------------------------------------------------

HBOOST   = -I/usr/include/boost

# vim: set ft=make :

quello per mac è analogo, cambiano le posizioni delle librerie...

Infine il sorgente del test che si comporta in maniera così bizzarra:
/*
MPI-spectral lib. solves elliptic problems using two level Schwartz
domain decomposition method for SEM.
Copyright (C) 2007, Proverbio Alessandro and Radice David

This program 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 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

# include<cassert>
# include<cmath>
# include<cstdlib>
# include<iostream>
# include<spectral>

# ifndef EPSILON
# undef EPSILON
# endif

# ifndef EPSILON2
# undef EPSILON2
# endif

# define EPSILON 1e-16
# define EPSILON2 1e-7

using namespace std;
using namespace spectral;

int compare(const void * a, const void * b) {
    double x( *(double*)a - *(double*)b );
    return (x<0)?(-1):(1);
};

struct Constant {
    double operator()(double x,double y) const {return 1.0;}
};

int main() {
    cout << "--------------------------------------------------------------\n";
    cout << "  integrator.cpp " << endl;
    cout << "--------------------------------------------------------------\n";

    // ================================================
    // Controllo generazione L10
    // ================================================
    Poly L(10);
    legendre(L);
    cout << "L10(x) = " << L << endl;

    // Coefficienti tabulati
    double coefficienti[] = {    46189.0/256.0 ,
                              - 109395.0/256.0 ,
                                 90090.0/256.0 ,
                              -  30030.0/256.0 ,
                                  3465.0/256.0 ,
                              -     63.0/256.0 };

    for(int i=0;i<=5;++i) {
        assert(abs(L[10-2*i]-coefficienti[i])<EPSILON);
    };

    for(int i=0;i<5;++i) {
        assert(abs(L[2*i+1])<EPSILON);
    };

    // ================================================
    // Controllo zeri di L10
    // ================================================
    double * roots;
    horner(L,1e-15,1e-15,roots);

    qsort(roots,10,sizeof(double),&(compare));

    cout << endl << "roots: " << endl;
    for(int i=0;i<10;++i) {
        cout << roots[i] << endl;
    }
    for(int i=0;i<5;++i) {
        assert(abs(roots[i]+roots[9-i])<EPSILON2);
    }

    // Zeri tabulati
    double zeri[] = { 0.148874338 ,
                      0.433395394 ,
                      0.679409568 ,
                      0.865063366 ,
                      0.973906528 };

    for(int i=0;i<5;++i) {
        assert(abs(roots[i+5]-zeri[i])<EPSILON2);
    }

    // ================================================
    // Controllo zeri di dL
    // ================================================

    L.setdegree(9);
    legendre(L);
    Poly dL(L.differentiate());

    cout << endl;
    cout << "L(x) = " << L << endl;
    cout << "dL(x) = " << dL << endl;

    cout << "Roots: " << endl;

    horner(dL,1e-10,1e-10,roots,(int)1e6);
    qsort(roots,8,sizeof(double),&(compare));

    for(int i=0;i<8;++i) {
        cout << roots[i] << "\t";
        cout << "L(" << roots[i] << ")=" << L(roots[i]) << "\t \t";
        cout << "dL(" << roots[i] << ")=" << dL(roots[i]) << endl;
    }
    
    cout << "L(1)=" << L(1.0) << endl;
    cout << "L(-1)=" << L(-1.0) << endl;

    for(int i=0;i<8;++i) {
        assert(abs(dL(roots[i]))<EPSILON2);
        assert(abs(L(roots[i]))>EPSILON2);
    }

    // ================================================
    // Controllo Integrazione costante
    // ================================================

    Integrator Int(10,1e-16,1e-16,(int)1e4);
    cout << endl;
    Point<double> A(-1.0,-1.0);
    Point<double> B(1.0,1.0);
    Constant c;

    cout << Int(c,A,B) << endl;
//    assert(abs(Int(c,A,B)-4)<EPSILON2);

}


Se qualcuno ha una qualche, anche vaghissima, idea di quale potrebbe essere la causa...

Risposte
david_e1
Risolto... era una mancata inizializzazione di un vettore che creava strani problemi. Il make non c'entrava nulla, semplicemente leggeva dati spazzatura dalla memoria.

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.