From f4fec8584a0738224ee00564ce215bf343a8f618 Mon Sep 17 00:00:00 2001 From: Fabio Roberto Vitello Date: Wed, 17 Jul 2019 11:02:03 +0200 Subject: [PATCH] Base Version of CoreApp with MPI+openMP --- GaiaGsrParSim | Bin 318454 -> 0 bytes Makefile | 80 +- Makefile.marconi_new | 38 - Makefile_marconi | 81 - a | 1 - aprod.c | 1118 ++++------ lsqr.c | 2511 +++++++++++----------- memRequest.c | 0 run_ppl.cmd | 28 + solvergaiaSim.c | 4769 +++++++++++++++++++----------------------- util.c | 0 util.h | 1 - 12 files changed, 3860 insertions(+), 4767 deletions(-) delete mode 100755 GaiaGsrParSim delete mode 100644 Makefile.marconi_new delete mode 100644 Makefile_marconi delete mode 100644 a mode change 100644 => 100755 memRequest.c create mode 100755 run_ppl.cmd mode change 100644 => 100755 util.c mode change 100644 => 100755 util.h diff --git a/GaiaGsrParSim b/GaiaGsrParSim deleted file mode 100755 index 0a6cb5c6896514f89dbcac26744e306710081b61..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 318454 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 diff --git a/Makefile b/Makefile index 60a1e38..aeaed93 100644 --- a/Makefile +++ b/Makefile @@ -1,89 +1,39 @@ # Gaia GSRPar Makefile -COMPILER = /opt/ompss/bin/mcc -##COMPILER = /opt/openmpi_icc/bin/mpic++ -COMPILERCPP = /opt/ompss/bin/mcxx --ompss -DOMP -##COMPILERCPP = /opt/openmpi_icc/bin/mpic++ +COMPILER = mpiicpc -qopenmp -DOMP +COMPILERCPP = mpiicpc -qopenmp -DOMP -CC = $(COMPILERCPP) +CC = $(COMPILER) CPP= $(COMPILERCPP) -CFITSIOLIB=/opt/cfitsio3_1_0/lib +CFITSIOLIB=/opt/cluster/cfitsio/intel/2017.1/lib/ +GAIAINC=/u/ubecciani/EuroExa/CoreApp7.2/src - - -GAIAINC=/home-volume/ube/Gaia/ParallelCodeV7/src7.2 - - - -GAIAGSR= aprod.o lsqrblas.o lsqr.o solvergaia.o util.o GAIAGSRSIM= aprod.o lsqrblas.o lsqr.o solvergaiaSim.o util.o -GAIAGSRFits2Bin= fits2bin.o util.o lsqrblas.o -GAIAGSRBin2Fits= bin2fits.o -GAIAGSRBin2Reduced= bin2reduced.o util.o lsqrblas.o -GAIAGSRCkEmptyCols= util.o ckemptycols.o lsqrblas.o -GAIAGSRBin2Asc= bin2asc.o -GAIAGSRChTask= changeTask.o -GAIAGSRRepairTask= ripristino.o MEMREQ= memRequest.o - -INCLUDE = -I$(GAIAINC) -I/opt/local/include -I/opt/openmpi_icc/include/ -I/opt/cfitsio3_1_0/include/ -I/opt/openmpi/include -pthread +##INCLUDE = -I$(GAIAINC) -I/opt/local/include -I/opt/local/include/mpich2 -I/opt/cluster/cfitsio/intel/2017.1/include/ +INCLUDE = -I$(GAIAINC) -I/opt/cluster/cfitsio/intel/2017.1/include/ #INCLUDE = -I$(GAIAINC) #CFLAGS= $(INCLUDE) -std=c99 -CPPFLAGS= $(INCLUDE) -g -fsanitize=address -mllvm -asan-stack -CPPFLAGS= $(INCLUDE) -LIB = -pthread -L/usr/local/pbspro/lib -Wl,-rpath -Wl,/usr/local/pbspro/lib -Wl,-rpath -Wl,/opt/openmpi/lib -Wl,--enable-new-dtags -L/opt/openmpi/lib -lmpi -L$(CFITSIOLIB) -lcfitsio -lm +#CPPFLAGS= $(INCLUDE) -g -fsanitize=address -mllvm -asan-stack +#CPPFLAGS= $(INCLUDE) -lirc -limf -lsvml +CPPFLAGS= $(INCLUDE) +LIB = -L$(CFITSIOLIB) -lcfitsio -lm -all: GaiaGsrParSim -####all: GaiaGsrPar MemReq GaiaGsrParSim GaiaFits2Bin GaiaBin2Fits GaiaBin2Reduced GaiaCkEmptyCols GaiaBin2Asc GaiaChTask GaiaRepTask +all: MemReq GaiaGsrParSim ###all: GaiaGsrPar MemReq GaiaGsrParTest GaiaFits2Bin GaiaBin2Fits GaiaBin2Reduced -ckemptycols.o: ckemptycols.cpp - $(CPP) $(CPPFLAGS) -c ckemptycols.cpp - -bin2fits.o: bin2fits.cpp - $(CPP) $(CPPFLAGS) -c bin2fits.cpp - -bin2asc.o: bin2asc.cpp - $(CPP) $(CPPFLAGS) -c bin2asc.cpp - - - -GaiaGsrPar: $(GAIAGSR) - $(CPP) $(CPPFLAGS) -o GaiaGsrPar $(GAIAGSR) $(INCLUDE) $(LIB) - -MemReq: $(MEMREQ) - $(CPP) $(CPPFLAGS) -o MemReq $(MEMREQ) $(INCLUDE) $(LIB) - GaiaGsrParSim: $(GAIAGSRSIM) $(CPP) $(CPPFLAGS) -o GaiaGsrParSim $(GAIAGSRSIM) $(INCLUDE) $(LIB) -GaiaFits2Bin: $(GAIAGSRFits2Bin) - $(CPP) $(CPPFLAGS) -o GaiaFits2Bin $(GAIAGSRFits2Bin) $(INCLUDE) $(LIB) - -GaiaBin2Fits: $(GAIAGSRBin2Fits) - $(CPP) $(CPPFLAGS) -o GaiaBin2Fits $(GAIAGSRBin2Fits) $(INCLUDE) $(LIB) - -GaiaBin2Reduced: $(GAIAGSRBin2Reduced) - $(CPP) $(CPPFLAGS) -o GaiaBin2Reduced $(GAIAGSRBin2Reduced) $(INCLUDE) $(LIB) - -GaiaBin2Asc: $(GAIAGSRBin2Asc) - $(CPP) $(CPPFLAGS) -o GaiaBin2Asc $(GAIAGSRBin2Asc) $(INCLUDE) $(LIB) - - -GaiaCkEmptyCols: $(GAIAGSRCkEmptyCols) - $(CPP) $(CPPFLAGS) -o GaiaCkEmptyCols $(GAIAGSRCkEmptyCols) $(LIB) - -GaiaChTask: $(GAIAGSRChTask) - $(CPP) -o GaiaChTask $(GAIAGSRChTask) $(LIB) +MemReq: $(MEMREQ) + $(CPP) $(CPPFLAGS) -o MemReq $(MEMREQ) $(INCLUDE) $(LIB) -GaiaRepTask: $(GAIAGSRRepairTask) - $(CPP) $(CPPFLAGS) -o GaiaRepairTask $(GAIAGSRRepairTask) $(LIB) - clean: rm -f *.o core + diff --git a/Makefile.marconi_new b/Makefile.marconi_new deleted file mode 100644 index d5ce443..0000000 --- a/Makefile.marconi_new +++ /dev/null @@ -1,38 +0,0 @@ -# Gaia GSRPar Makefile - -COMPILER = mpiicpc -qopenmp -DOMP -COMPILERCPP = mpiicpc -qopenmp -DOMP - -CC = $(COMPILER) -CPP= $(COMPILERCPP) - -CFITSIOLIB=$(CFITSIO_LIB) - -GAIAINC=. - -GAIAGSRSIM= aprod.o lsqrblas.o lsqr.o solvergaiaSim.o util.o -MEMREQ= memRequest.o - - -##INCLUDE = -I$(GAIAINC) -I/opt/local/include -I/opt/local/include/mpich2 -I/opt/cluster/cfitsio/intel/2017.1/include/ -INCLUDE = -I$(GAIAINC) -I$(CFITSIO_INC) -#INCLUDE = -I$(GAIAINC) -#CFLAGS= $(INCLUDE) -std=c99 -#CPPFLAGS= $(INCLUDE) -g -fsanitize=address -mllvm -asan-stack -#CPPFLAGS= $(INCLUDE) -lirc -limf -lsvml -CPPFLAGS= $(INCLUDE) -DOMP= -LIB = -L$(CFITSIOLIB) -lcfitsio -lm - - -all: GaiaGsrParSim -###all: GaiaGsrPar MemReq GaiaGsrParTest GaiaFits2Bin GaiaBin2Fits GaiaBin2Reduced - -GaiaGsrParSim: $(GAIAGSRSIM) - $(CPP) $(CPPFLAGS) -o GaiaGsrParSim $(GAIAGSRSIM) $(INCLUDE) $(LIB) - -MemReq: $(MEMREQ) - $(CPP) $(CPPFLAGS) -o MemReq $(MEMREQ) $(INCLUDE) $(LIB) - -clean: - rm -f *.o core - diff --git a/Makefile_marconi b/Makefile_marconi deleted file mode 100644 index 9e08b9f..0000000 --- a/Makefile_marconi +++ /dev/null @@ -1,81 +0,0 @@ -# Gaia GSRPar Makefile - -##COMPILER = mpiicpc -g -traceback -O3 -qopenmp -##COMPILERCPP = mpiicpc -g -traceback -O3 -qopenmp -COMPILER = mpiicpc -O3 -qopenmp -COMPILERCPP = mpiicpc -O3 -qopenmp - -CC = $(COMPILER) -CPP = $(COMPILERCPP) - - -# CFITSIOLIB=/opt/cfitsio/lib -#CFITSIOLIB=/cineca/prod/opt/libraries/cfitsio/3.390/intel--pe-xe-2016--binary/lib/ -CFITSIOLIB=$(CFITSIO_LIB) - -GAIAINC=. - - -GAIAGSR= aprod.o lsqrblas.o lsqr.o solvergaia.o util.o -GAIAGSRSIM= aprod.o lsqrblas.o lsqr.o solvergaiaSim.o util.o -GAIAGSRFits2Bin= fits2bin.o util.o lsqrblas.o -GAIAGSRBin2Fits= bin2fits.o -GAIAGSRBin2Reduced= bin2reduced.o util.o lsqrblas.o -GAIAGSRCkEmptyCols= util.o ckemptycols.o lsqrblas.o -GAIAGSRBin2Asc= bin2asc.o -GAIAGSRChTask= changeTask.o -GAIAGSRRepairTask= ripristino.o -MEMREQ= memRequest.o - - -# INCLUDE = -I$(GAIAINC) -I/opt/cfitsio/include -#INCLUDE = -I$(GAIAINC) -I/cineca/prod/opt/libraries/cfitsio/3.390/intel--pe-xe-2016--binary/include/ -INCLUDE = -I$(GAIAINC) -I$(CFITSIO_INC) -CPPFLAGS= $(INCLUDE) -DOMP= -LIB = -L$(CFITSIOLIB) -lcfitsio -lm - -all: GaiaGsrPar MemReq GaiaGsrParSim GaiaFits2Bin GaiaBin2Fits GaiaBin2Reduced GaiaCkEmptyCols GaiaBin2Asc GaiaChTask GaiaRepTask -###all: GaiaGsrPar MemReq GaiaGsrParTest GaiaFits2Bin GaiaBin2Fits GaiaBin2Reduced - -ckemptycols.o: ckemptycols.cpp - $(CPP) $(CPPFLAGS) -c ckemptycols.cpp - -bin2fits.o: bin2fits.cpp - $(CPP) $(CPPFLAGS) -c bin2fits.cpp - -bin2asc.o: bin2asc.cpp - $(CPP) $(CPPFLAGS) -c bin2asc.cpp - -GaiaGsrPar: $(GAIAGSR) - $(CPP) -o GaiaGsrPar $(GAIAGSR) $(INCLUDE) $(LIB) - -MemReq: $(MEMREQ) - $(CPP) -o MemReq $(MEMREQ) $(INCLUDE) $(LIB) - -GaiaGsrParSim: $(GAIAGSRSIM) - $(CPP) -o GaiaGsrParSim $(GAIAGSRSIM) $(INCLUDE) $(LIB) - -GaiaFits2Bin: $(GAIAGSRFits2Bin) - $(CPP) -o GaiaFits2Bin $(GAIAGSRFits2Bin) $(INCLUDE) $(LIB) - -GaiaBin2Fits: $(GAIAGSRBin2Fits) - $(CPP) -o GaiaBin2Fits $(GAIAGSRBin2Fits) $(INCLUDE) $(LIB) - -GaiaBin2Reduced: $(GAIAGSRBin2Reduced) - $(CPP) -o GaiaBin2Reduced $(GAIAGSRBin2Reduced) $(INCLUDE) $(LIB) - -GaiaBin2Asc: $(GAIAGSRBin2Asc) - $(CPP) -o GaiaBin2Asc $(GAIAGSRBin2Asc) $(INCLUDE) $(LIB) - -GaiaChTask: $(GAIAGSRChTask) - $(CPP) -o GaiaChTask $(GAIAGSRChTask) $(LIB) - -GaiaCkEmptyCols: $(GAIAGSRCkEmptyCols) - $(CPP) -o GaiaCkEmptyCols $(GAIAGSRCkEmptyCols) $(LIB) - -GaiaRepTask: $(GAIAGSRRepairTask) - $(CPP) $(CPPFLAGS) -o GaiaRepairTask $(GAIAGSRRepairTask) $(LIB) - -clean: - rm -f *.o core - diff --git a/a b/a deleted file mode 100644 index 8243688..0000000 --- a/a +++ /dev/null @@ -1 +0,0 @@ -scp *.c *.cpp *.h ubecciani@ssh.hca.bsc.es:/home/ubecciani/AVU-GSR/OMP/src/ diff --git a/aprod.c b/aprod.c index fa389f8..1e1507b 100644 --- a/aprod.c +++ b/aprod.c @@ -7,724 +7,458 @@ //#include "pardef.h" #include "util.h" void aprod(int mode, long int m, long int n, double *vVect, double *knownTerms, - double *systemMatrix, long int *matrixIndex, int *instrCol, int *instrConstrIlung, struct comData comlsqr, time_t *ompSec) + double *systemMatrix,long int *matrixIndex, int *instrCol,int *instrConstrIlung, struct comData comlsqr,time_t *ompSec) { - // Parallel definitions - int myid, nproc; +// Parallel definitions + int myid,nproc; long int *mapNoss, *mapNcoeff; - int nthreads, tid, ntasks; - long **mapForThread; - /// struct comData *comlsqr; - // + int nthreads, tid; + long **mapForThread; +/// struct comData *comlsqr; +// - FILE *fk, *fk0; + FILE *fk,*fk0; - double zero = 0.0; - double sum, yi; - long int l1, l2; - long int i, i1; - long int l, j, k; - int i2 = 0, j2 = 0, j3 = 0, na = 0; + double zero=0.0; + double sum, yi; + long int l1,l2; + long int i, i1; + long int l, j, k; + int i2=0,j2=0,j3=0,na=0; int setBound[4]; + + double localSum; + short nAstroPSolved=comlsqr.nAstroPSolved; - double localSum; - short nAstroPSolved = comlsqr.nAstroPSolved; - - long localAstro = comlsqr.VrIdAstroPDim * nAstroPSolved; - long localAstroMax = comlsqr.VrIdAstroPDimMax * nAstroPSolved; - // Initialize. - myid = comlsqr.myid; - nproc = comlsqr.nproc; - mapNcoeff = comlsqr.mapNcoeff; - mapNoss = comlsqr.mapNoss; - nthreads = comlsqr.nthreads; - ntasks= comlsqr.ntasks; + long localAstro= comlsqr.VrIdAstroPDim*nAstroPSolved; + long localAstroMax=comlsqr.VrIdAstroPDimMax*nAstroPSolved; +// Initialize. +myid=comlsqr.myid; +nproc=comlsqr.nproc; +mapNcoeff=comlsqr.mapNcoeff; +mapNoss=comlsqr.mapNoss; +nthreads=comlsqr.nthreads; +mapForThread=comlsqr.mapForThread; +int multMI=comlsqr.multMI; +long nparam=comlsqr.parOss; +short nAttAxes=comlsqr.nAttAxes; +int numOfExtStar=comlsqr.numOfExtStar; +int numOfBarStar=comlsqr.numOfBarStar; +int numOfExtAttCol=comlsqr.numOfExtAttCol; +long VrIdAstroPDimMax=comlsqr.VrIdAstroPDimMax; +int startingAttColExtConstr=comlsqr.startingAttColExtConstr; +int nOfElextObs=comlsqr.nOfElextObs; +int nEqExtConstr=comlsqr.nEqExtConstr; +int nOfElBarObs=comlsqr.nOfElBarObs; +int nEqBarConstr=comlsqr.nEqBarConstr; +int debugMode=comlsqr.debugMode; +short nInstrPSolved=comlsqr.nInstrPSolved; +int nOfInstrConstr=comlsqr.nOfInstrConstr; +int nElemIC=comlsqr.nElemIC; +short nAttP=comlsqr.nAttP; +short nGlobP=comlsqr.nGlobP; + +setBound[0]=comlsqr.setBound[0]; + setBound[1]=comlsqr.setBound[1]; + setBound[2]=comlsqr.setBound[2]; + setBound[3]=comlsqr.setBound[3]; + long nDegFreedomAtt=comlsqr.nDegFreedomAtt; + short nAttParAxis=comlsqr.nAttParAxis; + long offsetAttParam=comlsqr.offsetAttParam; + long offsetInstrParam=comlsqr.offsetInstrParam; + long offsetGlobParam=comlsqr.offsetGlobParam; + +nthreads=1; +tid=0; + FILE *fp1,*fp2; +// fp1=fopen("test1_aprod","w"); +// fp2=fopen("test2_aprod","w"); - mapForThread = comlsqr.mapForThread; - int multMI = comlsqr.multMI; - long nparam = comlsqr.parOss; - short nAttAxes = comlsqr.nAttAxes; - int numOfExtStar = comlsqr.numOfExtStar; - int numOfBarStar = comlsqr.numOfBarStar; - int numOfExtAttCol = comlsqr.numOfExtAttCol; - long VrIdAstroPDimMax = comlsqr.VrIdAstroPDimMax; - int startingAttColExtConstr = comlsqr.startingAttColExtConstr; - int nOfElextObs = comlsqr.nOfElextObs; - int nEqExtConstr = comlsqr.nEqExtConstr; - int nOfElBarObs = comlsqr.nOfElBarObs; - int nEqBarConstr = comlsqr.nEqBarConstr; - int debugMode = comlsqr.debugMode; - short nInstrPSolved = comlsqr.nInstrPSolved; - int nOfInstrConstr = comlsqr.nOfInstrConstr; - int nElemIC = comlsqr.nElemIC; - short nAttP = comlsqr.nAttP; - short nGlobP = comlsqr.nGlobP; - - setBound[0] = comlsqr.setBound[0]; - setBound[1] = comlsqr.setBound[1]; - setBound[2] = comlsqr.setBound[2]; - setBound[3] = comlsqr.setBound[3]; - long nDegFreedomAtt = comlsqr.nDegFreedomAtt; - short nAttParAxis = comlsqr.nAttParAxis; - long offsetAttParam = comlsqr.offsetAttParam; - long offsetInstrParam = comlsqr.offsetInstrParam; - long offsetGlobParam = comlsqr.offsetGlobParam; - //nthreads = 1; - tid = 0; - FILE *fp1, *fp2; - // fp1=fopen("test1_aprod","w"); - // fp2=fopen("test2_aprod","w"); - if (mode != 1 && mode != 2) - { - printf("ERROR: Invalid mode=%d in aprod function\n", mode); - exit(1); - } - l1 = 0; - l2 = 0; - myid = comlsqr.myid; - if (mode == 1) +if(mode!=1 && mode !=2) +{ + printf("ERROR: Invalid mode=%d in aprod function\n",mode); + exit(1); +} +l1=0; +l2=0; +myid=comlsqr.myid; +if(mode==1) +{ + time_t startTime=time(NULL); +#pragma omp parallel private(myid, sum, k, l1, l2, l, j,tid,nthreads,i2,na) shared(mapNoss,instrCol,comlsqr,vVect,systemMatrix,matrixIndex,knownTerms,j2) { - time_t startTime = time(NULL); -//// #pragma omp parallel private(myid, sum, k, l1, l2, l, j, tid, nthreads, i2, na) shared(mapNoss, instrCol, comlsqr, vVect, systemMatrix, matrixIndex, knownTerms, j2) + myid=comlsqr.myid; + if(comlsqr.itn==1) { - myid = comlsqr.myid; - /* - //FV_ EDIT ompSs - if (comlsqr.itn == 1) - { - #ifdef OMP - tid = omp_get_thread_num(); - nthreads = omp_get_num_threads(); - #endif - }*/ - if (comlsqr.itn == 1 && debugMode) - printf("PE=%d Aprod1 OpenMP num of threads =%d from thread =%d icycle=%ld comlsqr.itn=%d\n", myid, nthreads, tid, i, comlsqr.itn); - long miValAstro = 0; - long miValAtt = 0; - long jstartAtt = 0; - long jstartAstro = 0; - long lset = 0; - long offLocalAstro = 0; - long offLocalAtt = 0; - long offLocalInstr = 0; //Offset on Instruments - long ixInstr = 0; - int nInstrVal = 0; - offLocalInstr = offsetInstrParam + (localAstroMax - offsetAttParam); //Offset on Instruments - nInstrVal = nAstroPSolved + nAttP; - offLocalAstro = comlsqr.mapStar[myid][0] * nAstroPSolved; //Offset on my mstars - offLocalAtt = localAstroMax - offsetAttParam; //Offset on attitude - long offLocalGlob = offsetGlobParam + (localAstroMax - offsetAttParam); //Offset on GlobP - int nGlobVal = nAstroPSolved + nAttP + nInstrPSolved; - jstartAstro = miValAstro - offLocalAstro; - - //FV_ EDIT ompSs - - - for(int nt=0; nt < ntasks; nt++ ) - { - #pragma omp task //shared(matrixIndex,mapForThread,vVect,systemMatrix,knownTerms) in(nt,multMI,offLocalAstro, lset) - { - for (long ix = mapForThread[nt][0]; ix < mapForThread[nt][2]; ix++) - { - sum = 0.; - ///////////////////////////////////////////////////// - /// Mode 1 Astrometric Sect - if (nAstroPSolved) - { - - lset = ix * nparam; - if (matrixIndex[multMI * ix] != miValAstro) - { - miValAstro = matrixIndex[multMI * ix]; - jstartAstro = miValAstro - offLocalAstro; - } - for (long jx = jstartAstro; jx < jstartAstro + nAstroPSolved; jx++) - { - sum = sum + systemMatrix[lset] * vVect[jx]; - lset++; - } - } - ////////////////////////////////////////////////////// - /// Mode 1 Attitude Sect - if (nAttP) - { - lset = ix * nparam + nAstroPSolved; - miValAtt = matrixIndex[multMI * ix + (multMI - 1)]; - for (int nax = 0; nax < nAttAxes; nax++) - { - jstartAtt = miValAtt + offLocalAtt + nax * nDegFreedomAtt; - for (long inpax = jstartAtt; inpax < jstartAtt + nAttParAxis; inpax++) - { - sum = sum + systemMatrix[lset] * vVect[inpax]; - lset++; - } - } - } - ////////////////////////////////////////////////////// - /// Mode 1 Instrument Sect - if (nInstrPSolved) - { - - lset = ix * nparam + nInstrVal; - long iiVal = ix * nInstrPSolved; - for (int inInstr = 0; inInstr < nInstrPSolved; inInstr++) - { - ixInstr = offLocalInstr + instrCol[iiVal + inInstr]; - sum = sum + systemMatrix[lset] * vVect[ixInstr]; - lset++; - } - } - ////////////////////////////////////////////////////// - /// Mode 1 Global sect - if (nGlobP) - { - lset = ix * nparam + nGlobVal; - for (long inGlob = offLocalGlob; inGlob < offLocalGlob + nGlobP; inGlob++) - { - sum = sum + systemMatrix[lset] * vVect[inGlob]; - lset++; - } - } - ////////////////////////////////////////////////////// - knownTerms[ix] += sum; - } //for ix - } - #pragma omp taskwait - - } - - - - - - - - /* - //#pragma omp for - for (long ix = 0; ix < mapNoss[myid]; ix++) - { - sum = 0.; - ///////////////////////////////////////////////////// - /// Mode 1 Astrometric Sect - if (nAstroPSolved) - { - - lset = ix * nparam; - if (matrixIndex[multMI * ix] != miValAstro) - { - miValAstro = matrixIndex[multMI * ix]; - jstartAstro = miValAstro - offLocalAstro; - } - for (long jx = jstartAstro; jx < jstartAstro + nAstroPSolved; jx++) - { - sum = sum + systemMatrix[lset] * vVect[jx]; - lset++; - } - } - ////////////////////////////////////////////////////// - /// Mode 1 Attitude Sect - if (nAttP) - { - lset = ix * nparam + nAstroPSolved; - miValAtt = matrixIndex[multMI * ix + (multMI - 1)]; - for (int nax = 0; nax < nAttAxes; nax++) - { - jstartAtt = miValAtt + offLocalAtt + nax * nDegFreedomAtt; - for (long inpax = jstartAtt; inpax < jstartAtt + nAttParAxis; inpax++) - { - sum = sum + systemMatrix[lset] * vVect[inpax]; - lset++; - } - } - } - ////////////////////////////////////////////////////// - /// Mode 1 Instrument Sect - if (nInstrPSolved) - { +#ifdef OMP + tid = omp_get_thread_num(); + nthreads = omp_get_num_threads(); +#endif + } + if(comlsqr.itn==1 && debugMode) + printf("PE=%d Aprod1 OpenMP num of threads =%d from thread =%d icycle=%ld comlsqr.itn=%d\n",myid, nthreads,tid,i,comlsqr.itn); + long miValAstro=0; + long miValAtt=0; + long jstartAtt=0; + long jstartAstro=0; + long lset=0; + long offLocalAstro=0; + long offLocalAtt=0; + long offLocalInstr=0; //Offset on Instruments + long ixInstr=0; + int nInstrVal=0; + offLocalInstr=offsetInstrParam+(localAstroMax-offsetAttParam); //Offset on Instruments + nInstrVal=nAstroPSolved+nAttP; + offLocalAstro=comlsqr.mapStar[myid][0]*nAstroPSolved; //Offset on my mstars + offLocalAtt=localAstroMax-offsetAttParam; //Offset on attitude + long offLocalGlob=offsetGlobParam+(localAstroMax-offsetAttParam); //Offset on GlobP + int nGlobVal=nAstroPSolved+nAttP+nInstrPSolved; + jstartAstro=miValAstro-offLocalAstro; - lset = ix * nparam + nInstrVal; - long iiVal = ix * nInstrPSolved; - for (int inInstr = 0; inInstr < nInstrPSolved; inInstr++) - { - ixInstr = offLocalInstr + instrCol[iiVal + inInstr]; - sum = sum + systemMatrix[lset] * vVect[ixInstr]; - lset++; - } - } - ////////////////////////////////////////////////////// - /// Mode 1 Global sect - if (nGlobP) - { - lset = ix * nparam + nGlobVal; - for (long inGlob = offLocalGlob; inGlob < offLocalGlob + nGlobP; inGlob++) - { - sum = sum + systemMatrix[lset] * vVect[inGlob]; - lset++; - } - } - ////////////////////////////////////////////////////// - knownTerms[ix] += sum; - } //for ix - */ - - - - - /// Mode 1 ExtConstr - if (nEqExtConstr) - { - long offExtAtt; - long offExtAttConstr = VrIdAstroPDimMax * nAstroPSolved + startingAttColExtConstr; - long vVIx; - long ktIx = mapNoss[myid]; - long offExtConstr; - for (int iexc = 0; iexc < nEqExtConstr; iexc++) - { - sum = 0.0; - offExtConstr = mapNcoeff[myid] + iexc * nOfElextObs; - //FV_ EDIT ompSs - //#pragma omp for - for (int j3 = 0; j3 < numOfExtStar * nAstroPSolved; j3++) - sum += systemMatrix[offExtConstr + j3] * vVect[j3]; - for (int nax = 0; nax < nAttAxes; nax++) - { - offExtAtt = offExtConstr + numOfExtStar * nAstroPSolved + nax * numOfExtAttCol; - vVIx = offExtAttConstr + nax * nDegFreedomAtt; - //FV_ EDIT ompSs - //#pragma omp for - for (int j3 = 0; j3 < numOfExtAttCol; j3++) - sum += systemMatrix[offExtAtt + j3] * vVect[vVIx + j3]; - } - //FV_ EDIT ompSs - //#pragma omp atomic - knownTerms[ktIx + iexc] += sum; - } //for iexc - } - ////////////////////////////////////////////////////// - /// Mode 1 BarConstr - if (nEqBarConstr) - { - long offBarConstr = mapNcoeff[myid] + nOfElextObs * nEqExtConstr; - long offBarConstrIx; - long ktIx = mapNoss[myid] + nEqExtConstr; - for (int iexc = 0; iexc < nEqBarConstr; iexc++) - { - sum = 0.0; - offBarConstrIx = offBarConstr + iexc * nOfElBarObs; - //FV_ EDIT ompSs - //#pragma omp for - for (int j3 = 0; j3 < numOfBarStar * nAstroPSolved; j3++) - sum += systemMatrix[offBarConstrIx + j3] * vVect[j3]; - //FV_ EDIT ompSs - //#pragma omp atomic - knownTerms[ktIx + iexc] += sum; - } //for iexc - } - ////////////////////////////////////////////////////// - /// Mode 1 InstrConstr - if (nOfInstrConstr) +#pragma omp for + for(long ix=0;ix ZERO, - wantse = standardError != NULL; -long int i; -int - maxdx, - nconv, nstop; -double - alfopt, - alpha, arnorm0, beta, bnorm, - cs, cs1, cs2, ctol, - delta, dknorm, dknormSum, dnorm, dxk, dxmax, - gamma, gambar, phi, phibar, psi, - res2, rho, rhobar, rhbar1, - rhs, rtol, sn, sn1, sn2, - t, tau, temp, test1, test2, test3, - theta, t1, t2, t3, xnorm1, z, zbar; -char - enter[] = "Enter LSQR. ", - exitLsqr[] = "Exit LSQR. ", - msg[6][100] = + const bool + extra = false, // true for extra printing below. + damped = damp > ZERO, + wantse = standardError != NULL; + long int i; + int + maxdx, nconv, nstop; + double + alfopt, alpha, arnorm0, beta, bnorm, + cs, cs1, cs2, ctol, + delta, dknorm, dknormSum, dnorm, dxk, dxmax, + gamma, gambar, phi, phibar, psi, + res2, rho, rhobar, rhbar1, + rhs, rtol, sn, sn1, sn2, + t, tau, temp, test1, test2, test3, + theta, t1, t2, t3, xnorm1, z, zbar; + char + enter[] = "Enter LSQR. ", + exitLsqr[] = "Exit LSQR. ", + msg[6][100] = { {"The exact solution is x = 0"}, {"A solution to Ax = b was found, given atol, btol"}, {"A least-squares solution was found, given atol"}, {"A damped least-squares solution was found, given atol"}, {"Cond(Abar) seems to be too large, given conlim"}, - {"The iteration limit was reached"}}; -char lsqrOut[] = "lsqr-output"; // (buffer flush problem) -char wpath[1024]; -size_t sizePath = 1020; - + {"The iteration limit was reached"} + }; + char lsqrOut[] = "lsqr-output"; // (buffer flush problem) + char wpath[1024]; + size_t sizePath=1020; + //----------------------------------------------------------------------- // Format strings. -char fmt_1000[] = - " %s Least-squares solution of Ax = b\n" - " The matrix A has %ld rows and %ld columns\n" - " damp = %-22.2e wantse = %10i\n" - " atol = %-22.2e conlim = %10.2e\n" - " btol = %-22.2e itnlim = %10d\n\n"; -char fmt_1200[] = - " Itn x(1) Function" - " Compatible LS Norm A Cond A\n"; -char fmt_1300[] = - " Itn x(1) Function" - " Compatible LS Norm Abar Cond Abar\n"; -char fmt_1400[] = - " phi dknorm dxk alfa_opt\n"; -char fmt_1500_extra[] = - " %6d %16.9e %16.9e %9.2e %9.2e %8.1e %8.1e %8.1e %7.1e %7.1e %7.1e\n"; -char fmt_1500[] = - " %6d %16.9e %16.9e %9.2e %9.2e %8.1e %8.1e\n"; -char fmt_1550[] = - " %6d %16.9e %16.9e %9.2e %9.2e\n"; -char fmt_1600[] = - "\n"; -char fmt_2000[] = - "\n" - " %s istop = %-10d itn = %-10d\n" - " %s anorm = %11.5e acond = %11.5e\n" - " %s vnorm = %11.5e xnorm = %11.5e\n" - " %s rnorm = %11.5e arnorm = %11.5e\n"; -char fmt_2100[] = - " %s max dx = %7.1e occured at itn %-9d\n" - " %s = %7.1e*xnorm\n"; -char fmt_3000[] = - " %s %s\n"; + char fmt_1000[] = + " %s Least-squares solution of Ax = b\n" + " The matrix A has %ld rows and %ld columns\n" + " damp = %-22.2e wantse = %10i\n" + " atol = %-22.2e conlim = %10.2e\n" + " btol = %-22.2e itnlim = %10d\n\n"; + char fmt_1200[] = + " Itn x(1) Function" + " Compatible LS Norm A Cond A\n"; + char fmt_1300[] = + " Itn x(1) Function" + " Compatible LS Norm Abar Cond Abar\n"; + char fmt_1400[] = + " phi dknorm dxk alfa_opt\n"; + char fmt_1500_extra[] = + " %6d %16.9e %16.9e %9.2e %9.2e %8.1e %8.1e %8.1e %7.1e %7.1e %7.1e\n"; + char fmt_1500[] = + " %6d %16.9e %16.9e %9.2e %9.2e %8.1e %8.1e\n"; + char fmt_1550[] = + " %6d %16.9e %16.9e %9.2e %9.2e\n"; + char fmt_1600[] = + "\n"; + char fmt_2000[] = + "\n" + " %s istop = %-10d itn = %-10d\n" + " %s anorm = %11.5e acond = %11.5e\n" + " %s vnorm = %11.5e xnorm = %11.5e\n" + " %s rnorm = %11.5e arnorm = %11.5e\n"; + char fmt_2100[] = + " %s max dx = %7.1e occured at itn %-9d\n" + " %s = %7.1e*xnorm\n"; + char fmt_3000[] = + " %s %s\n"; ///////////// Specific definitions -time_t startCycleTime, endCycleTime, totTime, partialTime, CPRtimeStart, CPRtimeEnd, ompSec = 0; -int writeCPR; //=0 no write CPR, =1 write CPR and continue, =2 write CPR and return -int noCPR; -int myid, nproc; -long int *mapNoss, *mapNcoeff; -MPI_Status status; -long int nunkSplit, localAstro, localAstroMax, other; -int nAstroElements; -int debugMode; -long VrIdAstroPDim, VrIdAstroPDimMax; -long nDegFreedomAtt; -int nAttAxes; -int nAttParam, nInstrParam, nGlobalParam, itnTest, nAttP, numOfExtStar, numOfBarStar, numOfExtAttCol, nobs; -long mapNossBefore; -short nAstroPSolved, nInstrPsolved; -double cycleStartMpiTime, cycleEndMpiTime; -double *vAuxVect; -int CPRCount; -FILE *fpCPRend, *nout, *fpItnLimitNew; -int nEqExtConstr, nEqBarConstr; -int nElemIC, nOfInstrConstr; -double *kAuxcopy; -double *kcopy; -int ntasks; -int nthreads; -//////////////////////////////// + time_t startCycleTime,endCycleTime,totTime,partialTime,CPRtimeStart,CPRtimeEnd,ompSec=0; + int writeCPR; //=0 no write CPR, =1 write CPR and continue, =2 write CPR and return + int noCPR; + int myid,nproc; + long int *mapNoss, *mapNcoeff; + MPI_Status status; + long int nunkSplit, localAstro, localAstroMax, other; + int nAstroElements; + int debugMode; + long VrIdAstroPDim, VrIdAstroPDimMax; + long nDegFreedomAtt; + int nAttAxes; + int nAttParam,nInstrParam,nGlobalParam,itnTest,nAttP,numOfExtStar,numOfBarStar,numOfExtAttCol,nobs; + long mapNossBefore; + short nAstroPSolved,nInstrPsolved; + double cycleStartMpiTime, cycleEndMpiTime; + double *vAuxVect; + int CPRCount; + FILE *fpCPRend, *nout, *fpItnLimitNew; + int nEqExtConstr,nEqBarConstr; + int nElemIC,nOfInstrConstr; + double *kAuxcopy; + double *kcopy; +//////////////////////////////// // Initialize. -myid = comlsqr.myid; -nproc = comlsqr.nproc; -mapNcoeff = comlsqr.mapNcoeff; -mapNoss = comlsqr.mapNoss; -nAttParam = comlsqr.nAttParam; -nInstrParam = comlsqr.nInstrParam; -nGlobalParam = comlsqr.nGlobalParam; -nunkSplit = comlsqr.nunkSplit; -VrIdAstroPDim = comlsqr.VrIdAstroPDim; -VrIdAstroPDimMax = comlsqr.VrIdAstroPDimMax; -nAstroPSolved = comlsqr.nAstroPSolved; -nEqExtConstr = comlsqr.nEqExtConstr; -nEqBarConstr = comlsqr.nEqBarConstr; -nDegFreedomAtt = comlsqr.nDegFreedomAtt; -nAttAxes = comlsqr.nAttAxes; -localAstro = VrIdAstroPDim * nAstroPSolved; -localAstroMax = VrIdAstroPDimMax * nAstroPSolved; -numOfExtStar = comlsqr.numOfExtStar; -numOfBarStar = comlsqr.numOfBarStar; -nAttP = comlsqr.nAttP; -numOfExtAttCol = comlsqr.numOfExtAttCol; -mapNossBefore = comlsqr.mapNossBefore; -nobs = comlsqr.nobs; -debugMode = comlsqr.debugMode; -noCPR = comlsqr.noCPR; -nElemIC = comlsqr.nElemIC; -nOfInstrConstr = comlsqr.nOfInstrConstr; -nInstrPsolved = comlsqr.nInstrPSolved; -ntasks= comlsqr.ntasks; -nthreads= comlsqr.nthreads; - - other = (long)nAttParam + nInstrParam + nGlobalParam; -if (nAstroPSolved) - vAuxVect = (double *)calloc(localAstroMax, sizeof(double)); - -comlsqr.itn = itn; -totTime = comlsqr.totSec; -partialTime = comlsqr.totSec; - -if (debugMode) -{ - for (long i = 0; i < mapNoss[myid] + nEqExtConstr + nEqBarConstr + nOfInstrConstr; i++) - { - printf("PE=%d Knowterms[%d]=%e\n", myid, i, knownTerms[i]); +myid=comlsqr.myid; +nproc=comlsqr.nproc; +mapNcoeff=comlsqr.mapNcoeff; +mapNoss=comlsqr.mapNoss; +nAttParam=comlsqr.nAttParam; +nInstrParam=comlsqr.nInstrParam; +nGlobalParam=comlsqr.nGlobalParam; +nunkSplit=comlsqr.nunkSplit; +VrIdAstroPDim=comlsqr.VrIdAstroPDim; +VrIdAstroPDimMax=comlsqr.VrIdAstroPDimMax; +nAstroPSolved=comlsqr.nAstroPSolved; +nEqExtConstr=comlsqr.nEqExtConstr; +nEqBarConstr=comlsqr.nEqBarConstr; +nDegFreedomAtt=comlsqr.nDegFreedomAtt; +nAttAxes=comlsqr.nAttAxes; +localAstro= VrIdAstroPDim*nAstroPSolved; +localAstroMax=VrIdAstroPDimMax*nAstroPSolved; +numOfExtStar=comlsqr.numOfExtStar; +numOfBarStar=comlsqr.numOfBarStar; +nAttP=comlsqr.nAttP; +numOfExtAttCol=comlsqr.numOfExtAttCol; +mapNossBefore=comlsqr.mapNossBefore; +nobs=comlsqr.nobs; +debugMode=comlsqr.debugMode; +noCPR=comlsqr.noCPR; +nElemIC=comlsqr.nElemIC; +nOfInstrConstr=comlsqr.nOfInstrConstr; +nInstrPsolved=comlsqr.nInstrPSolved; + +other=(long)nAttParam + nInstrParam + nGlobalParam; +if(nAstroPSolved) vAuxVect=(double *) calloc(localAstroMax,sizeof(double)); + +comlsqr.itn=itn; +totTime=comlsqr.totSec; +partialTime=comlsqr.totSec; + + if(debugMode){ + for(long i=0; i ZERO) - ctol = ONE / conlim; -anorm = ZERO; -acond = ZERO; -dnorm = ZERO; -dxmax = ZERO; -res2 = ZERO; -psi = ZERO; -xnorm = ZERO; -xnorm1 = ZERO; -cs2 = -ONE; -sn2 = ZERO; -z = ZERO; - -CPRCount = 0; +itn = 0; +istop = 0; +nstop = 0; +maxdx = 0; +ctol = ZERO; +if (conlim > ZERO) ctol = ONE / conlim; +anorm = ZERO; +acond = ZERO; +dnorm = ZERO; +dxmax = ZERO; +res2 = ZERO; +psi = ZERO; +xnorm = ZERO; +xnorm1 = ZERO; +cs2 = - ONE; +sn2 = ZERO; +z = ZERO; + +CPRCount=0; // ------------------------------------------------------------------ // Set up the first vectors u and v for the bidiagonalization. // These satisfy beta*u = b, alpha*v = A(transpose)*u. // ------------------------------------------------------------------ -dload(nunkSplit, 0.0, vVect); -dload(nunkSplit, 0.0, xSolution); -if (wantse) - dload(nunkSplit, 0.0, standardError); -alpha = ZERO; +dload( nunkSplit, 0.0, vVect ); +dload( nunkSplit, 0.0, xSolution ); +if ( wantse ) + dload( nunkSplit, 0.0, standardError ); +alpha = ZERO; // Find the maximum value on u -double betaLoc; -if (myid == 0) - betaLoc = cblas_dnrm2(mapNoss[myid] + nEqExtConstr + nEqBarConstr + nOfInstrConstr, knownTerms, 1); -else - betaLoc = cblas_dnrm2(mapNoss[myid], knownTerms, 1); + double betaLoc; + if(myid==0) betaLoc=cblas_dnrm2(mapNoss[myid]+nEqExtConstr+nEqBarConstr+nOfInstrConstr,knownTerms,1); + else betaLoc=cblas_dnrm2(mapNoss[myid],knownTerms,1); -double betaLoc2 = betaLoc * betaLoc; +double betaLoc2=betaLoc*betaLoc; double betaGlob; -MPI_Allreduce(&betaLoc2, &betaGlob, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); -beta = sqrt(betaGlob); -if (beta > ZERO) +MPI_Allreduce(&betaLoc2, &betaGlob,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); +beta=sqrt(betaGlob); +if (beta > ZERO) { - cblas_dscal(mapNoss[myid] + nEqExtConstr + nEqBarConstr + nOfInstrConstr, (ONE / beta), knownTerms, 1); - MPI_Barrier(MPI_COMM_WORLD); + cblas_dscal ( mapNoss[myid]+nEqExtConstr+nEqBarConstr+nOfInstrConstr, (ONE / beta), knownTerms, 1 ); + MPI_Barrier(MPI_COMM_WORLD); //only processor 0 accumulate and distribute the v array -//// - - // FV EDIT - //#pragma omp for - for (i = 0; i < localAstroMax; i++) - { - vAuxVect[i] = vVect[i]; - vVect[i] = 0; - } - if (myid != 0) +#pragma omp for + for(i=0;i ZERO) { - double alphaOther = cblas_dnrm2(comlsqr.nunkSplit - localAstroMax, &vVect[localAstroMax], 1); - double alphaOther2 = alphaOther * alphaOther; - alphaLoc2 = alphaLoc2 + alphaOther2; + cblas_dscal ( nunkSplit, (ONE / alpha), vVect, 1 ); + cblas_dcopy ( nunkSplit, vVect, 1, wVect, 1 ); } - double alphaGlob2 = 0; - MPI_Allreduce(&alphaLoc2, &alphaGlob2, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - alpha = sqrt(alphaGlob2); -} - -if (alpha > ZERO) -{ - cblas_dscal(nunkSplit, (ONE / alpha), vVect, 1); - cblas_dcopy(nunkSplit, vVect, 1, wVect, 1); -} // printf("LSQR T4: PE=%d alpha=%15.12lf beta=%15.12lf arnorm=%15.12lf\n",myid,alpha,beta,arnorm); -arnorm = alpha * beta; -arnorm0 = arnorm; + arnorm = alpha * beta; + arnorm0 = arnorm; // printf("LSQR T5: PE=%d alpha=%15.12lf beta=%15.12lf arnorm=%15.12lf\n",myid,alpha,beta,arnorm); -if (arnorm == ZERO) - goto goto_800; -rhobar = alpha; -phibar = beta; -bnorm = beta; -rnorm = beta; + if (arnorm == ZERO) goto goto_800; + rhobar = alpha; + phibar = beta; + bnorm = beta; + rnorm = beta; -if (myid == 0) -{ - nout = fopen(lsqrOut, "a"); - if (nout != NULL) - { - if (damped) - fprintf(nout, fmt_1300); - else - fprintf(nout, fmt_1200); - } - else + if (myid==0) { - printf("Error while opening %s (2)\n", lsqrOut); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); + nout=fopen(lsqrOut,"a"); + if ( nout != NULL) { + if ( damped ) + fprintf(nout, fmt_1300); + else + fprintf(nout, fmt_1200); + } else { + printf("Error while opening %s (2)\n",lsqrOut); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + + test1 = ONE; + test2 = alpha / beta; + + if ( extra ) + fprintf(nout, fmt_1400); + + fprintf(nout, fmt_1550, itn, xSolution[0], rnorm, test1, test2); + fprintf(nout, fmt_1600); + fclose(nout); } - test1 = ONE; - test2 = alpha / beta; - - if (extra) - fprintf(nout, fmt_1400); - - fprintf(nout, fmt_1550, itn, xSolution[0], rnorm, test1, test2); - fprintf(nout, fmt_1600); - fclose(nout); -} - // ================================================================== // CheckPointRestart // ================================================================== - -if (!noCPR) - if (myid == 0) - printf("PE=%d call restart setup\n", myid); -restartSetup(&itn, - knownTerms, - &beta, - &alpha, - vVect, - &anorm, - &rhobar, - &phibar, - wVect, - xSolution, - standardError, - &dnorm, - &sn2, - &cs2, - &z, - &xnorm1, - &res2, - &nstop, - comlsqr); -if (myid == 0) - printf("PE=%d end restart setup\n", myid); + + if(!noCPR) + if(myid==0) printf("PE=%d call restart setup\n",myid); + restartSetup( &itn, + knownTerms, + &beta, + &alpha, + vVect, + &anorm, + &rhobar, + &phibar, + wVect, + xSolution, + standardError, + &dnorm, + &sn2, + &cs2, + &z, + &xnorm1, + &res2, + &nstop, + comlsqr); + if(myid==0) printf("PE=%d end restart setup\n",myid); // ================================================================== // Main iteration loop. // ================================================================== -if (myid == 0) -{ - startCycleTime = time(NULL); -} -//////////////////////// START ITERATIONS -while (1) -{ - writeCPR = 0; // No write CPR - cycleStartMpiTime = MPI_Wtime(); - itnTest = -1; - if (myid == 0) - { - fpItnLimitNew = NULL; - fpItnLimitNew = fopen("ITNLIMIT_NEW", "r"); - if (fpItnLimitNew != NULL) - { - fscanf(fpItnLimitNew, "%d\n", &itnTest); - if (itnTest > 0) + if(myid==0) + { + startCycleTime=time(NULL); + } +//////////////////////// START ITERATIONS + while (1) { + writeCPR=0; // No write CPR + cycleStartMpiTime=MPI_Wtime(); + itnTest=-1; + if(myid==0){ + fpItnLimitNew=NULL; + fpItnLimitNew=fopen("ITNLIMIT_NEW","r"); + if (fpItnLimitNew!=NULL) + { + fscanf(fpItnLimitNew, "%d\n",&itnTest); + if(itnTest>0) { - comlsqr.itnLimit = itnTest; - if (itnlim != itnTest) - { - itnlim = itnTest; - if (myid == 0) - printf("itnLimit forced with ITNLIMIT_NEW file to value %d\n", itnlim); + comlsqr.itnLimit=itnTest; + if(itnlim != itnTest){ + itnlim=itnTest; + if(myid==0) printf("itnLimit forced with ITNLIMIT_NEW file to value %d\n",itnlim); } } fclose(fpItnLimitNew); + } } - } - - if (myid == 0) - { - endCycleTime = time(NULL) - startCycleTime; - startCycleTime = time(NULL); - totTime = totTime + endCycleTime; - partialTime = partialTime + endCycleTime; - if (!noCPR) + + if(myid==0) { - - if (partialTime > comlsqr.timeCPR * 60) + endCycleTime=time(NULL)-startCycleTime; + startCycleTime=time(NULL); + totTime=totTime+endCycleTime; + partialTime=partialTime+endCycleTime; + if(!noCPR){ + + if(partialTime>comlsqr.timeCPR*60) + { + writeCPR=1; + partialTime=0; + } + if(totTime+endCycleTime*2>comlsqr.timeLimit*60) writeCPR=2; + + if(CPRCount>0 && CPRCount%comlsqr.itnCPR==0) writeCPR=1; + if(CPRCount>0 && CPRCount==comlsqr.itnCPRstop) writeCPR=2; + if(CPRCount==itnlim) writeCPR=2; + fpCPRend=NULL; + fpCPRend=fopen("CPR_END","r"); + if (fpCPRend!=NULL) { - writeCPR = 1; - partialTime = 0; - } - if (totTime + endCycleTime * 2 > comlsqr.timeLimit * 60) - writeCPR = 2; - - if (CPRCount > 0 && CPRCount % comlsqr.itnCPR == 0) - writeCPR = 1; - if (CPRCount > 0 && CPRCount == comlsqr.itnCPRstop) - writeCPR = 2; - if (CPRCount == itnlim) - writeCPR = 2; - fpCPRend = NULL; - fpCPRend = fopen("CPR_END", "r"); - if (fpCPRend != NULL) - { - itnTest = -1; - fscanf(fpCPRend, "%d\n", &itnTest); - if (itnTest > 0) + itnTest=-1; + fscanf(fpCPRend, "%d\n",&itnTest); + if(itnTest>0) { - if (comlsqr.itnCPRend != itnTest) - { - comlsqr.itnCPRend = itnTest; - printf("itnCPRend forced with CPR_END file to value %d\n", comlsqr.itnCPRend); + if(comlsqr.itnCPRend != itnTest){ + comlsqr.itnCPRend=itnTest; + printf("itnCPRend forced with CPR_END file to value %d\n",comlsqr.itnCPRend); } } fclose(fpCPRend); } - if (comlsqr.itnCPRend > 0 && comlsqr.itnCPRend <= itn) + if(comlsqr.itnCPRend>0 && comlsqr.itnCPRend<=itn) { - writeCPR = 2; - printf("itnCPRend condition triggered to value %d. writeCPR set to 2.\n", comlsqr.itnCPRend); + writeCPR=2; + printf("itnCPRend condition triggered to value %d. writeCPR set to 2.\n",comlsqr.itnCPRend); } - } //if(!noCPR) - } //if(myid==0) - MPI_Barrier(MPI_COMM_WORLD); - MPI_Bcast(&writeCPR, 1, MPI_INT, 0, MPI_COMM_WORLD); - MPI_Bcast(&itnlim, 1, MPI_INT, 0, MPI_COMM_WORLD); - MPI_Bcast(&comlsqr.itnLimit, 1, MPI_INT, 0, MPI_COMM_WORLD); - if (myid == 0) - { - printf("lsqr: Iteration number %d. Iteration seconds %ld. OmpSec %d Global Seconds %ld \n", itn, endCycleTime, ompSec, totTime); - if (writeCPR == 1) - printf("... writing CPR files\n"); - if (writeCPR == 2) - printf("... writing CPR files and return\n"); - } - - if (writeCPR > 0) - { - if (myid == 0) - CPRtimeStart = time(NULL); - writeCheckPoint(itn, - knownTerms, - beta, - alpha, - vVect, - anorm, - rhobar, - phibar, - wVect, - xSolution, - standardError, - dnorm, - sn2, - cs2, - z, - xnorm1, - res2, - nstop, - comlsqr); - - if (myid == 0) - { - CPRtimeEnd = time(NULL) - CPRtimeStart; - totTime += CPRtimeEnd; - partialTime += CPRtimeEnd; - printf("CPR: itn=%d writing CPR seconds %ld. Global Seconds %ld \n", itn, CPRtimeEnd, totTime); + }//if(!noCPR) + }//if(myid==0) + MPI_Barrier(MPI_COMM_WORLD); + MPI_Bcast( &writeCPR, 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Bcast( &itnlim, 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Bcast( &comlsqr.itnLimit, 1, MPI_INT, 0, MPI_COMM_WORLD); + if(myid==0) + { + printf("lsqr: Iteration number %d. Iteration seconds %ld. OmpSec %d Global Seconds %ld \n",itn,endCycleTime,ompSec,totTime); + if(writeCPR==1) printf("... writing CPR files\n"); + if(writeCPR==2) printf("... writing CPR files and return\n"); + } + + + if(writeCPR>0) + { + if(myid==0) + CPRtimeStart=time(NULL); + writeCheckPoint(itn, + knownTerms, + beta, + alpha, + vVect, + anorm, + rhobar, + phibar, + wVect, + xSolution, + standardError, + dnorm, + sn2, + cs2, + z, + xnorm1, + res2, + nstop, + comlsqr); + + if(myid==0){ + CPRtimeEnd=time(NULL)-CPRtimeStart; + totTime+=CPRtimeEnd; + partialTime+=CPRtimeEnd; + printf("CPR: itn=%d writing CPR seconds %ld. Global Seconds %ld \n",itn,CPRtimeEnd, totTime); + } + + if(writeCPR==2) + { + *istop_out = 1000; + *itn_out = itn; + if(nAstroPSolved) free(vAuxVect); + return; + } + if(myid==0) startCycleTime=time(NULL); } - if (writeCPR == 2) + itn = itn + 1; + comlsqr.itn=itn; + CPRCount++; +// ------------------------------------------------------------------ +// Perform the next step of the bidiagonalization to obtain the +// next beta, u, alpha, v. These satisfy the relations +// beta*u = A*v - alpha*u, +// alpha*v = A(transpose)*u - beta*v. +// ------------------------------------------------------------------ + cblas_dscal ( mapNoss[myid]+nEqExtConstr+nEqBarConstr+nOfInstrConstr, (- alpha), knownTerms, 1 ); + kAuxcopy=(double *) calloc(nEqExtConstr+nEqBarConstr+nOfInstrConstr, sizeof(double)); + for (int kk=0;kk ZERO) - { - cblas_dscal(mapNoss[myid] + nEqExtConstr + nEqBarConstr + nOfInstrConstr, (ONE / beta), knownTerms, 1); - cblas_dscal(nunkSplit, (-beta), vVect, 1); -//only processor 0 accumulate and distribute the v array - // FV EDIT - //#pragma omp for - for (i = 0; i < localAstroMax; i++) - { - vAuxVect[i] = vVect[i]; - vVect[i] = 0; - } - if (myid != 0) - { - // FV EDIT - //#pragma omp for - for (i = localAstroMax; i < nunkSplit; i++) - vVect[i] = 0; - } + temp = d2norm( alpha, beta ); + temp = d2norm( temp , damp ); + anorm = d2norm( anorm, temp ); - aprod(2, m, n, vVect, knownTerms, systemMatrix, matrixIndex, instrCol, instrConstrIlung, comlsqr, &ompSec); - MPI_Barrier(MPI_COMM_WORLD); + if (beta > ZERO) { + cblas_dscal ( mapNoss[myid]+nEqExtConstr+nEqBarConstr+nOfInstrConstr, (ONE / beta), knownTerms, 1 ); + cblas_dscal ( nunkSplit, (- beta), vVect, 1 ); +//only processor 0 accumulate and distribute the v array +#pragma omp for + for(i=0;i ZERO) { + cblas_dscal ( nunkSplit, (ONE / alpha), vVect, 1 ); + } } - double alphaLoc = 0; - if (nAstroPSolved) - alphaLoc = cblas_dnrm2(nAstroElements * comlsqr.nAstroPSolved, vVect, 1); - double alphaLoc2 = alphaLoc * alphaLoc; - if (myid == 0) - { - double alphaOther = cblas_dnrm2(comlsqr.nunkSplit - localAstroMax, &vVect[localAstroMax], 1); - double alphaOther2 = alphaOther * alphaOther; - alphaLoc2 = alphaLoc2 + alphaOther2; +// ------------------------------------------------------------------ +// Use a plane rotation to eliminate the damping parameter. +// This alters the diagonal (rhobar) of the lower-bidiagonal matrix. +// ------------------------------------------------------------------ + rhbar1 = rhobar; + if ( damped ) { + rhbar1 = d2norm( rhobar, damp ); + cs1 = rhobar / rhbar1; + sn1 = damp / rhbar1; + psi = sn1 * phibar; + phibar = cs1 * phibar; } - double alphaGlob2 = 0; - MPI_Allreduce(&alphaLoc2, &alphaGlob2, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - alpha = sqrt(alphaGlob2); - if (alpha > ZERO) - { - cblas_dscal(nunkSplit, (ONE / alpha), vVect, 1); +// ------------------------------------------------------------------ +// Use a plane rotation to eliminate the subdiagonal element (beta) +// of the lower-bidiagonal matrix, giving an upper-bidiagonal matrix. +// ------------------------------------------------------------------ + rho = d2norm( rhbar1, beta ); + cs = rhbar1 / rho; + sn = beta / rho; + theta = sn * alpha; + rhobar = - cs * alpha; + phi = cs * phibar; + phibar = sn * phibar; + tau = sn * phi; + +// ------------------------------------------------------------------ +// Update x, w and (perhaps) the standard error estimates. +// ------------------------------------------------------------------ + t1 = phi / rho; + t2 = - theta / rho; + t3 = ONE / rho; + dknorm = ZERO; + + for (i = 0; i < nAstroElements*comlsqr.nAstroPSolved; i++) { + t = wVect[i]; + t = (t3*t)*(t3*t); + dknorm = t + dknorm; } - } - - // ------------------------------------------------------------------ - // Use a plane rotation to eliminate the damping parameter. - // This alters the diagonal (rhobar) of the lower-bidiagonal matrix. - // ------------------------------------------------------------------ - rhbar1 = rhobar; - if (damped) - { - rhbar1 = d2norm(rhobar, damp); - cs1 = rhobar / rhbar1; - sn1 = damp / rhbar1; - psi = sn1 * phibar; - phibar = cs1 * phibar; - } - - // ------------------------------------------------------------------ - // Use a plane rotation to eliminate the subdiagonal element (beta) - // of the lower-bidiagonal matrix, giving an upper-bidiagonal matrix. - // ------------------------------------------------------------------ - rho = d2norm(rhbar1, beta); - cs = rhbar1 / rho; - sn = beta / rho; - theta = sn * alpha; - rhobar = -cs * alpha; - phi = cs * phibar; - phibar = sn * phibar; - tau = sn * phi; - - // ------------------------------------------------------------------ - // Update x, w and (perhaps) the standard error estimates. - // ------------------------------------------------------------------ - t1 = phi / rho; - t2 = -theta / rho; - t3 = ONE / rho; - dknorm = ZERO; - - for (i = 0; i < nAstroElements * comlsqr.nAstroPSolved; i++) - { - t = wVect[i]; - t = (t3 * t) * (t3 * t); - dknorm = t + dknorm; - } - dknormSum = 0; - MPI_Allreduce(&dknorm, &dknormSum, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - dknorm = dknormSum; - - if (wantse) - { - // FV EDIT - //#pragma omp for - for (i = 0; i < localAstro; i++) - { - t = wVect[i]; - xSolution[i] = t1 * t + xSolution[i]; - wVect[i] = t2 * t + vVect[i]; - t = (t3 * t) * (t3 * t); - standardError[i] = t + standardError[i]; + dknormSum=0; + MPI_Allreduce(&dknorm,&dknormSum,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); + dknorm=dknormSum; + + if ( wantse ) { +#pragma omp for + for (i = 0; i < localAstro; i++) { + t = wVect[i]; + xSolution[i] = t1*t + xSolution[i]; + wVect[i] = t2*t + vVect[i]; + t = (t3*t)*(t3*t); + standardError[i] = t + standardError[i]; + } +#pragma omp for + for (i = localAstroMax; i < localAstroMax+other; i++) { + t = wVect[i]; + xSolution[i] = t1*t + xSolution[i]; + wVect[i] = t2*t + vVect[i]; + t = (t3*t)*(t3*t); + standardError[i] = t + standardError[i]; + } + for (i = localAstroMax; i < localAstroMax+other; i++) { + t = wVect[i]; + t = (t3*t)*(t3*t); + dknorm = t + dknorm; + } } - // FV EDIT - //#pragma omp for - for (i = localAstroMax; i < localAstroMax + other; i++) - { - t = wVect[i]; - xSolution[i] = t1 * t + xSolution[i]; - wVect[i] = t2 * t + vVect[i]; - t = (t3 * t) * (t3 * t); - standardError[i] = t + standardError[i]; + else { +#pragma omp for + for (i = 0; i < localAstro; i++) { + t = wVect[i]; + xSolution[i] = t1*t + xSolution[i]; + wVect[i] = t2*t + vVect[i]; + } +#pragma omp for + for (i = localAstroMax; i < localAstroMax+other; i++) { + t = wVect[i]; + xSolution[i] = t1*t + xSolution[i]; + wVect[i] = t2*t + vVect[i]; + } + for (i = localAstroMax; i < localAstroMax+other; i++) { + t = wVect[i]; + dknorm = (t3*t)*(t3*t) + dknorm; + } } - for (i = localAstroMax; i < localAstroMax + other; i++) - { - t = wVect[i]; - t = (t3 * t) * (t3 * t); - dknorm = t + dknorm; + +// ------------------------------------------------------------------ +// Monitor the norm of d_k, the update to x. +// dknorm = norm( d_k ) +// dnorm = norm( D_k ), where D_k = (d_1, d_2, ..., d_k ) +// dxk = norm( phi_k d_k ), where new x = x_k + phi_k d_k. +// ------------------------------------------------------------------ + dknorm = sqrt( dknorm ); + dnorm = d2norm( dnorm, dknorm ); + dxk = fabs( phi * dknorm ); + if (dxmax < dxk ) { + dxmax = dxk; + maxdx = itn; } - } - else - { - // FV EDIT - //#pragma omp for - for (i = 0; i < localAstro; i++) - { - t = wVect[i]; - xSolution[i] = t1 * t + xSolution[i]; - wVect[i] = t2 * t + vVect[i]; + +// ------------------------------------------------------------------ +// Use a plane rotation on the right to eliminate the +// super-diagonal element (theta) of the upper-bidiagonal matrix. +// Then use the result to estimate norm(x). +// ------------------------------------------------------------------ + delta = sn2 * rho; + gambar = - cs2 * rho; + rhs = phi - delta * z; + zbar = rhs / gambar; + xnorm = d2norm( xnorm1, zbar ); + gamma = d2norm( gambar, theta ); + cs2 = gambar / gamma; + sn2 = theta / gamma; + z = rhs / gamma; + xnorm1 = d2norm( xnorm1, z ); + +// ------------------------------------------------------------------ +// Test for convergence. +// First, estimate the norm and condition of the matrix Abar, +// and the norms of rbar and Abar(transpose)*rbar. +// ------------------------------------------------------------------ + acond = anorm * dnorm; + res2 = d2norm( res2 , psi ); + rnorm = d2norm( res2 , phibar ); + arnorm = alpha * fabs( tau ); + +// Now use these norms to estimate certain other quantities, +// some of which will be small near a solution. + + alfopt = sqrt( rnorm / (dnorm * xnorm) ); + test1 = rnorm / bnorm; + test2 = ZERO; + if (rnorm > ZERO) test2 = arnorm / (anorm * rnorm); +// if (arnorm0 > ZERO) test2 = arnorm / arnorm0; //(Michael Friedlander's modification) + test3 = ONE / acond; + t1 = test1 / (ONE + anorm * xnorm / bnorm); + rtol = btol + atol * anorm * xnorm / bnorm; + +// The following tests guard against extremely small values of +// atol, btol or ctol. (The user may have set any or all of +// the parameters atol, btol, conlim to zero.) +// The effect is equivalent to the normal tests using +// atol = relpr, btol = relpr, conlim = 1/relpr. + + t3 = ONE + test3; + t2 = ONE + test2; + t1 = ONE + t1; +// printf("LSQR TP8 PE=%d itn=%d test1=%18.16lf, rnorm=%lf bnorm=%lf anorm=%lf xnorm=%lf rtol=%lf t1=%18.16lf\n",myid,itn,test1,rnorm,bnorm,anorm,xnorm,rtol,t1); + + if (itn >= itnlim) istop = 5; + if (t3 <= ONE ) istop = 4; + if (t2 <= ONE ) istop = 2; + if (t1 <= ONE ) istop = 1; +// if (t1 <= ONE ) printf("PE=%d t1=%lf\n",myid,t1); + +// Allow for tolerances set by the user. + + if (test3 <= ctol) istop = 4; + if (test2 <= atol) istop = 2; + if (test1 <= rtol) istop = 1; //(Michael Friedlander had this commented out) +// if (test1 <= rtol) printf("PE=%d test1=%lf\n",myid,test1); + +// ------------------------------------------------------------------ +// See if it is time to print something. +// ------------------------------------------------------------------ +// if (nout == NULL ) goto goto_600; // Delete for buffer flush modification??? TBV + if (n <= 40 ) goto goto_400; + if (itn <= 10 ) goto goto_400; + if (itn >= itnlim-10) goto goto_400; + if (itn % 10 == 0 ) goto goto_400; + if (test3 <= 2.0*ctol) goto goto_400; + if (test2 <= 10.0*atol) goto goto_400; + if (test1 <= 10.0*rtol) goto goto_400; + if (istop != 0 ) goto goto_400; + goto goto_600; + +// Print a line for this iteration. +// "extra" is for experimental purposes. + + goto_400: + if(!comlsqr.Test) + if(myid==0) { + nout=fopen(lsqrOut,"a"); + if ( nout != NULL) { + if ( extra ) { + fprintf(nout, fmt_1500_extra, + itn, xSolution[0], rnorm, test1, test2, anorm, + acond, phi, dknorm, dxk, alfopt); + } else { + fprintf(nout, fmt_1500, + itn, xSolution[0], rnorm, test1, test2, anorm, acond); + } + if (itn % 10 == 0) fprintf(nout, fmt_1600); + } else { + printf("Error while opening %s (3)\n",lsqrOut); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + fclose(nout); } - // FV EDIT - //#pragma omp for - for (i = localAstroMax; i < localAstroMax + other; i++) - { - t = wVect[i]; - xSolution[i] = t1 * t + xSolution[i]; - wVect[i] = t2 * t + vVect[i]; +// ------------------------------------------------------------------ +// Stop if appropriate. +// The convergence criteria are required to be met on nconv +// consecutive iterations, where nconv is set below. +// Suggested value: nconv = 1, 2 or 3. +// ------------------------------------------------------------------ + goto_600: + if (istop == 0) { + nstop = 0; } - for (i = localAstroMax; i < localAstroMax + other; i++) - { - t = wVect[i]; - dknorm = (t3 * t) * (t3 * t) + dknorm; + else { + nconv = 1; + nstop = nstop + 1; + if (nstop < nconv && itn < itnlim) istop = 0; } - } - - // ------------------------------------------------------------------ - // Monitor the norm of d_k, the update to x. - // dknorm = norm( d_k ) - // dnorm = norm( D_k ), where D_k = (d_1, d_2, ..., d_k ) - // dxk = norm( phi_k d_k ), where new x = x_k + phi_k d_k. - // ------------------------------------------------------------------ - dknorm = sqrt(dknorm); - dnorm = d2norm(dnorm, dknorm); - dxk = fabs(phi * dknorm); - if (dxmax < dxk) - { - dxmax = dxk; - maxdx = itn; - } - - // ------------------------------------------------------------------ - // Use a plane rotation on the right to eliminate the - // super-diagonal element (theta) of the upper-bidiagonal matrix. - // Then use the result to estimate norm(x). - // ------------------------------------------------------------------ - delta = sn2 * rho; - gambar = -cs2 * rho; - rhs = phi - delta * z; - zbar = rhs / gambar; - xnorm = d2norm(xnorm1, zbar); - gamma = d2norm(gambar, theta); - cs2 = gambar / gamma; - sn2 = theta / gamma; - z = rhs / gamma; - xnorm1 = d2norm(xnorm1, z); - - // ------------------------------------------------------------------ - // Test for convergence. - // First, estimate the norm and condition of the matrix Abar, - // and the norms of rbar and Abar(transpose)*rbar. - // ------------------------------------------------------------------ - acond = anorm * dnorm; - res2 = d2norm(res2, psi); - rnorm = d2norm(res2, phibar); - arnorm = alpha * fabs(tau); - - // Now use these norms to estimate certain other quantities, - // some of which will be small near a solution. - - alfopt = sqrt(rnorm / (dnorm * xnorm)); - test1 = rnorm / bnorm; - test2 = ZERO; - if (rnorm > ZERO) - test2 = arnorm / (anorm * rnorm); - // if (arnorm0 > ZERO) test2 = arnorm / arnorm0; //(Michael Friedlander's modification) - test3 = ONE / acond; - t1 = test1 / (ONE + anorm * xnorm / bnorm); - rtol = btol + atol * anorm * xnorm / bnorm; - - // The following tests guard against extremely small values of - // atol, btol or ctol. (The user may have set any or all of - // the parameters atol, btol, conlim to zero.) - // The effect is equivalent to the normal tests using - // atol = relpr, btol = relpr, conlim = 1/relpr. - - t3 = ONE + test3; - t2 = ONE + test2; - t1 = ONE + t1; - // printf("LSQR TP8 PE=%d itn=%d test1=%18.16lf, rnorm=%lf bnorm=%lf anorm=%lf xnorm=%lf rtol=%lf t1=%18.16lf\n",myid,itn,test1,rnorm,bnorm,anorm,xnorm,rtol,t1); - - if (itn >= itnlim) - istop = 5; - if (t3 <= ONE) - istop = 4; - if (t2 <= ONE) - istop = 2; - if (t1 <= ONE) - istop = 1; - // if (t1 <= ONE ) printf("PE=%d t1=%lf\n",myid,t1); - - // Allow for tolerances set by the user. - - if (test3 <= ctol) - istop = 4; - if (test2 <= atol) - istop = 2; - if (test1 <= rtol) - istop = 1; //(Michael Friedlander had this commented out) - // if (test1 <= rtol) printf("PE=%d test1=%lf\n",myid,test1); - - // ------------------------------------------------------------------ - // See if it is time to print something. - // ------------------------------------------------------------------ - // if (nout == NULL ) goto goto_600; // Delete for buffer flush modification??? TBV - if (n <= 40) - goto goto_400; - if (itn <= 10) - goto goto_400; - if (itn >= itnlim - 10) - goto goto_400; - if (itn % 10 == 0) - goto goto_400; - if (test3 <= 2.0 * ctol) - goto goto_400; - if (test2 <= 10.0 * atol) - goto goto_400; - if (test1 <= 10.0 * rtol) - goto goto_400; - if (istop != 0) - goto goto_400; - goto goto_600; - - // Print a line for this iteration. - // "extra" is for experimental purposes. - -goto_400: - if (!comlsqr.Test) - if (myid == 0) + + if(comlsqr.Test) { - nout = fopen(lsqrOut, "a"); - if (nout != NULL) - { - if (extra) - { - fprintf(nout, fmt_1500_extra, - itn, xSolution[0], rnorm, test1, test2, anorm, - acond, phi, dknorm, dxk, alfopt); - } - else - { - fprintf(nout, fmt_1500, - itn, xSolution[0], rnorm, test1, test2, anorm, acond); - } - if (itn % 10 == 0) - fprintf(nout, fmt_1600); - } - else - { - printf("Error while opening %s (3)\n", lsqrOut); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - fclose(nout); - } - // ------------------------------------------------------------------ - // Stop if appropriate. - // The convergence criteria are required to be met on nconv - // consecutive iterations, where nconv is set below. - // Suggested value: nconv = 1, 2 or 3. - // ------------------------------------------------------------------ -goto_600: - if (istop == 0) - { - nstop = 0; + if(itn n) - t = m - n; - if (damped) - t = m; - t = rnorm / sqrt(t); - - for (i = 0; i < nunkSplit; i++) - standardError[i] = t * sqrt(standardError[i]); -} + if ( wantse ) { + t = ONE; + if (m > n) t = m - n; + if ( damped ) t = m; + t = rnorm / sqrt( t ); + + for (i = 0; i < nunkSplit; i++) + standardError[i] = t * sqrt( standardError[i] ); + + } // Decide if istop = 2 or 3. // Print the stopping condition. -goto_800 : if (damped && istop == 2) istop = 3; -if (myid == 0) -{ - nout = fopen(lsqrOut, "a"); - if (nout != NULL) - { - fprintf(nout, fmt_2000, - exitLsqr, istop, itn, - exitLsqr, anorm, acond, - exitLsqr, bnorm, xnorm, - exitLsqr, rnorm, arnorm); - fprintf(nout, fmt_2100, - exitLsqr, dxmax, maxdx, - exitLsqr, dxmax / (xnorm + 1.0e-20)); - fprintf(nout, fmt_3000, - exitLsqr, msg[istop]); - } - else - { - printf("Error while opening %s (4)\n", lsqrOut); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - fclose(nout); -} + goto_800: + if (damped && istop == 2) istop = 3; + if (myid == 0) { + nout=fopen(lsqrOut,"a"); + if (nout != NULL) { + fprintf(nout, fmt_2000, + exitLsqr, istop, itn, + exitLsqr, anorm, acond, + exitLsqr, bnorm, xnorm, + exitLsqr, rnorm, arnorm); + fprintf(nout, fmt_2100, + exitLsqr, dxmax, maxdx, + exitLsqr, dxmax/(xnorm + 1.0e-20)); + fprintf(nout, fmt_3000, + exitLsqr, msg[istop]); + } else { + printf("Error while opening %s (4)\n",lsqrOut); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + fclose(nout); + } // Assign output variables from local copies. -*istop_out = istop; -*itn_out = itn; -*anorm_out = anorm; -*acond_out = acond; -*rnorm_out = rnorm; -*arnorm_out = test2; -*xnorm_out = xnorm; - -if (nAstroPSolved) - free(vAuxVect); -return; + *istop_out = istop; + *itn_out = itn; + *anorm_out = anorm; + *acond_out = acond; + *rnorm_out = rnorm; + *arnorm_out = test2; + *xnorm_out = xnorm; + + if(nAstroPSolved) free(vAuxVect); + return; } + + diff --git a/memRequest.c b/memRequest.c old mode 100644 new mode 100755 diff --git a/run_ppl.cmd b/run_ppl.cmd new file mode 100755 index 0000000..636fd0f --- /dev/null +++ b/run_ppl.cmd @@ -0,0 +1,28 @@ +#!/bin/bash +#SBATCH --job-name=AVUGSR_OMP +#SBATCH --time=0:30:00 +#SBATCH --out=out.log +#SBATCH --err=err.log +###SBATCH --nodes=2 --ntasks-per-node=2 --ntasks-per-socket=2 +#SBATCH --nodes=1 +#SBATCH --ntasks=2 +#SBATCH --cpus-per-task=4 +#SBATCH --mem=100000 +#SBATCH --partition=merlin +####SBATCH --account=INAF_GAIA14_3 +# +# +# +###module load profile/astro +##module load autoload intelmpi cfitsio +export OMP_NUM_THREADS=4 +export KMP_AFFINITY=compact +# +cd /home/ubecciani/AVU-GSR/OMP/src/run + +srun ../GaiaGsrParSim -auto + +exit 0 + +# +# diff --git a/solvergaiaSim.c b/solvergaiaSim.c index 30b8f0a..d001f9a 100644 --- a/solvergaiaSim.c +++ b/solvergaiaSim.c @@ -16,6 +16,8 @@ - version 5.0 - May 2013 from Ugo Becciani and Alberto Vecchiato */ + + //#include #include #include @@ -32,6 +34,7 @@ #define MAX_CONSTR 1000 + long instr_hash(int FoV, int CCD, int PixelColumn, int TimeInterval); long randlong(long max); long randlong1(long min, long max); @@ -39,570 +42,505 @@ int randint(int max); int randint1(int min, int max); int fill_extract(long *values, long *pos_min, long pos_max, long *number); + + /* Start of main program */ -int main(int argc, char **argv) -{ - int debugMode, wrsol; +int main(int argc, char **argv) { + int debugMode,wrsol; int i; - - int idtest = 0, precond = 1; + + int idtest=0, precond=1; double srIDtest, pert; - - int inputDirOpt = 0, outputDirOpt = 0, inputDirLen; - char inputDir[1024] = "", outputDir[1024] = "", wrfileDir[1024] = ""; + + int inputDirOpt=0, outputDirOpt=0, inputDirLen; + char inputDir[1024]="", outputDir[1024]="",wrfileDir[1024]=""; char wpath[1024]; - size_t sizePath = 1020; - + size_t sizePath=1020; + char filenameSolProps[150]; char filenameSolPropsFinal[150]; - char filenameAstroResults[150]; /* file storing the Astrometric Parameters */ - char filenameAttResults[150]; /* file storing the Attitude Parameters */ - char filenameInstrResults[150]; /* file storing the Instrument Parameters */ + char filenameAstroResults[150]; /* file storing the Astrometric Parameters */ + char filenameAttResults[150]; /* file storing the Attitude Parameters */ + char filenameInstrResults[150]; /* file storing the Instrument Parameters */ char filenameGlobalResults[150]; /* file storing the Global Parameters */ - + long ii, jj, kk; long sphereId; // Id of the sphere to be solved - long idum; // variable to initialize the random number generator aggiunta la variabile per inizializzare ran2() - + long idum; // variable to initialize the random number generator aggiunta la variabile per inizializzare ran2() + // LSQR input parameters - long itnlim; // maximum number of iteration allowed for the LSQR convergence + long itnlim; // maximum number of iteration allowed for the LSQR convergence double damp, atol, btol, conlim; // other LSQR input parameters - double aTol; //read by command line, overrides atol if >=0 - + double aTol; //read by command line, overrides atol if >=0 + // LSQR output parameters - int istop; // LSQR stopping condition - int itn; // LSQR iteration number + int istop; // LSQR stopping condition + int itn; // LSQR iteration number double anorm, acond, rnorm, arnorm, xnorm; // other LSQR output parameters - + // Properties of the system to be solved // Astrometric parameters: - long nStar; // number of stars - short nAstroP; // number of astrometric parameters for each observation - - short nAstroPSolved, nInstrPSolved; // number of astrometric and instrumental parameters taken as unknowns in the system of equations - int *mapAstroP; // indeces of the solved astrometric parameters - int lsInstrFlag, ssInstrFlag, nuInstrFlag, maInstrFlag; - int nElemIC = 0, nOfInstrConstr = 0; - int nOfInstrConstrLSAL = 0, nElemICLSAL = 0, nOfInstrConstrLSAC = 0, nElemICLSAC = 0, nOfInstrConstrSS = 0, nElemICSS = 0; + long nStar; // number of stars + short nAstroP; // number of astrometric parameters for each observation + + short nAstroPSolved,nInstrPSolved; // number of astrometric and instrumental parameters taken as unknowns in the system of equations + int *mapAstroP; // indeces of the solved astrometric parameters + int lsInstrFlag,ssInstrFlag,nuInstrFlag,maInstrFlag; + int nElemIC=0,nOfInstrConstr=0; + int nOfInstrConstrLSAL=0, nElemICLSAL=0, nOfInstrConstrLSAC=0, nElemICLSAC=0 , nOfInstrConstrSS=0 ,nElemICSS=0; // Attitude parameters: - - long nDegFreedomAtt = 0; // number of degrees of freedom for each attitude axis - long cCDLSAACZP = 14; // CCD light sensitive area AC zero point - short nAttAxes = 0, nAttParAxis; // number of attitude axes to be reconstructed, number of non-zero attitude coefficients per obs. & axis - short nAttP = 0; // number of attitude parameters for each observation + + + long nDegFreedomAtt=0; // number of degrees of freedom for each attitude axis + long cCDLSAACZP=14; // CCD light sensitive area AC zero point + short nAttAxes=0, nAttParAxis; // number of attitude axes to be reconstructed, number of non-zero attitude coefficients per obs. & axis + short nAttP=0; // number of attitude parameters for each observation // Instrument parameters: long instrSetUp; // number coding the set up of the instrument in terms of: # of FoVs, # of CCDs, # of pixel columns, # of time intervals short nInstrP; // number of instrument parameters for each observation // Global parameters: - short nGlobP; // number of global parameters - - long nobs; // number of observations - long nConstrLong, nConstrLat, nConstrMuLong, nConstrMuLat; // number of constraints for the astrometric parameters + short nGlobP; // number of global parameters + + long nobs; // number of observations + long nConstrLong, nConstrLat, nConstrMuLong, nConstrMuLat; // number of constraints for the astrometric parameters long *constrLongId, *constrLatId, *constrMuLongId, *constrMuLatId; // arrays with the gsrIDs of the constrained sources - double *constrLongW, *constrLatW, *constrMuLongW, *constrMuLatW; // arrays with the weights of the constraints - double extConstrW; // weight of the null space constraint equations - double barConstrW; // weight of the baricentric constraint equations - const double attExtConstrFact = -0.5; // the coefficients of the attitude part of the null space constraint equations must be multiplied by a factor -1/2 - + double *constrLongW, *constrLatW, *constrMuLongW, *constrMuLatW; // arrays with the weights of the constraints + double extConstrW; // weight of the null space constraint equations + double barConstrW; // weight of the baricentric constraint equations + const double attExtConstrFact=-0.5; // the coefficients of the attitude part of the null space constraint equations must be multiplied by a factor -1/2 + // Variables to be read from the GsrSystemRows - + // Internal variables long nAstroParam; - int nAttParam, nInstrParam, nGlobalParam, nInstrParamTot; // total number of unknowns for the Astrometric, Attitude, Instrument, and Global parameters respectively - int nparam; // total number of unknowns + int nAttParam, nInstrParam, nGlobalParam,nInstrParamTot; // total number of unknowns for the Astrometric, Attitude, Instrument, and Global parameters respectively + int nparam; // total number of unknowns long nunk, nunkSplit, nConstr; - long ncoeff, ielem, global_ielem, precnofrows, global_precnofrows, ncolumn, nrowsToRead; + long ncoeff, ielem, global_ielem, precnofrows,global_precnofrows, ncolumn, nrowsToRead; long offsetAttParam, offsetInstrParam, offsetGlobParam, VroffsetAttParam; // offests for the Attitude, Instrument, and Global columns of the coefficient matrix - unsigned long int totmem, nElements; // total required memory and temporary variable to store the memory being allocated - long VrIdAstroPDimMax = 0; // - long VrIdAstroPDim = 0; // + unsigned long int totmem, nElements; // total required memory and temporary variable to store the memory being allocated + long VrIdAstroPDimMax=0; // + long VrIdAstroPDim=0; // long VrIdAstroPDimRecv; int offset; long nObsxStar, nobsOri; - int nfileProc = 3; - int addElementAtt = 0; - int addElementextStar = 0; - int addElementbarStar = 0; - int nOfElextObs = 0; - int nOfElBarObs = 0; + int nfileProc=3; + int addElementAtt=0; + int addElementextStar=0; + int addElementbarStar=0; + int nOfElextObs=0; + int nOfElBarObs=0; double *attNS; + // Array arguments of the LSQR function double *knownTerms, *vVect, *wVect, *xSolution, *standardError; // arrays containing the known terms (knownterms), the bidiagonalization (wVect, wVect), the unknowns (xSolution), and the estimated variances (standardError) - long int *matrixIndex; // ia[i] contains the column number of the coefficient systemMatrix[i] + long int *matrixIndex; // ia[i] contains the column number of the coefficient systemMatrix[i] int *instrConst; - int *instrCol; // columns on each observation for instumental Parameters - int *instrConstrIlung; // vector containing the length of each instrConstr eq. + int *instrCol; // columns on each observation for instumental Parameters + int * instrConstrIlung; // vector containing the length of each instrConstr eq. double *systemMatrix, *preCondVect; // array of the non-zero coefficients of the system and of the column normalization respectively - int wgInstrCoeff = 1; - + int wgInstrCoeff=1; + ///////////////////// // Arrays containing the solution coming from the LSQR - double *xAstro, *standardErrorAstro; // solution and standard errors for the Astrometric parameters - double *xAtt, *standardErrorAtt; // solution and standard errors for the Attitude parameters - double *xInstr, *standardErrorInstr; // solution and standard errors for the Instrument parameters + double *xAstro, *standardErrorAstro; // solution and standard errors for the Astrometric parameters + double *xAtt, *standardErrorAtt; // solution and standard errors for the Attitude parameters + double *xInstr, *standardErrorInstr; // solution and standard errors for the Instrument parameters double *xGlobal, *standardErrorGlobal; // solution and standard errors for the Global parameters - + + // file pointers - FILE *fpSolProps, *fpSolPropsFinal, *fpSolPropsFileBin; + FILE *fpSolProps,*fpSolPropsFinal,*fpSolPropsFileBin; FILE *fpMI, *fpSM, *fpII, *fpKT, *fpCPR; FILE *fpAstroR, *fpAttR, *fpInstrR, *fpGlobR, *ffcont; - + time_t seconds[10], tot_sec[10]; seconds[0] = time(NULL); double timeToReadFiles; - + //MPI definitions - int nproc, myid, namelen; + int nproc, myid, namelen; char processor_name[MPI_MAX_PROCESSOR_NAME]; - double startTime, endTime; - + double startTime,endTime; + // Distributed array maps - long int *mapNcoeff, *mapNoss; - long int mapNcoeffBefore, mapNossBefore; - long int mapNcoeffAfter, mapNossAfter; + long int * mapNcoeff, * mapNoss; + long int mapNcoeffBefore, mapNossBefore; + long int mapNcoeffAfter, mapNossAfter; // struct to communicate with lsqr - int timeCPR, timeLimit, itnCPR, itnCPRstop = 1000000; + int timeCPR, timeLimit,itnCPR,itnCPRstop=1000000; int itnLimit; //read by command line, overrides itnlim if >0 struct comData comlsqr; // serach for map - long lastStar = -1; - long firstStar = -1; - long lastStarConstr = -1; - long firstStarConstr = -1; - int seqStar = 1; - int withFile = 1; - int noConstr = 0; - int zeroAtt = 0, zeroInstr = 0, zeroGlob = 0, wrFilebin = 0; + long lastStar=-1; + long firstStar=-1; + long lastStarConstr=-1; + long firstStarConstr=-1; + int seqStar=1; + int withFile=1; + int noConstr=0; + int zeroAtt=0, zeroInstr=0, zeroGlob=0, wrFilebin=0; int constraintFound[MAX_CONSTR][2]; // first: number of file of the constraint; second: row in file - int rowInFile = 0; - int noIter = 0; - int noCPR = 0; - int extConstraint = 0, nEqExtConstr = 0; - int barConstraint = 0, nEqBarConstr = 0; - int startingAttColExtConstr, endingAttColExtConstr, numOfExtAttCol, starOverlap = 0, numOfExtStar, numOfBarStar; + int rowInFile=0; + int noIter=0; + int noCPR=0; + int extConstraint=0, nEqExtConstr=0; + int barConstraint=0, nEqBarConstr=0; + int startingAttColExtConstr,endingAttColExtConstr,numOfExtAttCol,starOverlap=0,numOfExtStar,numOfBarStar; char constranitFoundFileName[MAX_CONSTR][256]; - struct dirent **namelistMI; + struct dirent **namelistMI; struct nullSpace nullSpaceCk; double nullSpaceAttfact; - int autoRun = 0; - float memGlobal = 0; + int autoRun=0; + float memGlobal=0; float memGB; - int nthreads=0; - int ntasks=0; - /////////////// - for (int i = 1; i < argc - 1; i++) + for (int i=1;i 0) - timeCPR = testTime; + nfileProc=atoi(argv[i+1]); + if(nfileProc <=0) nfileProc=3; } - if (strcmp(argv[i], "-timelimit") == 0) + if(strcmp (argv[i],"-timeCPR") == 0) { - testTime = atoi(argv[i + 1]); - if (testTime > 0) - timeLimit = testTime; + testTime=atoi(argv[i+1]); + if(testTime >0) timeCPR=testTime; } - - if (strcmp(argv[i], "-itnCPR") == 0) + if(strcmp (argv[i],"-timelimit") == 0) { - testTime = atoi(argv[i + 1]); - if (testTime > 0) - itnCPR = testTime; + testTime=atoi(argv[i+1]); + if(testTime >0) timeLimit=testTime; } - if (strcmp(argv[i], "-noCPR") == 0) + + if(strcmp (argv[i],"-itnCPR") == 0) { - noCPR = 1; + testTime=atoi(argv[i+1]); + if(testTime >0) itnCPR=testTime; } - if (strcmp(argv[i], "-itnlimit") == 0) + if(strcmp (argv[i],"-noCPR") == 0) { - testTime = atoi(argv[i + 1]); - if (testTime > 0) - itnLimit = testTime; + noCPR=1; } - if(strcmp (argv[i],"-tasks") == 0) + if(strcmp (argv[i],"-itnlimit") == 0) { - ntasks=atoi(argv[i+1]); - if(ntasks <=0) ntasks=0; + testTime=atoi(argv[i+1]); + if(testTime >0) itnLimit=testTime; } - if (strcmp(argv[i], "-atol") == 0) + if(strcmp (argv[i],"-atol") == 0) { - double dummy = atof(argv[i + 1]); - if (dummy >= 0) - aTol = dummy; + double dummy=atof(argv[i+1]); + if(dummy >=0) aTol=dummy; } - if (strcmp(argv[i], "-zeroAtt") == 0) + if(strcmp (argv[i],"-zeroAtt") == 0) { - zeroAtt = 1; + zeroAtt=1; } - if (strcmp(argv[i], "-zeroInstr") == 0) + if(strcmp (argv[i],"-zeroInstr") == 0) { - zeroInstr = 1; + zeroInstr=1; } - if (strcmp(argv[i], "-zeroGlob") == 0) + if(strcmp (argv[i],"-zeroGlob") == 0) { - zeroGlob = 1; + zeroGlob=1; } - if (strcmp(argv[i], "-wgic") == 0) + if(strcmp (argv[i],"-wgic") == 0) { - wgInstrCoeff = atoi(argv[i + 1]); - if (wgInstrCoeff <= 0) - wgInstrCoeff = 1; + wgInstrCoeff=atoi(argv[i+1]); + if(wgInstrCoeff<=0) wgInstrCoeff=1; } // inputDir e outputDir - - if (strcmp(argv[i], "-inputDir") == 0) + + if(strcmp (argv[i],"-inputDir") == 0) { - sprintf(inputDir, "%s", argv[i + 1]); - inputDirOpt = 1; + sprintf(inputDir, "%s", argv[i+1]); + inputDirOpt=1; } - - if (strcmp(argv[i], "-outputDir") == 0) + + if(strcmp (argv[i],"-outputDir") == 0) { - sprintf(outputDir, "%s", argv[i + 1]); - outputDirOpt = 1; + sprintf(outputDir, "%s", argv[i+1]); + outputDirOpt=1; } - + // Fine input e output Dir - - if (strcmp(argv[i], "-debug") == 0) - debugMode = 1; - - if (strcmp(argv[i], "-wrsol") == 0) - { - wrsol = 1; + + if(strcmp (argv[i],"-debug") == 0) + debugMode=1; + + if(strcmp (argv[i],"-wrsol") == 0){ + wrsol=1; } - - if (strcmp(argv[i], "-noiter") == 0) - { - noIter = 1; + + if(strcmp (argv[i],"-noiter") == 0){ + noIter=1; } - - if (strcmp(argv[i], "-wrfilebin") == 0) + + if(strcmp (argv[i],"-wrfilebin") == 0) { - sprintf(wrfileDir, "%s", argv[i + 1]); - wrFilebin = 1; + sprintf(wrfileDir, "%s", argv[i+1]); + wrFilebin=1; } - if (strcmp(argv[i], "-extConstr") == 0) + if(strcmp (argv[i],"-extConstr") == 0) { - extConstraint = 1; //extendet external constraint - nEqExtConstr = DEFAULT_EXTCONSTROWS; - extConstrW = atof(argv[i + 1]); - if (extConstrW == 0.0) - { - printf("ERROR: PE=%d -extConstr option given with no value or zero value ==> %le. Aborting\n", myid, extConstrW); - MPI_Abort(MPI_COMM_WORLD, 1); + extConstraint=1; //extendet external constraint + nEqExtConstr=DEFAULT_EXTCONSTROWS; + extConstrW=atof(argv[i+1]); + if(extConstrW==0.0){ + printf("ERROR: PE=%d -extConstr option given with no value or zero value ==> %le. Aborting\n",myid,extConstrW); + MPI_Abort(MPI_COMM_WORLD,1); exit(EXIT_FAILURE); } } - if (strcmp(argv[i], "-barConstr") == 0) + if(strcmp (argv[i],"-barConstr") == 0) { - barConstraint = 1; //extendet external constraint - nEqBarConstr = DEFAULT_BARCONSTROWS; - barConstrW = atof(argv[i + 1]); - if (barConstrW == 0.0) - { - printf("ERROR: PE=%d -barConstr option given with no value or zero value ==> %le. Aborting\n", myid, barConstrW); - MPI_Abort(MPI_COMM_WORLD, 1); + barConstraint=1; //extendet external constraint + nEqBarConstr=DEFAULT_BARCONSTROWS; + barConstrW=atof(argv[i+1]); + if(barConstrW==0.0){ + printf("ERROR: PE=%d -barConstr option given with no value or zero value ==> %le. Aborting\n",myid,barConstrW); + MPI_Abort(MPI_COMM_WORLD,1); exit(EXIT_FAILURE); } } + } - if (extConstraint) - noConstr = 2; - if (barConstraint) - noConstr = 2; - - if (myid == 0) - { - printf("Execution of solvergaia Simulator version %s on %d mpi-tasks\n solvergaiaSim ", VER, nproc); - if (idtest) - printf("-IDtest %le ", srIDtest); - if (precond) - printf("-Precond on"); - else - printf("-Precond off"); - if (nfileProc != 3) - printf("-numFilexproc %d ", nfileProc); - if (wrFilebin) - printf(" -wrfilebin %s ", wrfileDir); - if (!withFile) - printf(" -noFile "); - if (itnLimit > 0) - printf(" -itnlimit %d ", itnLimit); - if (noCPR > 0) - printf(" -noCPR "); - if (itnCPR != DEFAULT_ITNCPR) - printf(" -itnCPR %d ", itnCPR); - if (zeroAtt) - printf(" -zeroAtt "); - if (noConstr == 1) - printf(" -noConstr "); - if (zeroInstr) - printf(" -zeroInstr "); - if (zeroGlob) - printf(" -zeroGlob "); - if (inputDirOpt) - printf(" -inputDir %s ", inputDir); - if (outputDirOpt) - printf(" -outputDir %s ", outputDir); - if (wrsol) - printf(" -wrsol "); - if (noIter) - printf(" -noiter "); - if (debugMode) - printf(" -debug "); - if(ntasks>0) - printf(" -tasks %d ",ntasks); - if (extConstraint) - printf("-extConstr %le ", extConstrW); - if (barConstraint) - printf("-barConstr %le ", barConstrW); - printf("-wgic %d", wgInstrCoeff); - if (!autoRun) - printf(" %s\n", argv[argc - 1]); - if (extConstraint && barConstraint) - { + if (extConstraint) noConstr=2; + if (barConstraint) noConstr=2; + + + if(myid==0) + { + printf("Execution of solvergaia Simulator version %s on %d mpi-tasks\n solvergaiaSim ",VER,nproc); + if(idtest)printf ("-IDtest %le ", srIDtest); + if(precond)printf ("-Precond on"); + else printf ("-Precond off"); + if(nfileProc!=3) printf ("-numFilexproc %d ",nfileProc); + if(wrFilebin) printf(" -wrfilebin %s ",wrfileDir); + if(!withFile) printf(" -noFile "); + if(itnLimit>0) printf(" -itnlimit %d ",itnLimit); + if(noCPR>0) printf(" -noCPR "); + if(itnCPR!= DEFAULT_ITNCPR) printf(" -itnCPR %d ", itnCPR); + if(zeroAtt) printf(" -zeroAtt "); + if(noConstr==1) printf(" -noConstr "); + if(zeroInstr) printf(" -zeroInstr "); + if(zeroGlob) printf(" -zeroGlob "); + if(inputDirOpt) printf(" -inputDir %s ", inputDir); + if(outputDirOpt) printf(" -outputDir %s ", outputDir); + if(wrsol) printf(" -wrsol "); + if(noIter) printf(" -noiter "); + if(debugMode) printf(" -debug "); + if(extConstraint)printf("-extConstr %le ",extConstrW); + if(barConstraint)printf("-barConstr %le ",barConstrW); + printf("-wgic %d", wgInstrCoeff); + if(!autoRun) printf(" %s\n",argv[argc-1]); + if(extConstraint && barConstraint) { printf("Error: baricentric anld null space constraints are mutually exclusive. Aborting\n"); - MPI_Abort(MPI_COMM_WORLD, 1); + MPI_Abort(MPI_COMM_WORLD,1); exit(EXIT_FAILURE); } - if (wrFilebin && strcmp(inputDir, wrfileDir) == 0) - { + if(wrFilebin && strcmp(inputDir, wrfileDir)==0){ printf("inputDir and wrfilebinDir are the same. Execution Aborted.\n"); - MPI_Abort(MPI_COMM_WORLD, 1); + MPI_Abort(MPI_COMM_WORLD,1); exit(EXIT_FAILURE); + } - printf ("\n"); } ///////////////// - getcwd(wpath, sizePath); - if (!inputDirOpt) + getcwd(wpath,sizePath); + if(!inputDirOpt) strcpy(inputDir, wpath); - printf("Process %d running on %s\n", myid, processor_name); -////#ifdef OMP -///#pragma omp task + printf("Process %d running on %s\n",myid,processor_name); +#ifdef OMP +#pragma omp parallel { - // int tid = omp_get_thread_num(); - /* - const char* s = getenv("NX_SMP_WORKERS");//? "":"1"; - if(s ==NULL) - s="1"; - nthreads = atoi(s); //QUI** verifica che la chiamata ritorni il numero di tasks allocati!! - */ - - //nthreads sono attuatori - // ntasks sono la mia suddivisione - nthreads=omp_get_num_threads(); - if(ntasks==0) - ntasks=nthreads; - printf("PE=%d on processor %s total num of threads =%d, ntasks=%d\n",myid, processor_name,nthreads,ntasks); + int tid = omp_get_thread_num(); + int nthreads = omp_get_num_threads(); + printf("PE=%d on processor %s total num of threads =%d ID thread =%d \n",myid, processor_name,nthreads,tid); + } -////#pragma omp taskwait -////#endif - nullSpaceAttfact = 1.0 * attExtConstrFact * extConstrW; - comlsqr.extConstrW = extConstrW; - comlsqr.nullSpaceAttfact = nullSpaceAttfact; - comlsqr.barConstrW = barConstrW; - - if (inputDirOpt) +#endif + nullSpaceAttfact=1.0*attExtConstrFact*extConstrW; + comlsqr.extConstrW=extConstrW; + comlsqr.nullSpaceAttfact=nullSpaceAttfact; + comlsqr.barConstrW=barConstrW; + + + if(inputDirOpt) { - if (myid == 0) - printf("Checking input directory %s ... ", inputDir); - if (!(chdir(inputDir) == 0)) - { + if(myid==0) printf("Checking input directory %s ... ", inputDir); + if(!(chdir(inputDir)==0)) { printf("Input directory does not exist. Aborting\n"); - MPI_Abort(MPI_COMM_WORLD, 1); + MPI_Abort(MPI_COMM_WORLD,1); exit(EXIT_FAILURE); } chdir(wpath); - if (myid == 0) - printf("success.\n"); + if(myid==0) printf("success.\n"); } - inputDirLen = strlen(inputDir); - sprintf(filenameSolProps, "%s", argv[argc - 1]); - sprintf(filenameSolPropsFinal, "GsrFinal_%s", argv[argc - 1]); - - if (outputDirOpt) + inputDirLen=strlen(inputDir); + sprintf(filenameSolProps, "%s", argv[argc-1]); + sprintf(filenameSolPropsFinal,"GsrFinal_%s", argv[argc-1]); + + if(outputDirOpt) { - if (myid == 0) - printf("Checking output directory %s ...", outputDir); - if (!(chdir(outputDir) == 0)) - { + if(myid==0) printf("Checking output directory %s ...", outputDir); + if(!(chdir(outputDir)==0)) { printf("Output directory does not exist on PE %d. Aborting\n", myid); - MPI_Abort(MPI_COMM_WORLD, 1); + MPI_Abort(MPI_COMM_WORLD,1); exit(EXIT_FAILURE); } - if (myid == 0) - printf("success.\n"); + if(myid==0) printf("success.\n"); } - + ///////////// Initialize the output filename - sprintf(filenameAstroResults, "%s", "GsrAstroParamSolution.bin"); // file storing the Astrometric Parameters - sprintf(filenameAttResults, "%s", "GsrAttitudeParamSolution.bin"); // file storing the Attitude Parameters - sprintf(filenameInstrResults, "%s", "GsrInstrParamSolution.bin"); // file storing the Instrument Parameters - sprintf(filenameGlobalResults, "%s", "GsrGlobalParamSolution.bin"); // file storing the Global Parameters - - // instrConst=(int *) calloc(DEFAULT_NINSTRINDEXES+1 , sizeof(int)); - instrConst = (int *)calloc(DEFAULT_NINSTRINDEXES, sizeof(int)); - nAttParAxis = 4; + sprintf(filenameAstroResults, "%s", "GsrAstroParamSolution.bin"); // file storing the Astrometric Parameters + sprintf(filenameAttResults, "%s","GsrAttitudeParamSolution.bin"); // file storing the Attitude Parameters + sprintf(filenameInstrResults, "%s","GsrInstrParamSolution.bin"); // file storing the Instrument Parameters + sprintf(filenameGlobalResults, "%s","GsrGlobalParamSolution.bin"); // file storing the Global Parameters + + +// instrConst=(int *) calloc(DEFAULT_NINSTRINDEXES+1 , sizeof(int)); + instrConst=(int *) calloc(DEFAULT_NINSTRINDEXES , sizeof(int)); + nAttParAxis=4; //START READING filenameSolProps //START READING filenameSolProps GsrSolProps.dat - if (myid == 0 && wrFilebin) - { + if(myid==0 && wrFilebin){ chdir(wpath); chdir(wrfileDir); - fpSolPropsFileBin = fopen(filenameSolProps, "w"); + fpSolPropsFileBin=fopen(filenameSolProps,"w"); } chdir(wpath); - if (inputDirOpt) - chdir(inputDir); - if (myid == 0) - { - if (autoRun) - { - sphereId = 0; - atol = 0.000000; - btol = 0.000000; - conlim = 10000000000000.000000; - itnlim = 2000; - if (itnLimit > 0) - itnlim = itnLimit; - damp = 0.000000; - nStar = 10000; - nAstroP = 5; - nAstroPSolved = 5; - nConstrLat = 0; - nConstrLong = 0; - nConstrMuLat = 0; - nConstrMuLong = 0; - nDegFreedomAtt = 230489; - nAttAxes = 3; - instrConst[0] = 1; - instrConst[1] = 62; - instrConst[2] = 1966; - instrConst[3] = 22; - nInstrP = 6; - nInstrPSolved = 6; - lsInstrFlag = 1; - ssInstrFlag = 1; - nuInstrFlag = 1; - maInstrFlag = 1; - nOfInstrConstr = -1; - nElemIC = -1; - nGlobP = 0; - nobs = 2400000; + if(inputDirOpt) chdir(inputDir); + if(myid==0) + { + if (autoRun){ + sphereId=0; + atol= 0.000000; + btol= 0.000000; + conlim= 10000000000000.000000; + itnlim= 2000; + if(itnLimit>0) + itnlim=itnLimit; + damp= 0.000000; + nStar= 10000; + nAstroP= 5; + nAstroPSolved= 5; + nConstrLat= 0; + nConstrLong= 0; + nConstrMuLat= 0; + nConstrMuLong= 0; + nDegFreedomAtt= 230489; + nAttAxes= 3; + instrConst[0]= 1; + instrConst[1]= 62; + instrConst[2]= 1966; + instrConst[3]= 22; + nInstrP= 6; + nInstrPSolved= 6; + lsInstrFlag= 1; + ssInstrFlag= 1; + nuInstrFlag= 1; + maInstrFlag= 1; + nOfInstrConstr= -1; + nElemIC= -1; + nGlobP= 0; + nobs= 2400000; nAstroParam = nStar * nAstroPSolved; nAttParam = nDegFreedomAtt * nAttAxes; - if (nDegFreedomAtt < 4) - nAttParAxis = nDegFreedomAtt; - if (nDegFreedomAtt) - nAttP = nAttAxes * nAttParAxis; - long nFoVs = 1 + instrConst[0]; - long nCCDs = instrConst[1]; - long nPixelColumns = instrConst[2]; - long nTimeIntervals = instrConst[3]; + if(nDegFreedomAtt<4) nAttParAxis=nDegFreedomAtt; + if(nDegFreedomAtt) nAttP = nAttAxes * nAttParAxis; + long nFoVs=1+instrConst[0]; + long nCCDs=instrConst[1]; + long nPixelColumns=instrConst[2]; + long nTimeIntervals=instrConst[3]; // tot. instr. param. = nCCDs (Cmag) + nFoVs*nCCDs (Cnu) + nCCDs*nPixelColumns (delta_eta) + 3*nFoVs*nCCDs*nTimeIntervals (Delta_eta) + nCCDs*nPixelColumns (delta_zeta) + 3*nFoVs*nCCDs*nTimeIntervals (Delta_zeta) // added flags switch on and off the appropriate kind of parameters - nInstrParam = maInstrFlag * nCCDs + nuInstrFlag * nFoVs * nCCDs + ssInstrFlag * 2 * nCCDs * nPixelColumns + lsInstrFlag * 2 * 3 * nFoVs * nCCDs * nTimeIntervals; - nInstrParamTot = nCCDs + nFoVs * nCCDs + 2 * nCCDs * nPixelColumns + 2 * 3 * nFoVs * nCCDs * nTimeIntervals; - if (nInstrP == 0) - nInstrParamTot = 0; + nInstrParam = maInstrFlag*nCCDs+nuInstrFlag*nFoVs*nCCDs+ssInstrFlag*2*nCCDs*nPixelColumns+lsInstrFlag*2*3*nFoVs*nCCDs*nTimeIntervals; + nInstrParamTot = nCCDs+ nFoVs*nCCDs+ 2*nCCDs*nPixelColumns+2*3*nFoVs*nCCDs*nTimeIntervals; + if(nInstrP==0) nInstrParamTot=0; nGlobalParam = nGlobP; - + nparam = nAstroPSolved + nAttP + nInstrPSolved + nGlobP; - if (memGlobal != 0) - { - memGB = simfullram(nStar, nobs, memGlobal, nparam, nAttParam, nInstrParam); - printf("Running with memory %f GB, nStar=%d nobs=%ld\n", memGB, nStar, nobs); + if(memGlobal!=0){ + memGB=simfullram(nStar,nobs,memGlobal,nparam,nAttParam,nInstrParam); + printf("Running with memory %f GB, nStar=%d nobs=%ld\n",memGB, nStar,nobs); } printf("sphereId= %7ld\n", sphereId); printf("atol= %18.15lf\n", atol); @@ -619,7 +557,7 @@ int main(int argc, char **argv) printf("nConstrMuLong= %5ld\n", nConstrMuLong); printf("nDegFreedomAtt= %7ld\n", nDegFreedomAtt); printf("nAttAxes= %7hd\n", nAttAxes); - printf("nFovs= %7d ", instrConst[0] + 1); + printf("nFovs= %7d ", instrConst[0]+1); printf("(instrConst[0])= %7d\n", instrConst[0]); printf("nCCDs= %7d\n", instrConst[1]); printf("nPixelColumns= %7d\n", instrConst[2]); @@ -634,750 +572,616 @@ int main(int argc, char **argv) printf("nElemIC= %7d\n", nElemIC); printf("nGlobP= %7hd\n", nGlobP); printf("nObs= %10ld\n", nobs); - if (wrFilebin) - { - fprintf(fpSolPropsFileBin, "sphereId= %ld\n", sphereId); - fprintf(fpSolPropsFileBin, "atol= %lf\n", atol); - fprintf(fpSolPropsFileBin, "btol= %lf\n", btol); - fprintf(fpSolPropsFileBin, "conlim= %lf\n", conlim); - fprintf(fpSolPropsFileBin, "itnlim= %ld\n", itnlim); - fprintf(fpSolPropsFileBin, "damp= %lf\n", damp); - fprintf(fpSolPropsFileBin, "nStar= %ld\n", nStar); - fprintf(fpSolPropsFileBin, "nAstroP= %hd\n", nAstroP); - fprintf(fpSolPropsFileBin, "nAstroPSolved= %hd\n", nAstroPSolved); - fprintf(fpSolPropsFileBin, "nConstrLat= 0\n"); - fprintf(fpSolPropsFileBin, "nConstrLong= 0\n"); - fprintf(fpSolPropsFileBin, "nConstrMuLat= 0\n"); - fprintf(fpSolPropsFileBin, "nConstrMuLong= 0\n"); - fprintf(fpSolPropsFileBin, "nDegFreedomAtt= %ld\n", nDegFreedomAtt); - fprintf(fpSolPropsFileBin, "nAttAxes= %hd\n", nAttAxes); - fprintf(fpSolPropsFileBin, "nFoVs= %d\n", instrConst[0]); - fprintf(fpSolPropsFileBin, "nCCDs= %d\n", instrConst[1]); - fprintf(fpSolPropsFileBin, "nPixelColumns= %d\n", instrConst[2]); - fprintf(fpSolPropsFileBin, "nTimeIntervals= %d\n", instrConst[3]); - fprintf(fpSolPropsFileBin, "nInstrP= %hd\n", nInstrP); - fprintf(fpSolPropsFileBin, "nInstrPSolved= %hd\n", nInstrPSolved); - fprintf(fpSolPropsFileBin, "lsInstrFlag= %hd\n", lsInstrFlag); - fprintf(fpSolPropsFileBin, "ssInstrFlag= %hd\n", ssInstrFlag); - fprintf(fpSolPropsFileBin, "nuInstrFlag= %hd\n", nuInstrFlag); - fprintf(fpSolPropsFileBin, "maInstrFlag= %hd\n", maInstrFlag); - fprintf(fpSolPropsFileBin, "nOfInstrConstr= %d\n", nOfInstrConstr); - fprintf(fpSolPropsFileBin, "nElemIC= %d\n", nElemIC); - fprintf(fpSolPropsFileBin, "nGlobP= %hd\n", nGlobP); - fprintf(fpSolPropsFileBin, "nObs= %ld\n", nobs); + if(wrFilebin){ + fprintf(fpSolPropsFileBin,"sphereId= %ld\n", sphereId); + fprintf(fpSolPropsFileBin,"atol= %lf\n", atol); + fprintf(fpSolPropsFileBin,"btol= %lf\n", btol); + fprintf(fpSolPropsFileBin,"conlim= %lf\n", conlim); + fprintf(fpSolPropsFileBin,"itnlim= %ld\n", itnlim); + fprintf(fpSolPropsFileBin,"damp= %lf\n", damp); + fprintf(fpSolPropsFileBin,"nStar= %ld\n", nStar); + fprintf(fpSolPropsFileBin,"nAstroP= %hd\n", nAstroP); + fprintf(fpSolPropsFileBin,"nAstroPSolved= %hd\n", nAstroPSolved); + fprintf(fpSolPropsFileBin,"nConstrLat= 0\n"); + fprintf(fpSolPropsFileBin,"nConstrLong= 0\n"); + fprintf(fpSolPropsFileBin,"nConstrMuLat= 0\n"); + fprintf(fpSolPropsFileBin,"nConstrMuLong= 0\n"); + fprintf(fpSolPropsFileBin,"nDegFreedomAtt= %ld\n", nDegFreedomAtt); + fprintf(fpSolPropsFileBin,"nAttAxes= %hd\n", nAttAxes); + fprintf(fpSolPropsFileBin,"nFoVs= %d\n", instrConst[0]); + fprintf(fpSolPropsFileBin,"nCCDs= %d\n", instrConst[1]); + fprintf(fpSolPropsFileBin,"nPixelColumns= %d\n", instrConst[2]); + fprintf(fpSolPropsFileBin,"nTimeIntervals= %d\n", instrConst[3]); + fprintf(fpSolPropsFileBin,"nInstrP= %hd\n", nInstrP); + fprintf(fpSolPropsFileBin,"nInstrPSolved= %hd\n", nInstrPSolved); + fprintf(fpSolPropsFileBin,"lsInstrFlag= %hd\n", lsInstrFlag); + fprintf(fpSolPropsFileBin,"ssInstrFlag= %hd\n", ssInstrFlag); + fprintf(fpSolPropsFileBin,"nuInstrFlag= %hd\n", nuInstrFlag); + fprintf(fpSolPropsFileBin,"maInstrFlag= %hd\n", maInstrFlag); + fprintf(fpSolPropsFileBin,"nOfInstrConstr= %d\n", nOfInstrConstr); + fprintf(fpSolPropsFileBin,"nElemIC= %d\n", nElemIC); + fprintf(fpSolPropsFileBin,"nGlobP= %hd\n", nGlobP); + fprintf(fpSolPropsFileBin,"nObs= %ld\n", nobs); fclose(fpSolPropsFileBin); } + }else{ + fpSolProps=fopen(filenameSolProps,"r"); + if (!fpSolProps) + { + printf("Error while open %s\n",filenameSolProps); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + + if(fscanf(fpSolProps, "sphereId= %ld\n",&sphereId) != 1) { + printf("Error reading sphereId %ld \n",sphereId); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + printf("sphereId= %7ld\n", sphereId); + if(wrFilebin) fprintf(fpSolPropsFileBin,"sphereId= %ld\n", sphereId); + + if(fscanf(fpSolProps, "atol= %lf\n",&atol) != 1) { + printf("Error reading atol %lf \n",atol); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + if(aTol >=0) + atol=aTol; + printf("atol= %18.15lf\n", atol); + if(wrFilebin) fprintf(fpSolPropsFileBin,"atol= %lf\n", atol); + + if(fscanf(fpSolProps, "btol= %lf\n",&btol) != 1) { + printf("Error reading btol %lf \n",btol); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + printf("btol= %18.15lf\n", btol); + if(wrFilebin) fprintf(fpSolPropsFileBin,"btol= %lf\n", btol); + + if(fscanf(fpSolProps, "conlim= %lf\n",&conlim) != 1) { + printf("Error reading conlim %lf \n",conlim); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + printf("conlim= %18.15le\n", conlim); + if(wrFilebin) fprintf(fpSolPropsFileBin,"conlim= %lf\n", conlim); + + if(fscanf(fpSolProps, "itnlim= %ld\n",&itnlim) != 1) { + printf("Error reading itnlim %ld \n",itnlim); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + if(itnLimit>0) + itnlim=itnLimit; + printf("itnlim= %7ld\n", itnlim); + if(wrFilebin) fprintf(fpSolPropsFileBin,"itnlim= %ld\n", itnlim); + + if(fscanf(fpSolProps, "damp= %lf\n",&damp) != 1) { + printf("Error reading damp %lf \n",damp); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + printf("damp= %18.15lf\n", damp); + if(wrFilebin) fprintf(fpSolPropsFileBin,"damp= %lf\n", damp); + + if(fscanf(fpSolProps, "nStar= %ld\n",&nStar) != 1) { + printf("Error reading nStar %ld \n",nStar); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + printf("nStar= %7ld\n", nStar); + if(wrFilebin) fprintf(fpSolPropsFileBin,"nStar= %ld\n", nStar); + + if(fscanf(fpSolProps, "nAstroP= %hd\n",&nAstroP) != 1) { + printf("Error reading nAstroP %hd \n",nAstroP); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + printf("nAstroP= %7hd\n", nAstroP); + if(wrFilebin) fprintf(fpSolPropsFileBin,"nAstroP= %hd\n", nAstroP); + + if(fscanf(fpSolProps, "nAstroPSolved= %hd\n",&nAstroPSolved) != 1) { + printf("Error reading nAstroPSolved %hd \n",nAstroPSolved); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); } - else + printf("nAstroPSolved= %hd\n", nAstroPSolved); + if(wrFilebin) fprintf(fpSolPropsFileBin,"nAstroPSolved= %hd\n", nAstroPSolved); + + if(fscanf(fpSolProps, "nConstrLat= %ld\n",&nConstrLat) != 1) { + printf("Error reading nConstrLat %ld \n",nConstrLat); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + printf("nConstrLat= %5ld\n", nConstrLat); + if(wrFilebin){ + if(noConstr) fprintf(fpSolPropsFileBin,"nConstrLat= 0\n"); + else fprintf(fpSolPropsFileBin,"nConstrLat= %ld\n", nConstrLat); + } + if(nConstrLat>0) { - fpSolProps = fopen(filenameSolProps, "r"); - if (!fpSolProps) - { - printf("Error while open %s\n", filenameSolProps); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - - if (fscanf(fpSolProps, "sphereId= %ld\n", &sphereId) != 1) - { - printf("Error reading sphereId %ld \n", sphereId); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - printf("sphereId= %7ld\n", sphereId); - if (wrFilebin) - fprintf(fpSolPropsFileBin, "sphereId= %ld\n", sphereId); - - if (fscanf(fpSolProps, "atol= %lf\n", &atol) != 1) - { - printf("Error reading atol %lf \n", atol); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - if (aTol >= 0) - atol = aTol; - printf("atol= %18.15lf\n", atol); - if (wrFilebin) - fprintf(fpSolPropsFileBin, "atol= %lf\n", atol); - - if (fscanf(fpSolProps, "btol= %lf\n", &btol) != 1) - { - printf("Error reading btol %lf \n", btol); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - printf("btol= %18.15lf\n", btol); - if (wrFilebin) - fprintf(fpSolPropsFileBin, "btol= %lf\n", btol); - - if (fscanf(fpSolProps, "conlim= %lf\n", &conlim) != 1) - { - printf("Error reading conlim %lf \n", conlim); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - printf("conlim= %18.15le\n", conlim); - if (wrFilebin) - fprintf(fpSolPropsFileBin, "conlim= %lf\n", conlim); - - if (fscanf(fpSolProps, "itnlim= %ld\n", &itnlim) != 1) - { - printf("Error reading itnlim %ld \n", itnlim); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - if (itnLimit > 0) - itnlim = itnLimit; - printf("itnlim= %7ld\n", itnlim); - if (wrFilebin) - fprintf(fpSolPropsFileBin, "itnlim= %ld\n", itnlim); - - if (fscanf(fpSolProps, "damp= %lf\n", &damp) != 1) - { - printf("Error reading damp %lf \n", damp); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - printf("damp= %18.15lf\n", damp); - if (wrFilebin) - fprintf(fpSolPropsFileBin, "damp= %lf\n", damp); - - if (fscanf(fpSolProps, "nStar= %ld\n", &nStar) != 1) - { - printf("Error reading nStar %ld \n", nStar); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - printf("nStar= %7ld\n", nStar); - if (wrFilebin) - fprintf(fpSolPropsFileBin, "nStar= %ld\n", nStar); - - if (fscanf(fpSolProps, "nAstroP= %hd\n", &nAstroP) != 1) - { - printf("Error reading nAstroP %hd \n", nAstroP); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - printf("nAstroP= %7hd\n", nAstroP); - if (wrFilebin) - fprintf(fpSolPropsFileBin, "nAstroP= %hd\n", nAstroP); - - if (fscanf(fpSolProps, "nAstroPSolved= %hd\n", &nAstroPSolved) != 1) - { - printf("Error reading nAstroPSolved %hd \n", nAstroPSolved); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - printf("nAstroPSolved= %hd\n", nAstroPSolved); - if (wrFilebin) - fprintf(fpSolPropsFileBin, "nAstroPSolved= %hd\n", nAstroPSolved); - - if (fscanf(fpSolProps, "nConstrLat= %ld\n", &nConstrLat) != 1) - { - printf("Error reading nConstrLat %ld \n", nConstrLat); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - printf("nConstrLat= %5ld\n", nConstrLat); - if (wrFilebin) - { - if (noConstr) - fprintf(fpSolPropsFileBin, "nConstrLat= 0\n"); - else - fprintf(fpSolPropsFileBin, "nConstrLat= %ld\n", nConstrLat); - } - if (nConstrLat > 0) - { - constrLatId = (long *)calloc(nConstrLat, sizeof(long)); - for (i = 0; i < nConstrLat - 1; i++) - { - if (fscanf(fpSolProps, "%ld ", &constrLatId[i]) != 1) - { - printf("Error reading constrLatId[%d] %ld \n", i, constrLatId[i]); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - if (debugMode) - printf("constrLatId[%d]=%7ld ", i, constrLatId[i]); - if (wrFilebin && !noConstr) - fprintf(fpSolPropsFileBin, "%ld ", constrLatId[i]); - } - if (fscanf(fpSolProps, "%ld\n", &constrLatId[nConstrLat - 1]) != 1) - { - printf("Error reading constrLatId[nConstrLat-1] %ld \n", constrLatId[nConstrLat - 1]); - MPI_Abort(MPI_COMM_WORLD, 1); + constrLatId = (long *) calloc(nConstrLat, sizeof(long)); + for(i=0;i 0) - { - constrLongId = (long *)calloc(nConstrLong, sizeof(long)); - for (i = 0; i < nConstrLong - 1; i++) - { - if (fscanf(fpSolProps, "%ld ", &constrLongId[i]) != 1) - { - printf("Error reading constrLongId[%d] %ld \n", i, constrLongId[i]); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - if (debugMode) - printf("constrLongId[%d]=%7ld ", i, constrLongId[i]); - if (wrFilebin && !noConstr) - fprintf(fpSolPropsFileBin, "%ld ", constrLongId[i]); - } - if (fscanf(fpSolProps, "%ld\n", &constrLongId[nConstrLong - 1]) != 1) - { - printf("Error reading constrLongId[nConstrLong-1] %ld \n", constrLongId[nConstrLong - 1]); - MPI_Abort(MPI_COMM_WORLD, 1); + if(debugMode) printf("constrLatW[nConstrLat-1]=%18.15lf\n",constrLatW[nConstrLat-1]); + if(wrFilebin && !noConstr) fprintf(fpSolPropsFileBin,"%lf\n",constrLatW[nConstrLat-1]); + } + + if(fscanf(fpSolProps, "nConstrLong= %ld\n",&nConstrLong) != 1) { + printf("Error reading nConstrLong %ld \n",nConstrLong); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + printf("nConstrLong= %5ld\n", nConstrLong); + if(wrFilebin){ + if(noConstr) fprintf(fpSolPropsFileBin,"nConstrLong= 0\n"); + else fprintf(fpSolPropsFileBin,"nConstrLong= %ld\n", nConstrLong); + } + if(nConstrLong>0) + { + constrLongId = (long *) calloc(nConstrLong, sizeof(long)); + for(i=0;i 0) - { - constrMuLatId = (long *)calloc(nConstrMuLat, sizeof(long)); - for (i = 0; i < nConstrMuLat - 1; i++) - { - if (fscanf(fpSolProps, "%ld ", &constrMuLatId[i]) != 1) - { - printf("Error reading constrMuLatId[%d] %ld \n", i, constrMuLatId[i]); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - if (debugMode) - printf("constrMuLatId[%d]=%7ld ", i, constrMuLatId[i]); - if (wrFilebin && !noConstr) - fprintf(fpSolPropsFileBin, "%ld ", constrMuLatId[i]); - } - if (fscanf(fpSolProps, "%ld\n", &constrMuLatId[nConstrMuLat - 1]) != 1) - { - printf("Error reading constrMuLatId[nConstrMuLat-1] %ld \n", constrMuLatId[nConstrMuLat - 1]); - MPI_Abort(MPI_COMM_WORLD, 1); + if(debugMode) printf("constrLongW[nConstrLong-1]=%18.15lf\n",constrLongW[nConstrLong-1]); + if(wrFilebin && !noConstr) fprintf(fpSolPropsFileBin,"%lf\n",constrLongW[nConstrLong-1]); + } + + if(fscanf(fpSolProps, "nConstrMuLat= %ld\n",&nConstrMuLat) != 1) { + printf("Error reading nConstrMuLat %ld \n",nConstrMuLat); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + printf("nConstrMuLat= %5ld\n", nConstrMuLat); + if(wrFilebin){ + if(noConstr) fprintf(fpSolPropsFileBin,"nConstrMuLat= 0\n"); + else fprintf(fpSolPropsFileBin,"nConstrMuLat= %ld\n", nConstrMuLat); + } + + if(nConstrMuLat>0) + { + constrMuLatId = (long *) calloc(nConstrMuLat, sizeof(long)); + for(i=0;i 0) - { - constrMuLongId = (long *)calloc(nConstrMuLong, sizeof(long)); - for (i = 0; i < nConstrMuLong - 1; i++) - { - if (fscanf(fpSolProps, "%ld ", &constrMuLongId[i]) != 1) - { - printf("Error reading constrMuLongId[%d] %ld \n", i, constrMuLongId[i]); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - if (debugMode) - printf("constrMuLongId[%d]=%7ld ", i, constrMuLongId[i]); - if (wrFilebin && !noConstr) - fprintf(fpSolPropsFileBin, "%7ld ", constrMuLongId[i]); - } - if (fscanf(fpSolProps, "%ld\n", &constrMuLongId[nConstrMuLong - 1]) != 1) - { - printf("Error reading constrMuLongId[nConstrMuLong-1] %ld \n", constrMuLongId[nConstrMuLong - 1]); - MPI_Abort(MPI_COMM_WORLD, 1); + if(debugMode) printf("constrMuLatW[nConstrMuLat-1]=%18.15lf\n",constrMuLatW[nConstrMuLat-1]); + if(wrFilebin && !noConstr) fprintf(fpSolPropsFileBin,"%lf\n",constrMuLatW[nConstrMuLat-1]); + + } + + if(fscanf(fpSolProps, "nConstrMuLong= %ld\n",&nConstrMuLong) != 1) { + printf("Error reading nConstrMuLong %ld \n",nConstrMuLong); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + printf("nConstrMuLong= %5ld\n", nConstrMuLong); + if(wrFilebin){ + if(noConstr) fprintf(fpSolPropsFileBin,"nConstrMuLong= 0\n"); + else fprintf(fpSolPropsFileBin,"nConstrMuLong= %ld\n", nConstrMuLong); + } + if(nConstrMuLong>0) + { + constrMuLongId = (long *) calloc(nConstrMuLong, sizeof(long)); + for(i=0;i 1) - { - printf("Execution aborted with invalid nFovs=%d\n", instrConst[0] + 1); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - printf("nFovs= %7d ", instrConst[0] + 1); - printf("(instrConst[0])= %7d\n", instrConst[0]); - if (wrFilebin) - fprintf(fpSolPropsFileBin, "nFoVs= %d\n", instrConst[0]); - - if (fscanf(fpSolProps, "nCCDs= %d\n", &instrConst[1]) != 1) - { - printf("Error reading nCCDs %d \n", instrConst[1]); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - if (zeroInstr) - instrConst[1] = 0; - printf("nCCDs= %7d\n", instrConst[1]); - if (wrFilebin) - fprintf(fpSolPropsFileBin, "nCCDs= %d\n", instrConst[1]); - - if (fscanf(fpSolProps, "nPixelColumns= %d\n", &instrConst[2]) != 1) - { - printf("Error reading nPixelColumns %d \n", instrConst[2]); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - if (zeroInstr) - instrConst[2] = 0; - printf("nPixelColumns= %7d\n", instrConst[2]); - if (wrFilebin) - fprintf(fpSolPropsFileBin, "nPixelColumns= %d\n", instrConst[2]); - - if (fscanf(fpSolProps, "nTimeIntervals= %d\n", &instrConst[3]) != 1) - { - printf("Error reading nTimeIntervals %d \n", instrConst[3]); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - if (zeroInstr) - instrConst[3] = 0; - printf("nTimeIntervals= %7d\n", instrConst[3]); - if (wrFilebin) - fprintf(fpSolPropsFileBin, "nTimeIntervals= %d\n", instrConst[3]); - - if (fscanf(fpSolProps, "nInstrP= %hd\n", &nInstrP) != 1) - { - printf("Error reading nInstrP %hd \n", nInstrP); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - if (zeroInstr) - nInstrP = 0; - printf("nInstrP= %7hd\n", nInstrP); - if (nInstrP != 0 && nInstrP != 6) - { - printf("Execution aborted with invalid nInstrP\n"); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - if (wrFilebin) - fprintf(fpSolPropsFileBin, "nInstrP= %hd\n", nInstrP); - if (fscanf(fpSolProps, "nInstrPSolved= %hd\n", &nInstrPSolved) != 1) - { - printf("Error reading nInstrPSolved %hd \n", nInstrPSolved); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - printf("nInstrPSolved= %7hd\n", nInstrPSolved); - - if (nInstrPSolved < 0 || nInstrPSolved > 6) - { - printf("Execution aborted with invalid nInstrPSolved\n"); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - if (wrFilebin) - fprintf(fpSolPropsFileBin, "nInstrPSolved= %hd\n", nInstrPSolved); - - if (fscanf(fpSolProps, "lsInstrFlag= %d\n", &lsInstrFlag) != 1) - { - printf("Error reading lsInstrFlag %d \n", lsInstrFlag); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - printf("lsInstrFlag= %7d\n", lsInstrFlag); - - if (lsInstrFlag < 0 || lsInstrFlag > 1) - { - printf("Execution aborted with invalid lsInstrFlag\n"); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - if (wrFilebin) - fprintf(fpSolPropsFileBin, "lsInstrFlag= %hd\n", lsInstrFlag); - if (fscanf(fpSolProps, "ssInstrFlag= %d\n", &ssInstrFlag) != 1) - { - printf("Error reading ssInstrFlag %d \n", ssInstrFlag); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - printf("ssInstrFlag= %7d\n", ssInstrFlag); - - if (ssInstrFlag < 0 || ssInstrFlag > 1) - { - printf("Execution aborted with invalid ssInstrFlag\n"); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - if (wrFilebin) - fprintf(fpSolPropsFileBin, "ssInstrFlag= %hd\n", ssInstrFlag); - if (fscanf(fpSolProps, "nuInstrFlag= %d\n", &nuInstrFlag) != 1) - { - printf("Error reading nuInstrFlag %d \n", nuInstrFlag); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - printf("nuInstrFlag= %7d\n", nuInstrFlag); - - if (nuInstrFlag < 0 || nuInstrFlag > 1) - { - printf("Execution aborted with invalid lsInstrFlag\n"); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - if (wrFilebin) - fprintf(fpSolPropsFileBin, "nuInstrFlag= %hd\n", nuInstrFlag); - if (fscanf(fpSolProps, "maInstrFlag= %d\n", &maInstrFlag) != 1) - { - printf("Error reading maInstrFlag %d \n", maInstrFlag); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - printf("maInstrFlag= %7d\n", maInstrFlag); - - if (maInstrFlag < 0 || maInstrFlag > 1) - { - printf("Execution aborted with invalid maInstrFlag\n"); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - if (wrFilebin) - fprintf(fpSolPropsFileBin, "maInstrFlag= %hd\n", maInstrFlag); - - if (nInstrPSolved != maInstrFlag + nuInstrFlag + ssInstrFlag + 3 * lsInstrFlag) - { - printf("Execution aborted invalid nInstrPSolved=%d. It should be =%d\n", nInstrPSolved, maInstrFlag + nuInstrFlag + ssInstrFlag + 3 * lsInstrFlag); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - - if (fscanf(fpSolProps, "nOfInstrConstr= %d\n", &nOfInstrConstr) != 1) - { - printf("Error reading nOfInstrConstr %d \n", nOfInstrConstr); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - printf("nOfInstrConstr= %7d\n", nOfInstrConstr); - if (wrFilebin) - fprintf(fpSolPropsFileBin, "nOfInstrConstr= %d\n", nOfInstrConstr); - - if (fscanf(fpSolProps, "nElemIC= %d\n", &nElemIC) != 1) - { - printf("Error reading nElemIC %d \n", nElemIC); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - printf("nElemIC= %7d\n", nElemIC); - if (wrFilebin) - fprintf(fpSolPropsFileBin, "nElemIC= %d\n", nElemIC); - - if (fscanf(fpSolProps, "nGlobP= %hd\n", &nGlobP) != 1) - { - printf("Error reading nGlobP %hd \n", nGlobP); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - if (zeroGlob) - nGlobP = 0; - printf("nGlobP= %7hd\n", nGlobP); - if (wrFilebin) - fprintf(fpSolPropsFileBin, "nGlobP= %hd\n", nGlobP); - - if (fscanf(fpSolProps, "nObs= %ld\n", &nobs) != 1) - { - printf("Error reading nObs %ld \n", nobs); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } - printf("nObs= %10ld\n", nobs); - if (wrFilebin) - fprintf(fpSolPropsFileBin, "nObs= %ld\n", nobs); - - fclose(fpSolProps); - if (wrFilebin) - fclose(fpSolPropsFileBin); - } //if (autoRun) else - } + if(debugMode) printf("constrMuLongW[nConstrMuLong-1]=%18.15lf\n",constrMuLongW[nConstrMuLong-1]); + if(wrFilebin && !noConstr) fprintf(fpSolPropsFileBin,"%lf\n",constrMuLongW[nConstrMuLong-1]); + } + + if(fscanf(fpSolProps, "nDegFreedomAtt= %ld\n",&nDegFreedomAtt) != 1) { + printf("Error reading nDegFreedomAtt %ld \n",nDegFreedomAtt); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + if(zeroAtt) nDegFreedomAtt=0; + printf("nDegFreedomAtt= %7ld\n", nDegFreedomAtt); + if(wrFilebin) fprintf(fpSolPropsFileBin,"nDegFreedomAtt= %ld\n", nDegFreedomAtt); + + if(fscanf(fpSolProps, "nAttAxes= %hd\n",&nAttAxes) != 1) { + printf("Error reading nAttAxes %hd \n",nAttAxes); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + if(zeroAtt) nAttAxes=0; + printf("nAttAxes= %7hd\n", nAttAxes); + if(wrFilebin) fprintf(fpSolPropsFileBin,"nAttAxes= %hd\n", nAttAxes); + + if(fscanf(fpSolProps, "nFoVs= %d\n",&instrConst[0]) != 1) { + printf("Error reading nFoVs %d \n",instrConst[0]); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + if(zeroInstr) instrConst[0]=0; + // instrConst[0] must be 0 or 1 because nFoVs = 2 for Gaia and nFoVs=1+instrConst[0] + if(instrConst[0]<0 || instrConst[0]>1){ + printf("Execution aborted with invalid nFovs=%d\n",instrConst[0]+1); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + + } + printf("nFovs= %7d ", instrConst[0]+1); + printf("(instrConst[0])= %7d\n", instrConst[0]); + if(wrFilebin) fprintf(fpSolPropsFileBin,"nFoVs= %d\n", instrConst[0]); + + if(fscanf(fpSolProps, "nCCDs= %d\n",&instrConst[1]) != 1) { + printf("Error reading nCCDs %d \n",instrConst[1]); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + if(zeroInstr) instrConst[1]=0; + printf("nCCDs= %7d\n", instrConst[1]); + if(wrFilebin) fprintf(fpSolPropsFileBin,"nCCDs= %d\n", instrConst[1]); + + if(fscanf(fpSolProps, "nPixelColumns= %d\n",&instrConst[2]) != 1) { + printf("Error reading nPixelColumns %d \n",instrConst[2]); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + if(zeroInstr) instrConst[2]=0; + printf("nPixelColumns= %7d\n", instrConst[2]); + if(wrFilebin) fprintf(fpSolPropsFileBin,"nPixelColumns= %d\n", instrConst[2]); + + if(fscanf(fpSolProps, "nTimeIntervals= %d\n",&instrConst[3]) != 1) { + printf("Error reading nTimeIntervals %d \n",instrConst[3]); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + if(zeroInstr) instrConst[3]=0; + printf("nTimeIntervals= %7d\n", instrConst[3]); + if(wrFilebin) fprintf(fpSolPropsFileBin,"nTimeIntervals= %d\n", instrConst[3]); + + if(fscanf(fpSolProps, "nInstrP= %hd\n",&nInstrP) != 1) { + printf("Error reading nInstrP %hd \n",nInstrP); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + if(zeroInstr) nInstrP=0; + printf("nInstrP= %7hd\n", nInstrP); + if(nInstrP!=0 && nInstrP !=6){ + printf("Execution aborted with invalid nInstrP\n"); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + if(wrFilebin) fprintf(fpSolPropsFileBin,"nInstrP= %hd\n", nInstrP); + if(fscanf(fpSolProps, "nInstrPSolved= %hd\n",&nInstrPSolved) != 1) + { + printf("Error reading nInstrPSolved %hd \n",nInstrPSolved); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + printf("nInstrPSolved= %7hd\n", nInstrPSolved); + + if(nInstrPSolved<0 || nInstrPSolved >6){ + printf("Execution aborted with invalid nInstrPSolved\n"); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + if(wrFilebin) fprintf(fpSolPropsFileBin,"nInstrPSolved= %hd\n", nInstrPSolved); + + if(fscanf(fpSolProps, "lsInstrFlag= %d\n",&lsInstrFlag) != 1) + { + printf("Error reading lsInstrFlag %d \n",lsInstrFlag); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + printf("lsInstrFlag= %7d\n", lsInstrFlag); + + if(lsInstrFlag<0 || lsInstrFlag >1){ + printf("Execution aborted with invalid lsInstrFlag\n"); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + if(wrFilebin) fprintf(fpSolPropsFileBin,"lsInstrFlag= %hd\n", lsInstrFlag); + if(fscanf(fpSolProps, "ssInstrFlag= %d\n",&ssInstrFlag) != 1) + { + printf("Error reading ssInstrFlag %d \n",ssInstrFlag); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + printf("ssInstrFlag= %7d\n", ssInstrFlag); + + if(ssInstrFlag<0 || ssInstrFlag >1){ + printf("Execution aborted with invalid ssInstrFlag\n"); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + if(wrFilebin) fprintf(fpSolPropsFileBin,"ssInstrFlag= %hd\n", ssInstrFlag); + if(fscanf(fpSolProps, "nuInstrFlag= %d\n",&nuInstrFlag) != 1) + { + printf("Error reading nuInstrFlag %d \n",nuInstrFlag); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + printf("nuInstrFlag= %7d\n", nuInstrFlag); + + if(nuInstrFlag<0 || nuInstrFlag >1){ + printf("Execution aborted with invalid lsInstrFlag\n"); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + if(wrFilebin) fprintf(fpSolPropsFileBin,"nuInstrFlag= %hd\n", nuInstrFlag); + if(fscanf(fpSolProps, "maInstrFlag= %d\n",&maInstrFlag) != 1) + { + printf("Error reading maInstrFlag %d \n",maInstrFlag); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + printf("maInstrFlag= %7d\n", maInstrFlag); + + if(maInstrFlag<0 || maInstrFlag >1){ + printf("Execution aborted with invalid maInstrFlag\n"); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + if(wrFilebin) fprintf(fpSolPropsFileBin,"maInstrFlag= %hd\n", maInstrFlag); - endTime = MPI_Wtime(); - if ((nDegFreedomAtt == 0 && nAttAxes > 0) || (nDegFreedomAtt > 0 && nAttAxes == 0)) - { - if (myid == 0) + if(nInstrPSolved != maInstrFlag+nuInstrFlag+ssInstrFlag+3*lsInstrFlag){ + printf("Execution aborted invalid nInstrPSolved=%d. It should be =%d\n",nInstrPSolved,maInstrFlag+nuInstrFlag+ssInstrFlag+3*lsInstrFlag); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + + } + + if(fscanf(fpSolProps, "nOfInstrConstr= %d\n",&nOfInstrConstr) != 1) { - printf("inconsistent values for nDegFreedomAtt=%ld and nAttaxes=%d\n", nDegFreedomAtt, nAttAxes); - MPI_Abort(MPI_COMM_WORLD, 1); + printf("Error reading nOfInstrConstr %d \n",nOfInstrConstr); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + printf("nOfInstrConstr= %7d\n", nOfInstrConstr); + if(wrFilebin) fprintf(fpSolPropsFileBin,"nOfInstrConstr= %d\n", nOfInstrConstr); + + if(fscanf(fpSolProps, "nElemIC= %d\n",&nElemIC) != 1) + { + printf("Error reading nElemIC %d \n",nElemIC); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + printf("nElemIC= %7d\n", nElemIC); + if(wrFilebin) fprintf(fpSolPropsFileBin,"nElemIC= %d\n", nElemIC); + + + if(fscanf(fpSolProps, "nGlobP= %hd\n",&nGlobP) != 1) { + printf("Error reading nGlobP %hd \n",nGlobP); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } + if(zeroGlob) nGlobP=0; + printf("nGlobP= %7hd\n", nGlobP); + if(wrFilebin) fprintf(fpSolPropsFileBin,"nGlobP= %hd\n", nGlobP); + + if(fscanf(fpSolProps, "nObs= %ld\n",&nobs) != 1) { + printf("Error reading nObs %ld \n",nobs); + MPI_Abort(MPI_COMM_WORLD,1); exit(EXIT_FAILURE); } + printf("nObs= %10ld\n", nobs); + if(wrFilebin) fprintf(fpSolPropsFileBin,"nObs= %ld\n", nobs); + + fclose(fpSolProps); + if(wrFilebin) fclose(fpSolPropsFileBin); + }//if (autoRun) else } - - if (myid == 0) - printf("Time to read initial parameters =%f sec.\n", endTime - startTime); - // Start section for parameter broadcast - MPI_Bcast(&atol, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); - MPI_Bcast(&btol, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); - MPI_Bcast(&conlim, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); - MPI_Bcast(&damp, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); - MPI_Bcast(&nAstroP, 1, MPI_SHORT, 0, MPI_COMM_WORLD); - MPI_Bcast(&nAstroPSolved, 1, MPI_SHORT, 0, MPI_COMM_WORLD); - MPI_Bcast(&nInstrP, 1, MPI_SHORT, 0, MPI_COMM_WORLD); - MPI_Bcast(&nInstrPSolved, 1, MPI_SHORT, 0, MPI_COMM_WORLD); - MPI_Bcast(&lsInstrFlag, 1, MPI_INT, 0, MPI_COMM_WORLD); - MPI_Bcast(&ssInstrFlag, 1, MPI_INT, 0, MPI_COMM_WORLD); - MPI_Bcast(&nuInstrFlag, 1, MPI_INT, 0, MPI_COMM_WORLD); - MPI_Bcast(&maInstrFlag, 1, MPI_INT, 0, MPI_COMM_WORLD); - MPI_Bcast(&nElemIC, 1, MPI_INT, 0, MPI_COMM_WORLD); - MPI_Bcast(&nOfInstrConstr, 1, MPI_INT, 0, MPI_COMM_WORLD); - MPI_Bcast(&nGlobP, 1, MPI_SHORT, 0, MPI_COMM_WORLD); - MPI_Bcast(&itnlim, 1, MPI_LONG, 0, MPI_COMM_WORLD); - MPI_Bcast(&nStar, 1, MPI_LONG, 0, MPI_COMM_WORLD); - MPI_Bcast(&nDegFreedomAtt, 1, MPI_LONG, 0, MPI_COMM_WORLD); - MPI_Bcast(&nAttAxes, 1, MPI_SHORT, 0, MPI_COMM_WORLD); - MPI_Bcast(&instrSetUp, 1, MPI_LONG, 0, MPI_COMM_WORLD); - MPI_Bcast(instrConst, DEFAULT_NINSTRINDEXES, MPI_INT, 0, MPI_COMM_WORLD); - MPI_Bcast(&nobs, 1, MPI_LONG, 0, MPI_COMM_WORLD); - MPI_Bcast(&nConstrLat, 1, MPI_LONG, 0, MPI_COMM_WORLD); - MPI_Bcast(&nConstrLong, 1, MPI_LONG, 0, MPI_COMM_WORLD); - MPI_Bcast(&nConstrMuLat, 1, MPI_LONG, 0, MPI_COMM_WORLD); - MPI_Bcast(&nConstrMuLong, 1, MPI_LONG, 0, MPI_COMM_WORLD); - if (myid != 0) - { - constrLatId = (long *)calloc(nConstrLat, sizeof(long)); - constrLatW = (double *)calloc(nConstrLat, sizeof(double)); - constrLongId = (long *)calloc(nConstrLong, sizeof(long)); - constrLongW = (double *)calloc(nConstrLong, sizeof(double)); - constrMuLatId = (long *)calloc(nConstrMuLat, sizeof(long)); - constrMuLatW = (double *)calloc(nConstrMuLat, sizeof(double)); - constrMuLongId = (long *)calloc(nConstrMuLong, sizeof(long)); - constrMuLongW = (double *)calloc(nConstrMuLong, sizeof(double)); + + endTime=MPI_Wtime(); + if((nDegFreedomAtt==0 && nAttAxes>0) || (nDegFreedomAtt>0 && nAttAxes==0) ){ + if(myid==0){ + printf("inconsistent values for nDegFreedomAtt=%ld and nAttaxes=%d\n",nDegFreedomAtt,nAttAxes); + MPI_Abort(MPI_COMM_WORLD, 1); + exit(EXIT_FAILURE); + } } - MPI_Bcast(constrLatId, nConstrLat, MPI_LONG, 0, MPI_COMM_WORLD); - MPI_Bcast(constrLatW, nConstrLat, MPI_DOUBLE, 0, MPI_COMM_WORLD); - MPI_Bcast(constrLongId, nConstrLong, MPI_LONG, 0, MPI_COMM_WORLD); - MPI_Bcast(constrLongW, nConstrLong, MPI_DOUBLE, 0, MPI_COMM_WORLD); - MPI_Bcast(constrMuLatId, nConstrMuLat, MPI_LONG, 0, MPI_COMM_WORLD); - MPI_Bcast(constrMuLatW, nConstrMuLat, MPI_DOUBLE, 0, MPI_COMM_WORLD); - MPI_Bcast(constrMuLongId, nConstrMuLong, MPI_LONG, 0, MPI_COMM_WORLD); - MPI_Bcast(constrMuLongW, nConstrMuLong, MPI_DOUBLE, 0, MPI_COMM_WORLD); - - if (nInstrPSolved == 0) - zeroInstr = 1; + + if(myid==0) printf("Time to read initial parameters =%f sec.\n",endTime-startTime); + // Start section for parameter broadcast + MPI_Bcast( &atol, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); + MPI_Bcast( &btol, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); + MPI_Bcast( &conlim, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); + MPI_Bcast( &damp, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); + MPI_Bcast( &nAstroP, 1, MPI_SHORT, 0, MPI_COMM_WORLD); + MPI_Bcast( &nAstroPSolved, 1, MPI_SHORT, 0, MPI_COMM_WORLD); + MPI_Bcast( &nInstrP, 1, MPI_SHORT, 0, MPI_COMM_WORLD); + MPI_Bcast( &nInstrPSolved, 1, MPI_SHORT, 0, MPI_COMM_WORLD); + MPI_Bcast( &lsInstrFlag, 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Bcast( &ssInstrFlag, 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Bcast( &nuInstrFlag, 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Bcast( &maInstrFlag, 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Bcast( &nElemIC, 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Bcast( &nOfInstrConstr, 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Bcast( &nGlobP, 1, MPI_SHORT, 0, MPI_COMM_WORLD); + MPI_Bcast( &itnlim, 1, MPI_LONG, 0, MPI_COMM_WORLD); + MPI_Bcast( &nStar, 1, MPI_LONG, 0, MPI_COMM_WORLD); + MPI_Bcast( &nDegFreedomAtt, 1, MPI_LONG, 0, MPI_COMM_WORLD); + MPI_Bcast( &nAttAxes, 1, MPI_SHORT, 0, MPI_COMM_WORLD); + MPI_Bcast( &instrSetUp, 1, MPI_LONG, 0, MPI_COMM_WORLD); + MPI_Bcast( instrConst, DEFAULT_NINSTRINDEXES , MPI_INT, 0, MPI_COMM_WORLD); // errore + MPI_Bcast( &nobs, 1, MPI_LONG, 0, MPI_COMM_WORLD); + MPI_Bcast( &nConstrLat, 1, MPI_LONG, 0, MPI_COMM_WORLD); + MPI_Bcast( &nConstrLong, 1, MPI_LONG, 0, MPI_COMM_WORLD); + MPI_Bcast( &nConstrMuLat, 1, MPI_LONG, 0, MPI_COMM_WORLD); + MPI_Bcast( &nConstrMuLong, 1, MPI_LONG, 0, MPI_COMM_WORLD); + if(myid !=0) + { + constrLatId=(long *) calloc(nConstrLat , sizeof(long)); + constrLatW=(double *) calloc(nConstrLat , sizeof(double)); + constrLongId=(long *) calloc(nConstrLong , sizeof(long)); + constrLongW=(double *) calloc(nConstrLong , sizeof(double)); + constrMuLatId=(long *) calloc(nConstrMuLat , sizeof(long)); + constrMuLatW=(double *) calloc(nConstrMuLat , sizeof(double)); + constrMuLongId=(long *) calloc(nConstrMuLong , sizeof(long)); + constrMuLongW=(double *) calloc(nConstrMuLong , sizeof(double)); + } + MPI_Bcast( constrLatId, nConstrLat, MPI_LONG, 0, MPI_COMM_WORLD); + MPI_Bcast( constrLatW, nConstrLat, MPI_DOUBLE, 0, MPI_COMM_WORLD); + MPI_Bcast( constrLongId, nConstrLong, MPI_LONG, 0, MPI_COMM_WORLD); + MPI_Bcast( constrLongW, nConstrLong, MPI_DOUBLE, 0, MPI_COMM_WORLD); + MPI_Bcast( constrMuLatId, nConstrMuLat, MPI_LONG, 0, MPI_COMM_WORLD); + MPI_Bcast( constrMuLatW, nConstrMuLat, MPI_DOUBLE, 0, MPI_COMM_WORLD); + MPI_Bcast( constrMuLongId, nConstrMuLong, MPI_LONG, 0, MPI_COMM_WORLD); + MPI_Bcast( constrMuLongW, nConstrMuLong, MPI_DOUBLE, 0, MPI_COMM_WORLD); + + if(nInstrPSolved==0) + zeroInstr=1; /////////// Multiplicity of matrixIndex - + int multMI; - - if (nAstroPSolved) - multMI = 2; - else - { - multMI = 1; - extConstraint = 0; - barConstraint = 0; + + if(nAstroPSolved) + multMI=2; + else{ + multMI=1; + extConstraint=0; + barConstraint=0; } nAstroParam = nStar * nAstroPSolved; nAttParam = nDegFreedomAtt * nAttAxes; - if (nDegFreedomAtt < 4) - nAttParAxis = nDegFreedomAtt; - if (nDegFreedomAtt) - nAttP = nAttAxes * nAttParAxis; - long nFoVs = 1 + instrConst[0]; - long nCCDs = instrConst[1]; - long nPixelColumns = instrConst[2]; - long nTimeIntervals = instrConst[3]; + if(nDegFreedomAtt<4) nAttParAxis=nDegFreedomAtt; + if(nDegFreedomAtt) nAttP = nAttAxes * nAttParAxis; + long nFoVs=1+instrConst[0]; + long nCCDs=instrConst[1]; + long nPixelColumns=instrConst[2]; + long nTimeIntervals=instrConst[3]; // tot. instr. param. = nCCDs (Cmag) + nFoVs*nCCDs (Cnu) + nCCDs*nPixelColumns (delta_eta) + 3*nFoVs*nCCDs*nTimeIntervals (Delta_eta) + nCCDs*nPixelColumns (delta_zeta) + 3*nFoVs*nCCDs*nTimeIntervals (Delta_zeta) // added flags switch on and off the appropriate kind of parameters - nInstrParam = maInstrFlag * nCCDs + nuInstrFlag * nFoVs * nCCDs + ssInstrFlag * 2 * nCCDs * nPixelColumns + lsInstrFlag * 2 * 3 * nFoVs * nCCDs * nTimeIntervals; - nInstrParamTot = nCCDs + nFoVs * nCCDs + 2 * nCCDs * nPixelColumns + 2 * 3 * nFoVs * nCCDs * nTimeIntervals; + nInstrParam = maInstrFlag*nCCDs+nuInstrFlag*nFoVs*nCCDs+ssInstrFlag*2*nCCDs*nPixelColumns+lsInstrFlag*2*3*nFoVs*nCCDs*nTimeIntervals; + nInstrParamTot = nCCDs+ nFoVs*nCCDs+ 2*nCCDs*nPixelColumns+2*3*nFoVs*nCCDs*nTimeIntervals; nGlobalParam = nGlobP; - - if (nElemIC < 0 || nOfInstrConstr < 0) - { - nOfInstrConstrLSAL = lsInstrFlag * nTimeIntervals; - nElemICLSAL = nFoVs * nCCDs; - nOfInstrConstrLSAC = lsInstrFlag * nFoVs * nTimeIntervals; + + if(nElemIC<0 || nOfInstrConstr <0){ + + + nOfInstrConstrLSAL = lsInstrFlag*nTimeIntervals; + nElemICLSAL = nFoVs*nCCDs; + nOfInstrConstrLSAC = lsInstrFlag*nFoVs*nTimeIntervals; nElemICLSAC = nCCDs; - nOfInstrConstrSS = lsInstrFlag * ssInstrFlag * 2 * nCCDs * 3; // the factor 2 comes from the AL and AC constraint equations + nOfInstrConstrSS = lsInstrFlag*ssInstrFlag*2*nCCDs*3; // the factor 2 comes from the AL and AC constraint equations nElemICSS = nPixelColumns; nOfInstrConstr = nOfInstrConstrLSAL + nOfInstrConstrLSAC + nOfInstrConstrSS; - nElemIC = nOfInstrConstrLSAL * nElemICLSAL + nOfInstrConstrLSAC * nElemICLSAC + nOfInstrConstrSS * nElemICSS; + nElemIC = nOfInstrConstrLSAL*nElemICLSAL + nOfInstrConstrLSAC*nElemICLSAC + nOfInstrConstrSS*nElemICSS; + } + // Map the solved astrometric parameters, putting their indeces into an array of size nAstroPSolved // astroCoeff[0] -> parallax // astroCoeff[1] -> alpha @@ -1388,1012 +1192,909 @@ int main(int argc, char **argv) // nAstroPSolved=3 => parallax, alpha, delta, and the array is mapAstroP=[0,1,2] // nAstroPSolved=4 => alpha, delta, mu alpha, mu delta and the array is mapAstroP=[1,2,3,4] // nAstroPSolved=5 => parallax, alpha, delta, mu alpha, mu delta and the array is mapAstroP=[0,1,2,3,4] - - int LatPos = -1, LongPos = -1, MuLatPos = -1, MuLongPos = -1; - - if (nAstroPSolved) - { - mapAstroP = (int *)calloc(nAstroPSolved, sizeof(int)); - switch (nAstroPSolved) - { - case 2: - mapAstroP[0] = 1; - mapAstroP[1] = 2; - LongPos = 0; - LatPos = 1; - MuLongPos = -1; - MuLatPos = -1; - nConstrMuLat = 0; - nConstrMuLong = 0; - if (extConstraint) - nEqExtConstr = 3; - if (barConstraint) - nEqBarConstr = 3; - break; - case 3: - mapAstroP[0] = 0; - mapAstroP[1] = 1; - mapAstroP[2] = 2; - LongPos = 1; - LatPos = 2; - MuLongPos = -1; - MuLatPos = -1; - nConstrMuLat = 0; - nConstrMuLong = 0; - if (extConstraint) - nEqExtConstr = 3; - if (barConstraint) - nEqBarConstr = 3; - break; - case 4: - mapAstroP[0] = 1; - mapAstroP[1] = 2; - mapAstroP[2] = 3; - mapAstroP[3] = 4; - LongPos = 0; - LatPos = 1; - MuLongPos = 2; - MuLatPos = 3; - break; - case 5: - mapAstroP[0] = 0; - mapAstroP[1] = 1; - mapAstroP[2] = 2; - mapAstroP[3] = 3; - mapAstroP[4] = 4; - LongPos = 1; - LatPos = 2; - MuLongPos = 3; - MuLatPos = 4; - break; - default: - if (myid == 0) - { - printf("nAstroPSolved=%d, invalid value. Aborting.\n", nAstroPSolved); - MPI_Abort(MPI_COMM_WORLD, 1); - exit(EXIT_FAILURE); - } + + int LatPos=-1, LongPos=-1,MuLatPos=-1, MuLongPos=-1; + + if(nAstroPSolved) + { + mapAstroP=(int *) calloc(nAstroPSolved, sizeof(int)); + switch(nAstroPSolved) { + case 2: + mapAstroP[0] = 1; + mapAstroP[1] = 2; + LongPos=0; + LatPos=1; + MuLongPos=-1; + MuLatPos=-1; + nConstrMuLat=0; + nConstrMuLong=0; + if(extConstraint) nEqExtConstr=3; + if(barConstraint) nEqBarConstr=3; + break; + case 3: + mapAstroP[0] = 0; + mapAstroP[1] = 1; + mapAstroP[2] = 2; + LongPos=1; + LatPos=2; + MuLongPos=-1; + MuLatPos=-1; + nConstrMuLat=0; + nConstrMuLong=0; + if(extConstraint) nEqExtConstr=3; + if(barConstraint) nEqBarConstr=3; + break; + case 4: + mapAstroP[0] = 1; + mapAstroP[1] = 2; + mapAstroP[2] = 3; + mapAstroP[3] = 4; + LongPos=0; + LatPos=1; + MuLongPos=2; + MuLatPos=3; + break; + case 5: + mapAstroP[0] = 0; + mapAstroP[1] = 1; + mapAstroP[2] = 2; + mapAstroP[3] = 3; + mapAstroP[4] = 4; + LongPos=1; + LatPos=2; + MuLongPos=3; + MuLatPos=4; + break; + default: + if(myid==0) { + printf("nAstroPSolved=%d, invalid value. Aborting.\n", nAstroPSolved); + MPI_Abort(MPI_COMM_WORLD,1); + exit(EXIT_FAILURE); + } } } // End map + /////////////////////// end broadcast section - + // Initialize the values needed to dimension the vectors nConstr = nConstrLong + nConstrLat + nConstrMuLong + nConstrMuLat; // number of constraints to be generated - - nObsxStar = nobs / nStar; - nobsOri = nobs; - if (noConstr) + + nObsxStar=nobs/nStar; + nobsOri=nobs; + if(noConstr) { - nConstr = 0; - nConstrLong = 0; - nConstrLat = 0; - nConstrMuLong = 0; - nConstrMuLat = 0; - } - else + nConstr=0; + nConstrLong=0; + nConstrLat=0; + nConstrMuLong=0; + nConstrMuLat=0; + } else { - for (int q = 0; q < nConstrLat; q++) - if (constrLatId[q] >= nStar) + for(int q=0;q=nStar) { - printf("PE=%d Error invalit Lat Constraint %ld\n", myid, constrLatId[q]); - MPI_Abort(MPI_COMM_WORLD, 1); + printf("PE=%d Error invalit Lat Constraint %ld\n",myid,constrLatId[q]); + MPI_Abort(MPI_COMM_WORLD,1); exit(EXIT_FAILURE); } - - for (int q = 0; q < nConstrLong; q++) - if (constrLongId[q] >= nStar) + + for(int q=0;q=nStar) { - printf("PE=%d Error invalit Long Constraint %ld\n", myid, constrLongId[q]); - MPI_Abort(MPI_COMM_WORLD, 1); + printf("PE=%d Error invalit Long Constraint %ld\n",myid,constrLongId[q]); + MPI_Abort(MPI_COMM_WORLD,1); exit(EXIT_FAILURE); } - for (int q = 0; q < nConstrMuLat; q++) - if (constrMuLatId[q] >= nStar) + for(int q=0;q=nStar) { - printf("PE=%d Error invalit MuLat Constraint %ld\n", myid, constrMuLatId[q]); - MPI_Abort(MPI_COMM_WORLD, 1); + printf("PE=%d Error invalit MuLat Constraint %ld\n",myid,constrMuLatId[q]); + MPI_Abort(MPI_COMM_WORLD,1); exit(EXIT_FAILURE); } - - for (int q = 0; q < nConstrMuLong; q++) - if (constrMuLongId[q] >= nStar) + + for(int q=0;q=nStar) { - printf("PE=%d Error invalit MuLat Constraint %ld\n", myid, constrMuLongId[q]); - MPI_Abort(MPI_COMM_WORLD, 1); + printf("PE=%d Error invalit MuLat Constraint %ld\n",myid,constrMuLongId[q]); + MPI_Abort(MPI_COMM_WORLD,1); exit(EXIT_FAILURE); } - + nConstr = nConstrLong + nConstrLat + nConstrMuLong + nConstrMuLat; // number of constraints to be generated } - - nobs += nConstr; - nunk = ((long)nAstroParam) + nAttParam + nInstrParam + nGlobalParam; // number of unknowns (i.e. columns of the system matrix) - nparam = nAstroPSolved + nAttP + nInstrPSolved + nGlobP; // number of non-zero coefficients for each observation (i.e. for each system row) - if (nparam == 0) - { - printf("Abort. Empty system nparam=0 . nAstroPSolved=%d nAttP=%d nInstrPSolved=%d nGlobP=%d\n", nAstroPSolved, nAttP, nInstrPSolved, nGlobP); - MPI_Abort(MPI_COMM_WORLD, 1); + + + nobs+=nConstr; + nunk = ((long) nAstroParam) + nAttParam + nInstrParam + nGlobalParam; // number of unknowns (i.e. columns of the system matrix) + nparam = nAstroPSolved + nAttP + nInstrPSolved + nGlobP; // number of non-zero coefficients for each observation (i.e. for each system row) + if(nparam==0){ + printf("Abort. Empty system nparam=0 . nAstroPSolved=%d nAttP=%d nInstrPSolved=%d nGlobP=%d\n",nAstroPSolved,nAttP,nInstrPSolved,nGlobP); + MPI_Abort(MPI_COMM_WORLD,1); } ncoeff = nparam * nobs; // total number of non-zero coefficients of the system - - if (nobs <= nunk) - { - printf("SEVERE ERROR: number of equations=%ld and number of unknown=%ld make solution unsafe\n", nobs, nunk); - MPI_Abort(MPI_COMM_WORLD, 1); + + if(nobs <=nunk){ + printf("SEVERE ERROR: number of equations=%ld and number of unknown=%ld make solution unsafe\n",nobs,nunk); + MPI_Abort(MPI_COMM_WORLD,1); exit(EXIT_FAILURE); - } + } + // Start map distributed array - mapNoss = (long int *)calloc(nproc, sizeof(long int)); - mapNcoeff = (long int *)calloc(nproc, sizeof(long int)); - mapNossAfter = 0; - mapNcoeffAfter = 0; - mapNossBefore = 0; - mapNcoeffBefore = 0; - for (i = 0; i < nproc; i++) + mapNoss=(long int *) calloc(nproc,sizeof(long int)); + mapNcoeff=(long int *) calloc(nproc,sizeof(long int)); + mapNossAfter=0; + mapNcoeffAfter=0; + mapNossBefore=0; + mapNcoeffBefore=0; + for(i=0;i= i + 1) - mapNoss[i]++; - mapNcoeff[i] = mapNoss[i] * nparam; - if (i < myid) + mapNoss[i]=(nobs)/nproc; + if(nobs % nproc >=i+1) mapNoss[i]++; + mapNcoeff[i]=mapNoss[i]*nparam; + if(i myid) + if(i>myid) { - mapNossAfter += mapNoss[i]; - mapNcoeffAfter += mapNcoeff[i]; + mapNossAfter+=mapNoss[i]; + mapNcoeffAfter+=mapNcoeff[i]; } } ////////////////// Simulating the ... of NObsxStar file - if (extConstraint) - { - int *sumNObsxStar; - sumNObsxStar = (int *)calloc(nStar, sizeof(int)); - int irest = nobs % nStar; - for (int i = 0; i < nStar; i++) - { - sumNObsxStar[i] = nobs / nStar; - if (i < irest) - sumNObsxStar[i]++; - } - if (wrFilebin && myid == 0) - { + if(extConstraint){ + int * sumNObsxStar; + sumNObsxStar=(int *) calloc(nStar, sizeof(int)); + int irest=nobs % nStar; + for(int i=0;i mapNossBefore && firstStarConstr == -1) - firstStarConstr = i; //first star assigned in extConstr - if (counterObsxStar >= mapNossBefore + mapNoss[myid] && lastStarConstr == -1) - { - lastStarConstr = i; //last star assigned in extConstr (it will be eqaul to lastrStar-1 in case of overlap) - if (counterObsxStar > (mapNossBefore + mapNoss[myid]) && myid != (nproc - 1)) - { - starOverlap = 1; + + } + long counterObsxStar=0; + for(int i=0;imapNossBefore && firstStarConstr==-1) firstStarConstr=i; //first star assigned in extConstr + if(counterObsxStar>=mapNossBefore+mapNoss[myid] && lastStarConstr==-1){ + lastStarConstr=i; //last star assigned in extConstr (it will be eqaul to lastrStar-1 in case of overlap) + if(counterObsxStar>(mapNossBefore+mapNoss[myid]) && myid!=(nproc-1)){ + starOverlap=1; lastStarConstr--; } break; } } - numOfExtStar = lastStarConstr - firstStarConstr + 1; //number of stars computed in ext Constr - - int counterAttCols = 0; - startingAttColExtConstr = 0; // numero di colonna di assetto escluso l'offset: la prima è 0 per il PE0 x asse - endingAttColExtConstr = 0; // numero di colonna di assetto finale l'offset: la prima è nDegFreedomAtt/nproc-1 (+1 in caso di modulo) per il PE0 x asse - int attRes = nDegFreedomAtt % nproc; - startingAttColExtConstr = (nDegFreedomAtt / nproc) * myid; - if (myid < attRes) - startingAttColExtConstr += myid; - else - startingAttColExtConstr += attRes; - endingAttColExtConstr = startingAttColExtConstr + (nDegFreedomAtt / nproc) - 1; - if (myid < attRes) - endingAttColExtConstr++; - - numOfExtAttCol = endingAttColExtConstr - startingAttColExtConstr + 1; //numeroi di colonne x asse + numOfExtStar=lastStarConstr-firstStarConstr+1; //number of stars computed in ext Constr + + int counterAttCols=0; + startingAttColExtConstr=0; // numero di colonna di assetto escluso l'offset: la prima è 0 per il PE0 x asse + endingAttColExtConstr=0; // numero di colonna di assetto finale l'offset: la prima è nDegFreedomAtt/nproc-1 (+1 in caso di modulo) per il PE0 x asse + int attRes=nDegFreedomAtt%nproc; + startingAttColExtConstr=(nDegFreedomAtt/nproc)*myid; + if(myid mapNossBefore && firstStarConstr == -1) - firstStarConstr = i; //first star assigned in barConstr - if (counterObsxStar >= mapNossBefore + mapNoss[myid] && lastStarConstr == -1) - { - lastStarConstr = i; //last star assigned in barConstr (it will be eqaul to lastrStar-1 in case of overlap) - if (counterObsxStar > (mapNossBefore + mapNoss[myid]) && myid != (nproc - 1)) - { - starOverlap = 1; + + } + int counterObsxStar=0; + for(int i=0;imapNossBefore && firstStarConstr==-1) firstStarConstr=i; //first star assigned in barConstr + if(counterObsxStar>=mapNossBefore+mapNoss[myid] && lastStarConstr==-1){ + lastStarConstr=i; //last star assigned in barConstr (it will be eqaul to lastrStar-1 in case of overlap) + if(counterObsxStar>(mapNossBefore+mapNoss[myid]) && myid!=(nproc-1)){ + starOverlap=1; lastStarConstr--; } break; } } - numOfBarStar = lastStarConstr - firstStarConstr + 1; //number of stars computed in bar Constr + numOfBarStar=lastStarConstr-firstStarConstr+1; //number of stars computed in bar Constr + } ////////////////////// comlsqr - - comlsqr.nStar = nStar; - comlsqr.nAstroP = nAstroP; - comlsqr.nAstroPSolved = nAstroPSolved; - comlsqr.nAttP = nAttP; - comlsqr.nInstrP = nInstrP; - comlsqr.nInstrPSolved = nInstrPSolved; - comlsqr.nGlobP = nGlobP; - comlsqr.mapNossBefore = mapNossBefore; - comlsqr.mapNossAfter = mapNossAfter; - comlsqr.myid = myid; - comlsqr.nproc = nproc; - comlsqr.mapNoss = mapNoss; - comlsqr.mapNcoeff = mapNcoeff; - comlsqr.multMI = multMI; - comlsqr.debugMode = debugMode; - comlsqr.noCPR = noCPR; - comlsqr.nAttParam = nAttParam; - comlsqr.extConstraint = extConstraint; - comlsqr.nEqExtConstr = nEqExtConstr; - comlsqr.numOfExtStar = numOfExtStar; - comlsqr.barConstraint = barConstraint; - comlsqr.nEqBarConstr = nEqBarConstr; - comlsqr.numOfBarStar = numOfBarStar; - comlsqr.firstStarConstr = firstStarConstr; - comlsqr.lastStarConstr = lastStarConstr; - comlsqr.numOfExtAttCol = numOfExtAttCol; - comlsqr.startingAttColExtConstr = startingAttColExtConstr; - comlsqr.setBound[0] = 0; - comlsqr.setBound[1] = nAstroPSolved; - comlsqr.setBound[2] = nAstroPSolved + nAttP; - comlsqr.setBound[3] = nAstroPSolved + nAttP + nInstrPSolved; - comlsqr.nDegFreedomAtt = nDegFreedomAtt; - comlsqr.nAttParAxis = nAttParAxis; - comlsqr.nAttAxes = nAttAxes; - comlsqr.nobs = nobs; - comlsqr.lsInstrFlag = lsInstrFlag; - comlsqr.ssInstrFlag = ssInstrFlag; - comlsqr.nuInstrFlag = nuInstrFlag; - comlsqr.maInstrFlag = maInstrFlag; - comlsqr.myid = myid; - comlsqr.cCDLSAACZP = cCDLSAACZP; - comlsqr.nOfInstrConstr = nOfInstrConstr; - comlsqr.nElemIC = nElemIC; - comlsqr.nElemICLSAL = nElemICLSAL; - comlsqr.nElemICLSAC = nElemICLSAC; - comlsqr.nElemICSS = nElemICSS; - comlsqr.instrConst[0] = instrConst[0]; - comlsqr.instrConst[1] = instrConst[1]; - comlsqr.instrConst[2] = instrConst[2]; - comlsqr.instrConst[3] = instrConst[3]; - comlsqr.nInstrParam = nInstrParam; - comlsqr.nGlobalParam = nGlobalParam; - - comlsqr.nthreads= nthreads; - comlsqr.ntasks= ntasks; + + + comlsqr.nStar=nStar; + comlsqr.nAstroP=nAstroP; + comlsqr.nAstroPSolved=nAstroPSolved; + comlsqr.nAttP=nAttP; + comlsqr.nInstrP=nInstrP; + comlsqr.nInstrPSolved=nInstrPSolved; + comlsqr.nGlobP=nGlobP; + comlsqr.mapNossBefore=mapNossBefore; + comlsqr.mapNossAfter=mapNossAfter; + comlsqr.myid=myid; + comlsqr.nproc=nproc; + comlsqr.mapNoss=mapNoss; + comlsqr.mapNcoeff=mapNcoeff; + comlsqr.multMI=multMI; + comlsqr.debugMode=debugMode; + comlsqr.noCPR=noCPR; + comlsqr.nAttParam=nAttParam; + comlsqr.extConstraint=extConstraint; + comlsqr.nEqExtConstr=nEqExtConstr; + comlsqr.numOfExtStar=numOfExtStar; + comlsqr.barConstraint=barConstraint; + comlsqr.nEqBarConstr=nEqBarConstr; + comlsqr.numOfBarStar=numOfBarStar; + comlsqr.firstStarConstr=firstStarConstr; + comlsqr.lastStarConstr=lastStarConstr; + comlsqr.numOfExtAttCol=numOfExtAttCol; + comlsqr.startingAttColExtConstr=startingAttColExtConstr; + comlsqr.setBound[0]=0; + comlsqr.setBound[1]=nAstroPSolved; + comlsqr.setBound[2]=nAstroPSolved+nAttP; + comlsqr.setBound[3]=nAstroPSolved+nAttP+nInstrPSolved; + comlsqr.nDegFreedomAtt=nDegFreedomAtt; + comlsqr.nAttParAxis=nAttParAxis; + comlsqr.nAttAxes=nAttAxes; + comlsqr.nobs=nobs; + comlsqr.lsInstrFlag=lsInstrFlag; + comlsqr.ssInstrFlag=ssInstrFlag; + comlsqr.nuInstrFlag=nuInstrFlag; + comlsqr.maInstrFlag=maInstrFlag; + comlsqr.myid=myid; + comlsqr.cCDLSAACZP=cCDLSAACZP; + comlsqr.nOfInstrConstr=nOfInstrConstr; + comlsqr.nElemIC=nElemIC; + comlsqr.nElemICLSAL=nElemICLSAL; + comlsqr.nElemICLSAC=nElemICLSAC; + comlsqr.nElemICSS=nElemICSS; + comlsqr.instrConst[0]=instrConst[0]; + comlsqr.instrConst[1]=instrConst[1]; + comlsqr.instrConst[2]=instrConst[2]; + comlsqr.instrConst[3]=instrConst[3]; + comlsqr.nInstrParam=nInstrParam; + comlsqr.nGlobalParam=nGlobalParam; ///////////////////// end buidl map distributed arrays - + // Allocate the memory for the vectors and compute the total memory allocated totmem = 0; nElements = mapNcoeff[myid]; - if (extConstraint) - { - addElementextStar = (lastStarConstr - firstStarConstr + 1) * nAstroPSolved; - addElementAtt = numOfExtAttCol * nAttAxes; + if (extConstraint){ + addElementextStar= (lastStarConstr-firstStarConstr+1)*nAstroPSolved; + addElementAtt=numOfExtAttCol*nAttAxes; } - if (barConstraint) - { - addElementbarStar = (lastStarConstr - firstStarConstr + 1) * nAstroPSolved; + if (barConstraint){ + addElementbarStar= (lastStarConstr-firstStarConstr+1)*nAstroPSolved; } - nOfElextObs = addElementextStar + addElementAtt; - nOfElBarObs = addElementbarStar; - comlsqr.nOfElextObs = nOfElextObs; - comlsqr.nOfElBarObs = nOfElBarObs; - - nElements += nOfElextObs * nEqExtConstr + nOfElBarObs * nEqBarConstr + nElemIC; + nOfElextObs=addElementextStar+addElementAtt; + nOfElBarObs=addElementbarStar; + comlsqr.nOfElextObs=nOfElextObs; + comlsqr.nOfElBarObs=nOfElBarObs; - systemMatrix = (double *)calloc(nElements, sizeof(double)); + nElements+=nOfElextObs*nEqExtConstr+nOfElBarObs*nEqBarConstr+nElemIC; + + systemMatrix = (double *) calloc(nElements,sizeof(double)); if (!systemMatrix) - exit(err_malloc("systemMatrix", myid)); - totmem += nElements * sizeof(double); - - nElements = mapNoss[myid] * multMI; - matrixIndex = (long int *)calloc(nElements, sizeof(long int)); + exit(err_malloc("systemMatrix",myid)); + totmem += nElements*sizeof(double); + + nElements = mapNoss[myid]*multMI; + matrixIndex = (long int *) calloc(nElements, sizeof(long int)); if (!matrixIndex) - exit(err_malloc("matrixIndex", myid)); - totmem += nElements * sizeof(long int); - - nElements = mapNoss[myid] * nInstrPSolved + nElemIC; - instrCol = (int *)calloc(nElements, sizeof(int)); + exit(err_malloc("matrixIndex",myid)); + totmem += nElements* sizeof(long int); + + nElements = mapNoss[myid]*nInstrPSolved+nElemIC; + instrCol = (int *) calloc(nElements, sizeof(int)); if (!instrCol) - exit(err_malloc("instrCol", myid)); - totmem += nElements * sizeof(int); + exit(err_malloc("instrCol",myid)); + totmem += nElements* sizeof(int); nElements = nOfInstrConstr; - instrConstrIlung = (int *)calloc(nElements, sizeof(int)); // it is the vectorr that for each observation (in this PE) save the INDEX for the values of instr + instrConstrIlung = (int *) calloc(nElements, sizeof(int)); // it is the vectorr that for each observation (in this PE) save the INDEX for the values of instr if (!instrConstrIlung) - exit(err_malloc("instrConstrIlung", myid)); - totmem += nElements * sizeof(int); - + exit(err_malloc("instrConstrIlung",myid)); + totmem += nElements* sizeof(int); + + nElements = mapNoss[myid]; - if (extConstraint) - nElements += nEqExtConstr; - if (barConstraint) - nElements += nEqBarConstr; - if (nOfInstrConstr > 0) - nElements += nOfInstrConstr; - knownTerms = (double *)calloc(nElements, sizeof(double)); + if(extConstraint) nElements+=nEqExtConstr; + if(barConstraint) nElements+=nEqBarConstr; + if(nOfInstrConstr>0) nElements+=nOfInstrConstr; + knownTerms = (double *) calloc(nElements, sizeof(double)); if (!knownTerms) - exit(err_malloc("knownTerms", myid)); - totmem += nElements * sizeof(double); - + exit(err_malloc("knownTerms",myid)); + totmem += nElements* sizeof(double); + ielem = 0; offsetAttParam = nAstroParam; offsetInstrParam = offsetAttParam + nAttParam; offsetGlobParam = offsetInstrParam + nInstrParam; - comlsqr.offsetAttParam = offsetAttParam; - - long rowsxFile = nobsOri / (nproc * nfileProc); - - if (withFile) - { - char filenameSim_SM[128] = "SIM_PE_SM_"; - char filenameSim_MI[128] = "SIM_PE_MI_"; - char filenameSim_II[128] = "SIM_PE_II_"; - char filenameSim_KT[128] = "SIM_PE_KT_"; - char varpe[32] = ""; - char varrows[32] = ""; - sprintf(varpe, "%d", myid); - sprintf(varrows, "%ld", rowsxFile); - strcat(filenameSim_SM, varrows); - strcat(filenameSim_SM, "_"); - strcat(filenameSim_SM, varpe); - strcat(filenameSim_SM, ".bin"); - strcat(filenameSim_MI, varrows); - strcat(filenameSim_MI, "_"); - strcat(filenameSim_MI, varpe); - strcat(filenameSim_MI, ".bin"); - strcat(filenameSim_II, varrows); - strcat(filenameSim_II, "_"); - strcat(filenameSim_II, varpe); - strcat(filenameSim_II, ".bin"); - strcat(filenameSim_KT, varrows); - strcat(filenameSim_KT, "_"); - strcat(filenameSim_KT, varpe); - strcat(filenameSim_KT, ".bin"); - + comlsqr.offsetAttParam=offsetAttParam; + + + long rowsxFile=nobsOri/(nproc*nfileProc); + + if(withFile) + { + char filenameSim_SM[128]="SIM_PE_SM_"; + char filenameSim_MI[128]="SIM_PE_MI_"; + char filenameSim_II[128]="SIM_PE_II_"; + char filenameSim_KT[128]="SIM_PE_KT_"; + char varpe[32]=""; + char varrows[32]=""; + sprintf(varpe,"%d",myid); + sprintf(varrows,"%ld",rowsxFile); + strcat(filenameSim_SM,varrows); + strcat(filenameSim_SM,"_"); + strcat(filenameSim_SM,varpe); + strcat(filenameSim_SM,".bin"); + strcat(filenameSim_MI,varrows); + strcat(filenameSim_MI,"_"); + strcat(filenameSim_MI,varpe); + strcat(filenameSim_MI,".bin"); + strcat(filenameSim_II,varrows); + strcat(filenameSim_II,"_"); + strcat(filenameSim_II,varpe); + strcat(filenameSim_II,".bin"); + strcat(filenameSim_KT,varrows); + strcat(filenameSim_KT,"_"); + strcat(filenameSim_KT,varpe); + strcat(filenameSim_KT,".bin"); + double *smsim; - smsim = (double *)calloc(rowsxFile * nparam, sizeof(double)); - fpSM = fopen(filenameSim_SM, "wb"); - fwrite(smsim, sizeof(double), rowsxFile * nparam, fpSM); + smsim=(double *)calloc(rowsxFile*nparam,sizeof(double)); + fpSM=fopen(filenameSim_SM,"wb"); + fwrite(smsim,sizeof(double),rowsxFile*nparam,fpSM); fclose(fpSM); - fpKT = fopen(filenameSim_KT, "wb"); - fwrite(smsim, sizeof(double), rowsxFile, fpKT); + fpKT=fopen(filenameSim_KT,"wb"); + fwrite(smsim,sizeof(double),rowsxFile,fpKT); fclose(fpKT); free(smsim); int *intsim; - intsim = (int *)calloc(rowsxFile * nInstrPSolved, sizeof(int)); - fpII = fopen(filenameSim_II, "wb"); - fwrite(intsim, sizeof(int), rowsxFile * nInstrPSolved, fpII); + intsim=(int *)calloc(rowsxFile*nInstrPSolved,sizeof(int)); + fpII=fopen(filenameSim_II,"wb"); + fwrite(intsim,sizeof(int),rowsxFile*nInstrPSolved,fpII); fclose(fpII); free(intsim); long *misim; - misim = (long *)calloc(rowsxFile * multMI, sizeof(long)); - fpMI = fopen(filenameSim_MI, "wb"); - fwrite(misim, sizeof(long), rowsxFile * multMI, fpMI); + misim=(long *)calloc(rowsxFile*multMI,sizeof(long)); + fpMI=fopen(filenameSim_MI,"wb"); + fwrite(misim,sizeof(long),rowsxFile*multMI,fpMI); fclose(fpMI); free(misim); long nrowToRead; - if (myid == 0) - printf( - "Found %d SM data files in the directory. Reading the coefficients...\n", - (nfileProc)*nproc); - timeToReadFiles = MPI_Wtime(); - - for (ii = 0; ii < nfileProc + 2; ii++) - { - - if (ii == 0 && myid == 0) - printf("PE=%d Opening %d and reading %s and associated files\n", myid, nfileProc, filenameSim_SM); - - fpSM = fopen(filenameSim_SM, "rb"); + if(myid==0) printf( + "Found %d SM data files in the directory. Reading the coefficients...\n", + (nfileProc)*nproc); + timeToReadFiles=MPI_Wtime(); + + for(ii=0;ii 0) + obsTotal+=nObsxStar; + if(startingStar0) { - for (int q = 0; q < nConstrLat; q++) - if (constrLatId[q] == startingStar) - obsTotal++; - for (int q = 0; q < nConstrLong; q++) - if (constrLongId[q] == startingStar) - obsTotal++; - for (int q = 0; q < nConstrMuLat; q++) - if (constrMuLatId[q] == startingStar) - obsTotal++; - for (int q = 0; q < nConstrMuLong; q++) - if (constrMuLongId[q] == startingStar) - obsTotal++; + for(int q=0;q 0) - { - for (int q = 0; q < nConstrLat; q++) - if (constrLatId[q] == currentStar) - obsStar++; - for (int q = 0; q < nConstrLong; q++) - if (constrLongId[q] == currentStar) - obsStar++; - for (int q = 0; q < nConstrMuLat; q++) - if (constrMuLatId[q] == currentStar) - obsStar++; - for (int q = 0; q < nConstrLong; q++) - if (constrMuLongId[q] == currentStar) - obsStar++; + if(debugMode) + printf("PE=%d instrStartFreedom=%ld instrEndFreedom=%ld nInstrParam=%d\n",myid,instrStartFreedom,instrEndFreedom,nInstrParam); + if(obsStar==0) + { + obsStar=nObsxStar; + if(currentStar0) + { + for(int q=0;q 0) + obsStarnow=obsStar; + if(nConstr>0) { - for (int q = 0; q < nConstrLat; q++) - if (constrLatId[q] == currentStar) - isConstraint++; - for (int q = 0; q < nConstrLong; q++) - if (constrLongId[q] == currentStar) - isConstraint++; - for (int q = 0; q < nConstrMuLat; q++) - if (constrMuLatId[q] == currentStar) - isConstraint++; - for (int q = 0; q < nConstrMuLong; q++) - if (constrMuLongId[q] == currentStar) - isConstraint++; + for(int q=0;q= nDegFreedomAtt - nAttParAxis) - lastFreedom = nDegFreedomAtt - nAttParAxis; - matrixIndex[ii * multMI + (multMI - 1)] = offsetAttParam + lastFreedom; - if (lastFreedom >= endFreedom || lastFreedom >= nDegFreedomAtt - nAttParAxis) - freedomReached = 1; - lastFreedom += nAttParAxis; + else{ + if(lastFreedom>=nDegFreedomAtt-nAttParAxis) lastFreedom=nDegFreedomAtt-nAttParAxis; + matrixIndex[ii*multMI+(multMI-1)]=offsetAttParam+lastFreedom; + if(lastFreedom>=endFreedom || lastFreedom>=nDegFreedomAtt-nAttParAxis) freedomReached=1; + lastFreedom+=nAttParAxis; } - } - else - { - lastFreedom = (((double)rand()) / (((double)RAND_MAX))) * (nDegFreedomAtt - nAttParAxis + 1); - if (lastFreedom > nDegFreedomAtt - nAttParAxis) - lastFreedom = nDegFreedomAtt - nAttParAxis; - if ((obsStar - counterStarObs) <= isConstraint) //constraint + } else { + lastFreedom=( ( (double)rand() ) / ( ((double)RAND_MAX) ) ) * (nDegFreedomAtt-nAttParAxis+1); + if(lastFreedom>nDegFreedomAtt-nAttParAxis) lastFreedom=nDegFreedomAtt-nAttParAxis; + if((obsStar-counterStarObs)<=isConstraint) //constraint { - lastFreedom = 0; - constraintFound[counterConstr][0] = currentStar / 1000; - constraintFound[counterConstr][1] = rowInFile; + lastFreedom=0; + constraintFound[counterConstr][0]=currentStar/1000; + constraintFound[counterConstr][1]=rowInFile; counterConstr++; } - matrixIndex[ii * multMI + (multMI - 1)] = offsetAttParam + lastFreedom; + matrixIndex[ii*multMI+(multMI-1)]=offsetAttParam+lastFreedom; } ///////////// generate InstrIndex - - if (!instrFreedomReached && nInstrPSolved) - { - if ((obsStar - counterStarObs) <= isConstraint) - { //constraint - for (int kk = 0; kk < nInstrPSolved; kk++) - instrCol[ii * nInstrPSolved + kk] = 0; - } - else - { - if (instrLastFreedom > instrEndFreedom) - instrLastFreedom = instrEndFreedom; - instrCol[ii * nInstrPSolved] = instrLastFreedom; - for (int kk = 1; kk < nInstrPSolved; kk++) - instrCol[ii * nInstrPSolved + kk] = (((double)rand()) / (((double)RAND_MAX))) * (nInstrParam - 1); - if (instrLastFreedom == instrEndFreedom) - instrFreedomReached = 1; + + if(!instrFreedomReached && nInstrPSolved) + { + if((obsStar-counterStarObs)<=isConstraint) + { //constraint + for(int kk=0;kkinstrEndFreedom) instrLastFreedom=instrEndFreedom; + instrCol[ii*nInstrPSolved]=instrLastFreedom; + for(int kk=1;kk isConstraint) - { - for (int q = 0; q < nAstroPSolved; q++) - systemMatrix[ii * nparam + q] = (((double)rand()) / RAND_MAX) * 2 - 1.0; - for (int q = 0; q < nAttP + nInstrPSolved + nGlobP; q++) - systemMatrix[ii * nparam + nAstroPSolved + q] = (((double)rand()) / RAND_MAX) * 2 - 1.0; - } - else // I add a Constraint - { - for (int q = 0; q < nAstroPSolved + nAttP + nInstrPSolved + nGlobP; q++) - systemMatrix[ii * nparam + q] = 0.; - if (nAstroPSolved > 0) - { - if (ii != 0) - offsetConstraint = 0; - int foundedConstraint = (obsStar - counterStarObs) + offsetConstraint; - int itis = 0; - for (int q = 0; q < nConstrLong; q++) - if (constrLongId[q] == currentStar) - { + if((obsStar-counterStarObs)>isConstraint ) + { + for(int q=0;q0) + { + if(ii!=0) offsetConstraint=0; + int foundedConstraint=(obsStar-counterStarObs)+offsetConstraint; + int itis=0; + for(int q=0;q 0) - { - for (int q = 0; q < nConstrLat; q++) - if (constrLatId[q] == currentStar) + changedStar=1; + isConstraint=0; + obsStar=nObsxStar; + if(currentStar0) + { + for(int q=0;q= 2) - randVal = 0.; - if (nAstroPSolved == 5 && i % nAstroPSolved == 0) - randVal = 0.; - if (nAstroPSolved == 5 && i % nAstroPSolved > 2 && j < 3) - randVal = 0.; + exit(err_malloc("attNS",myid)); + if(myid==0){ + for(int i=0;i=2) randVal=0.; + if(nAstroPSolved==5 && i%nAstroPSolved==0) randVal=0.; + if(nAstroPSolved==5 && i%nAstroPSolved>2 && j<3) randVal=0.; } - if (i >= addElementextStar) - { - if (j < 3) - randVal = 1.0; - if (j == 0 || j == 3) - { - if (i >= addElementextStar + addElementAtt / nAttAxes) - randVal = 0.0; + if(i>=addElementextStar){ + if(j<3) randVal=1.0; + if(j==0 || j==3){ + if(i>=addElementextStar+addElementAtt/nAttAxes) randVal=0.0; } - if (j == 1 || j == 4) - { - if (i < addElementextStar + addElementAtt / nAttAxes) - randVal = 0.0; - if (i >= addElementextStar + 2 * addElementAtt / nAttAxes) - randVal = 0.0; + if(j==1 || j==4){ + if(i=addElementextStar+2*addElementAtt/nAttAxes) randVal=0.0; } - if (j == 2 || j == 5) - { - if (i < addElementextStar + 2 * addElementAtt / nAttAxes) - randVal = 0.0; + if(j==2 || j==5){ + if(i= 2) - randVal = 0.; - if (nAstroPSolved == 5 && i % nAstroPSolved == 0) - randVal = 0.; - if (nAstroPSolved == 5 && i % nAstroPSolved > 2 && j < 3) - randVal = 0.; - systemMatrix[mapNcoeff[myid] + nEqExtConstr * nOfElextObs + i + j * nOfElBarObs] = randVal * barConstrW; - accumulator[j] += randVal * barConstrW; - } - if (!idtest) - knownTerms[mapNoss[myid] + nEqExtConstr + j] = 0.; - } // j=0 - if (idtest) - MPI_Allreduce(accumulator, &knownTerms[mapNoss[myid] + nEqExtConstr], nEqBarConstr, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + accumulator=(double *) calloc(nEqBarConstr,sizeof(double)); + + for(int j=0;j=2) randVal=0.; + if(nAstroPSolved==5 && i%nAstroPSolved==0) randVal=0.; + if(nAstroPSolved==5 && i%nAstroPSolved>2 && j<3) randVal=0.; + systemMatrix[mapNcoeff[myid]+nEqExtConstr*nOfElextObs+i+j*nOfElBarObs]=randVal*barConstrW; + accumulator[j]+=randVal*barConstrW; + + } + if(!idtest) + knownTerms[mapNoss[myid]+nEqExtConstr+j]=0.; + }// j=0 + if(idtest) + MPI_Allreduce(accumulator, &knownTerms[mapNoss[myid]+nEqExtConstr], nEqBarConstr, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); free(accumulator); } //if(barConstr - + ///////////////////////// generate instrConstr on systemMatrix // There are 1 AL + 2 AC constraint equations for each time interval for the large scale parameters (total=3*nTimeIntervals) // There are 1 AL + 1 AC constraint equations for each CCD and Legendre polinomial degree (total=2*nCCDs*3) // The equations are described by three arrays: instrCoeffConstr, instrColsConstr, instrConstrIlung, which contain the // coefficients, the column indexes and the length of the non-zero coefficients of each equation respectively. - comlsqr.offsetCMag = maInstrFlag * nCCDs; // offest=0 if maInstrFlag=0 - comlsqr.offsetCnu = comlsqr.offsetCMag + nuInstrFlag * nFoVs * nCCDs; // offest=offsetCMag if nuInstrFlag=0 - comlsqr.offsetCdelta_eta = comlsqr.offsetCnu + ssInstrFlag * nCCDs * nPixelColumns; // offest=offsetCnu if ssInstrFlag=0 - comlsqr.offsetCDelta_eta_1 = comlsqr.offsetCdelta_eta + lsInstrFlag * nFoVs * nCCDs * nTimeIntervals; - comlsqr.offsetCDelta_eta_2 = comlsqr.offsetCdelta_eta + lsInstrFlag * 2 * nFoVs * nCCDs * nTimeIntervals; - comlsqr.offsetCDelta_eta_3 = comlsqr.offsetCdelta_eta + lsInstrFlag * 3 * nFoVs * nCCDs * nTimeIntervals; - comlsqr.offsetCdelta_zeta = comlsqr.offsetCDelta_eta_3 + ssInstrFlag * nCCDs * nPixelColumns; - comlsqr.offsetCDelta_zeta_1 = comlsqr.offsetCdelta_zeta + lsInstrFlag * nFoVs * nCCDs * nTimeIntervals; - comlsqr.offsetCDelta_zeta_2 = comlsqr.offsetCdelta_zeta + lsInstrFlag * 2 * nFoVs * nCCDs * nTimeIntervals; - comlsqr.nInstrPSolved = nInstrPSolved; - - if (myid == 0 && lsInstrFlag && nElemIC != 0) - { - double *instrCoeffConstr; - instrCoeffConstr = (double *)calloc(nElemIC, sizeof(double)); - int *instrColsConstr; - instrColsConstr = (int *)calloc(nElemIC, sizeof(int)); + comlsqr.offsetCMag=maInstrFlag*nCCDs; // offest=0 if maInstrFlag=0 + comlsqr.offsetCnu=comlsqr.offsetCMag+nuInstrFlag*nFoVs*nCCDs; // offest=offsetCMag if nuInstrFlag=0 + comlsqr.offsetCdelta_eta=comlsqr.offsetCnu+ssInstrFlag*nCCDs*nPixelColumns; // offest=offsetCnu if ssInstrFlag=0 + comlsqr.offsetCDelta_eta_1=comlsqr.offsetCdelta_eta+lsInstrFlag*nFoVs*nCCDs*nTimeIntervals; + comlsqr.offsetCDelta_eta_2=comlsqr.offsetCdelta_eta+lsInstrFlag*2*nFoVs*nCCDs*nTimeIntervals; + comlsqr.offsetCDelta_eta_3=comlsqr.offsetCdelta_eta+lsInstrFlag*3*nFoVs*nCCDs*nTimeIntervals; + comlsqr.offsetCdelta_zeta=comlsqr.offsetCDelta_eta_3+ssInstrFlag*nCCDs*nPixelColumns; + comlsqr.offsetCDelta_zeta_1=comlsqr.offsetCdelta_zeta+lsInstrFlag*nFoVs*nCCDs*nTimeIntervals; + comlsqr.offsetCDelta_zeta_2=comlsqr.offsetCdelta_zeta+lsInstrFlag*2*nFoVs*nCCDs*nTimeIntervals; + comlsqr.nInstrPSolved=nInstrPSolved; - if (!computeInstrConstr(comlsqr, instrCoeffConstr, instrColsConstr, instrConstrIlung)) + + if(myid==0 && lsInstrFlag && nElemIC!=0 ){ + double * instrCoeffConstr; + instrCoeffConstr=(double *) calloc(nElemIC, sizeof(double)); + int * instrColsConstr; + instrColsConstr=(int *) calloc(nElemIC, sizeof(int)); + + if(!computeInstrConstr(comlsqr, instrCoeffConstr, instrColsConstr, instrConstrIlung)) { printf("SEVERE ERROR PE=0 computeInstrConstr failed\n"); - MPI_Abort(MPI_COMM_WORLD, 1); + MPI_Abort(MPI_COMM_WORLD,1); exit(EXIT_FAILURE); } ////////////////////////// - for (int k = 0; k < nElemIC; k++) - instrCoeffConstr[k] = instrCoeffConstr[k] * wgInstrCoeff; + for(int k=0;k 0) + if(seqStar<=1 && nAstroPSolved>0) { - printf("ERROR PE=%d Only %d star Run not allowed with this PE numbers .n", myid, seqStar); + printf("ERROR PE=%d Only %d star Run not allowed with this PE numbers .n",myid,seqStar); exit(EXIT_FAILURE); } - comlsqr.VrIdAstroPDim = seqStar; - long tempDimMax = comlsqr.VrIdAstroPDim; + comlsqr.VrIdAstroPDim=seqStar; + long tempDimMax=comlsqr.VrIdAstroPDim; long tempVrIdAstroPDimMax; - MPI_Allreduce(&tempDimMax, &tempVrIdAstroPDimMax, 1, MPI_LONG, MPI_MAX, MPI_COMM_WORLD); - - comlsqr.VrIdAstroPDimMax = tempVrIdAstroPDimMax; - + MPI_Allreduce(&tempDimMax,&tempVrIdAstroPDimMax,1,MPI_LONG,MPI_MAX,MPI_COMM_WORLD); + + comlsqr.VrIdAstroPDimMax=tempVrIdAstroPDimMax; + int **tempStarSend, **tempStarRecv; - tempStarSend = (int **)calloc(nproc, sizeof(int *)); - for (int i = 0; i < nproc; i++) - tempStarSend[i] = (int *)calloc(2, sizeof(int)); - tempStarRecv = (int **)calloc(nproc, sizeof(int *)); - for (int i = 0; i < nproc; i++) - tempStarRecv[i] = (int *)calloc(2, sizeof(int)); - + tempStarSend=(int **) calloc(nproc,sizeof(int *)); + for(int i=0;i 0) + + if(comlsqr.mapStar[myid][0]==comlsqr.mapStar[myid][1] && nAstroPSolved>0) { - printf("PE=%d ERROR. Only one star in this PE: starting star=%d ending start=%d\n", myid, comlsqr.mapStar[myid][0], comlsqr.mapStar[myid][1]); - MPI_Abort(MPI_COMM_WORLD, 1); + printf("PE=%d ERROR. Only one star in this PE: starting star=%d ending start=%d\n",myid,comlsqr.mapStar[myid][0],comlsqr.mapStar[myid][1]); + MPI_Abort(MPI_COMM_WORLD,1); exit(EXIT_FAILURE); + } - if (myid == 0) - for (int i = 0; i < nproc; i++) - printf("mapStar[%d][0]=%d mapStar[%d][1]=%d\n", i, comlsqr.mapStar[i][0], i, comlsqr.mapStar[i][1]); - - //////// Check Null Space Vector - if (extConstraint) - { + if(myid==0) + for(int i=0;id_name); + if(debugMode) + for(ii=0;iid_name); } - if (nFiles <= 0) + if(nFiles <=0) { - printf("error on scandir n=%d\n", nFiles); - MPI_Abort(MPI_COMM_WORLD, 1); + printf("error on scandir n=%d\n",nFiles); + MPI_Abort(MPI_COMM_WORLD,1); } - + ////////////////// Writing FileConstr_GsrSolProps.dat - char fileConstr[512] = ""; + char fileConstr[512]=""; strcat(fileConstr, "FileConstr_"); strcat(fileConstr, filenameSolProps); - fpFilePosConstr = fopen(fileConstr, "w"); - for (int k = 0; k < counterConstr; k++) - { - fileNum = constraintFound[k][0]; - fprintf(fpFilePosConstr, "%d %s %d\n", fileNum, namelistMI[fileNum]->d_name, constraintFound[k][1]); - } - if (debugMode) - for (int k = 0; k < counterConstr; k++) - { - fileNum = constraintFound[k][0]; - printf("PE=%d %d %s %d\n", myid, fileNum, namelistMI[fileNum]->d_name, constraintFound[k][1]); + fpFilePosConstr=fopen(fileConstr,"w"); + for(int k=0;kd_name,constraintFound[k][1]); + } + if(debugMode) + for(int k=0;kd_name,constraintFound[k][1]); } - for (int np = 1; np < nproc; np++) - { - MPI_Recv(&counterConstr, 1, MPI_INT, np, 0, MPI_COMM_WORLD, &statusMpi); - MPI_Recv(&constraintFound[0][0], counterConstr * 2, MPI_INT, np, 1, MPI_COMM_WORLD, &statusMpi); - - for (int k = 0; k < counterConstr; k++) - { - fileNum = constraintFound[k][0]; - fprintf(fpFilePosConstr, "%d %s %d\n", fileNum, namelistMI[fileNum]->d_name, constraintFound[k][1]); + for(int np=1;npd_name,constraintFound[k][1]); } - if (debugMode) - for (int k = 0; k < counterConstr; k++) - { - fileNum = constraintFound[k][0]; - printf("PE=%d %d %s %d\n", np, fileNum, namelistMI[fileNum]->d_name, constraintFound[k][1]); + if(debugMode) + for(int k=0;kd_name,constraintFound[k][1]); } } fclose(fpFilePosConstr); - } - else - { + } else { MPI_Send(&counterConstr, 1, MPI_INT, 0, 0, MPI_COMM_WORLD); - MPI_Send(&constraintFound[0][0], counterConstr * 2, MPI_INT, 0, 1, MPI_COMM_WORLD); + MPI_Send(&constraintFound[0][0], counterConstr*2, MPI_INT, 0, 1, MPI_COMM_WORLD); } } - - VrIdAstroPDimMax = comlsqr.VrIdAstroPDimMax; - VrIdAstroPDim = comlsqr.VrIdAstroPDim; - VroffsetAttParam = VrIdAstroPDimMax * nAstroPSolved; - comlsqr.VroffsetAttParam = VroffsetAttParam; - - nunkSplit = VrIdAstroPDimMax * nAstroPSolved + nAttParam + nInstrParam + nGlobalParam; - comlsqr.nunkSplit = nunkSplit; - nElements = nunkSplit; - preCondVect = (double *)calloc(nElements, sizeof(double)); + + VrIdAstroPDimMax=comlsqr.VrIdAstroPDimMax; + VrIdAstroPDim=comlsqr.VrIdAstroPDim; + VroffsetAttParam = VrIdAstroPDimMax*nAstroPSolved; + comlsqr.VroffsetAttParam=VroffsetAttParam; + + nunkSplit = VrIdAstroPDimMax*nAstroPSolved + nAttParam + nInstrParam + nGlobalParam; + comlsqr.nunkSplit=nunkSplit; + nElements = nunkSplit ; + preCondVect = (double *) calloc(nElements,sizeof(double)); if (!preCondVect) - exit(err_malloc("preCondVect", myid)); - totmem += nElements * sizeof(double); - + exit(err_malloc("preCondVect",myid)); + totmem += nElements*sizeof(double); + nElements = nunkSplit; // the arrays v, w, x, and se require the same amount of memory (nunk * sizeof(double)) - vVect = (double *)calloc(nElements, sizeof(double)); + vVect = (double *) calloc(nElements, sizeof(double)); if (!vVect) - exit(err_malloc("vVect", myid)); - totmem += nElements * sizeof(double); - - wVect = (double *)calloc(nElements, sizeof(double)); + exit(err_malloc("vVect",myid)); + totmem += nElements* sizeof(double); + + wVect = (double *) calloc(nElements, sizeof(double)); if (!wVect) - exit(err_malloc("wVect", myid)); - totmem += nElements * sizeof(double); - - xSolution = (double *)calloc(nElements, sizeof(double)); + exit(err_malloc("wVect",myid)); + totmem += nElements* sizeof(double); + + xSolution = (double *) calloc(nElements, sizeof(double)); if (!xSolution) - exit(err_malloc("xSolution", myid)); - totmem += nElements * sizeof(double); - - standardError = (double *)calloc(nElements, sizeof(double)); + exit(err_malloc("xSolution",myid)); + totmem += nElements* sizeof(double); + + standardError = (double *) calloc(nElements, sizeof(double)); if (!standardError) - exit(err_malloc("standardError", myid)); - totmem += nElements * sizeof(double); - - totmem += nElements * sizeof(double); //dcopy+vAuxVect locally allocated on lsqr.c - - totmem = totmem / (1024 * 1024); // mem in MB - + exit(err_malloc("standardError",myid)); + totmem += nElements* sizeof(double); + + totmem += nElements* sizeof(double); //dcopy+vAuxVect locally allocated on lsqr.c + + totmem=totmem/(1024*1024); // mem in MB + // Compute and write the total memory allocated - if (myid == 0) + if(myid==0) { printf("LOCAL %ld MB of memory allocated on each task.\n", totmem); - printf("TOTAL MB memory allocated= %ld\n", nproc * totmem); + printf("TOTAL MB memory allocated= %ld\n", nproc*totmem ); } - + + /////////////////////////////// - + + + + MPI_Barrier(MPI_COMM_WORLD); // Compute the preconditioning vector for the system columns - - long int aIndex = 0; + + + long int aIndex=0; long instrLongIndex[6]; - long iIelem = 0; - - for (ii = 0; ii < mapNoss[myid] * multMI; ii = ii + multMI) + long iIelem=0; + + + + for (ii = 0; ii < mapNoss[myid]*multMI; ii=ii+multMI) { - long int numOfStarPos = 0; - if (nAstroPSolved > 0) - numOfStarPos = matrixIndex[ii] / nAstroPSolved; // number of star associated to matrixIndex[ii] - long int numOfAttPos = matrixIndex[ii + (multMI - 1)]; - long int VrIdAstroPValue = -1; // - - VrIdAstroPValue = numOfStarPos - comlsqr.mapStar[myid][0]; - if (VrIdAstroPValue == -1) + long int numOfStarPos=0; + if(nAstroPSolved>0) numOfStarPos=matrixIndex[ii]/nAstroPSolved; // number of star associated to matrixIndex[ii] + long int numOfAttPos=matrixIndex[ii+(multMI-1)]; + long int VrIdAstroPValue=-1; // + + VrIdAstroPValue=numOfStarPos-comlsqr.mapStar[myid][0]; + if(VrIdAstroPValue==-1) { - printf("PE=%d ERROR. Can't find gsrId for precondvect.\n", myid); - MPI_Abort(MPI_COMM_WORLD, 1); + printf("PE=%d ERROR. Can't find gsrId for precondvect.\n",myid); + MPI_Abort(MPI_COMM_WORLD,1); exit(EXIT_FAILURE); } - for (int ns = 0; ns < nAstroPSolved; ns++) + for(int ns=0;ns= nunkSplit || ncolumn < 0) - { - printf("ERROR. PE=%d ncolumn=%ld ii=%ld matrixIndex[ii]=%ld\n", myid, ncolumn, ii, + if (ncolumn >= nunkSplit || ncolumn < 0 ) { + printf("ERROR. PE=%d ncolumn=%ld ii=%ld matrixIndex[ii]=%ld\n",myid, ncolumn, ii, matrixIndex[ii]); - MPI_Abort(MPI_COMM_WORLD, 1); + MPI_Abort(MPI_COMM_WORLD,1); exit(EXIT_FAILURE); } preCondVect[ncolumn] += systemMatrix[aIndex] * systemMatrix[aIndex]; - if (preCondVect[ncolumn] == 0.0) + if(preCondVect[ncolumn]==0.0) printf("Astrometric: preCondVect[%ld]=0.0\n", ncolumn); aIndex++; } // - for (int naxis = 0; naxis < nAttAxes; naxis++) - for (int ns = 0; ns < nAttParAxis; ns++) + for(int naxis=0;naxis= nunkSplit || ncolumn < 0) - { - printf("ERROR. PE=%d numOfAttPos=%ld nStar*nAstroPSolved=%ld ncolumn=%ld ns=%d naxis=%d matrixIndex[ii+%d]=%ld\n", myid, numOfAttPos, nStar * nAstroPSolved, ncolumn, ns, naxis, multMI - 1, matrixIndex[ii + (multMI - 1)]); - MPI_Abort(MPI_COMM_WORLD, 1); + ncolumn = numOfAttPos+(VroffsetAttParam-offsetAttParam)+ns+naxis*nDegFreedomAtt; + if (ncolumn >= nunkSplit || ncolumn < 0 ) { + printf("ERROR. PE=%d numOfAttPos=%ld nStar*nAstroPSolved=%ld ncolumn=%ld ns=%d naxis=%d matrixIndex[ii+%d]=%ld\n",myid,numOfAttPos,nStar*nAstroPSolved,ncolumn, ns, naxis,multMI-1,matrixIndex[ii+(multMI-1)]); + MPI_Abort(MPI_COMM_WORLD,1); exit(EXIT_FAILURE); } preCondVect[ncolumn] += systemMatrix[aIndex] * systemMatrix[aIndex]; - if (preCondVect[ncolumn] == 0.0) - printf("Attitude: PE=%d preCondVect[%ld]=0.0 aIndex=%ld systemMatrix[aIndex]=%12.9lf\n", myid, ncolumn, aIndex, systemMatrix[aIndex]); // if aggiunto + if(preCondVect[ncolumn]==0.0) + printf("Attitude: PE=%d preCondVect[%ld]=0.0 aIndex=%ld systemMatrix[aIndex]=%12.9lf\n",myid, ncolumn,aIndex,systemMatrix[aIndex]); // if aggiunto aIndex++; } ///// End of Attitude preCondVect - - if (nInstrPSolved > 0) + + + if(nInstrPSolved>0) { - for (int ns = 0; ns < nInstrPSolved; ns++) + for(int ns=0;ns= nunkSplit || ncolumn < 0) + ncolumn = offsetInstrParam+(VroffsetAttParam-offsetAttParam)+instrCol[(ii/multMI)*nInstrPSolved+ns]; + if (ncolumn >= nunkSplit || ncolumn < 0 ) { - printf("ERROR. PE=%d ii=%ld ", myid, ii); - for (int ke = 0; ke < nInstrPSolved; ke++) - printf("instrCol[%d]=%d ", ii / multMI + ke, instrCol[ii / multMI + ke]); + printf("ERROR. PE=%d ii=%ld ",myid, ii); + for(int ke=0;ke= nunkSplit || ncolumn < 0) - { - printf("ERROR. PE=%d ncolumn=%ld ii=%ld matrixIndex[ii+2]=%ld\n", myid, ncolumn, ii, + ncolumn = offsetGlobParam+(VroffsetAttParam-offsetAttParam)+ns; + if (ncolumn >= nunkSplit || ncolumn < 0 ) { + printf("ERROR. PE=%d ncolumn=%ld ii=%ld matrixIndex[ii+2]=%ld\n",myid, ncolumn, ii, matrixIndex[ii]); - MPI_Abort(MPI_COMM_WORLD, 1); + MPI_Abort(MPI_COMM_WORLD,1); exit(EXIT_FAILURE); } preCondVect[ncolumn] += systemMatrix[aIndex] * systemMatrix[aIndex]; - if (preCondVect[ncolumn] == 0) + if(preCondVect[ncolumn]==0) printf("Global: preCondVect[%ld]=0.0\n", ncolumn); // if aggiunto aIndex++; } } - + ///// precondvect for extConstr - if (extConstraint) - { - if (aIndex != mapNcoeff[myid]) - { - printf("PE=%d. Error on aIndex=%ld different of mapNcoeff[%d]=%ld\n", myid, aIndex, myid, mapNcoeff[myid]); + if(extConstraint){ + if(aIndex!=mapNcoeff[myid]){ + printf("PE=%d. Error on aIndex=%ld different of mapNcoeff[%d]=%ld\n",myid,aIndex,myid,mapNcoeff[myid]); MPI_Abort(MPI_COMM_WORLD, 1); exit(EXIT_FAILURE); } - for (int i = 0; i < nEqExtConstr; i++) - { - long int numOfStarPos = 0; - if (nAstroPSolved > 0) - numOfStarPos = firstStarConstr; // number of star associated to matrixIndex[ii] - long int numOfAttPos = startingAttColExtConstr; - long int VrIdAstroPValue = -1; // - - VrIdAstroPValue = numOfStarPos - comlsqr.mapStar[myid][0]; - if (VrIdAstroPValue == -1) + for(int i=0;i0) numOfStarPos=firstStarConstr; // number of star associated to matrixIndex[ii] + long int numOfAttPos=startingAttColExtConstr; + long int VrIdAstroPValue=-1; // + + VrIdAstroPValue=numOfStarPos-comlsqr.mapStar[myid][0]; + if(VrIdAstroPValue==-1) { - printf("PE=%d ERROR. Can't find gsrId for precondvect.\n", myid); - MPI_Abort(MPI_COMM_WORLD, 1); + printf("PE=%d ERROR. Can't find gsrId for precondvect.\n",myid); + MPI_Abort(MPI_COMM_WORLD,1); exit(EXIT_FAILURE); } - for (int ns = 0; ns < nAstroPSolved * numOfExtStar; ns++) + for(int ns=0;ns= nunkSplit || ncolumn < 0) - { - printf("ERROR. PE=%d ncolumn=%ld ii=%ld matrixIndex[ii]=%ld\n", myid, ncolumn, ii, + if (ncolumn >= nunkSplit || ncolumn < 0 ) { + printf("ERROR. PE=%d ncolumn=%ld ii=%ld matrixIndex[ii]=%ld\n",myid, ncolumn, ii, matrixIndex[ii]); - MPI_Abort(MPI_COMM_WORLD, 1); + MPI_Abort(MPI_COMM_WORLD,1); exit(EXIT_FAILURE); } preCondVect[ncolumn] += systemMatrix[aIndex] * systemMatrix[aIndex]; - if (preCondVect[ncolumn] == 0.0) + if(preCondVect[ncolumn]==0.0) printf("Astrometric: preCondVect[%ld]=0.0\n", ncolumn); aIndex++; } // - for (int naxis = 0; naxis < nAttAxes; naxis++) - { - for (int j = 0; j < numOfExtAttCol; j++) - { - ncolumn = VrIdAstroPDimMax * nAstroPSolved + startingAttColExtConstr + j + naxis * nDegFreedomAtt; - if (ncolumn >= nunkSplit || ncolumn < 0) - { - printf("ERROR. PE=%d ncolumn=%ld naxis=%d j=%d\n", myid, ncolumn, naxis, j); - MPI_Abort(MPI_COMM_WORLD, 1); + for(int naxis=0;naxis= nunkSplit || ncolumn < 0 ) { + printf("ERROR. PE=%d ncolumn=%ld naxis=%d j=%d\n",myid,ncolumn, naxis,j); + MPI_Abort(MPI_COMM_WORLD,1); exit(EXIT_FAILURE); } - preCondVect[ncolumn] += systemMatrix[aIndex] * systemMatrix[aIndex]; - // printf("%d %d %d %d\n",ncolumn, aIndex,j,naxis); - if (preCondVect[ncolumn] == 0.0) - printf("Attitude: PE=%d preCondVect[%ld]=0.0 aIndex=%ld systemMatrix[aIndex]=%12.9lf\n", myid, ncolumn, aIndex, systemMatrix[aIndex]); // if aggiunto - aIndex++; + preCondVect[ncolumn] += systemMatrix[aIndex] * systemMatrix[aIndex]; +// printf("%d %d %d %d\n",ncolumn, aIndex,j,naxis); + if(preCondVect[ncolumn]==0.0) + printf("Attitude: PE=%d preCondVect[%ld]=0.0 aIndex=%ld systemMatrix[aIndex]=%12.9lf\n",myid, ncolumn,aIndex,systemMatrix[aIndex]); // if aggiunto + aIndex++; } } } } ///// end precondvect for extConstr ///// precondvect for barConstr - if (barConstraint) - { - for (int i = 0; i < nEqBarConstr; i++) - { - long int numOfStarPos = 0; - if (nAstroPSolved > 0) - numOfStarPos = firstStarConstr; // number of star associated to matrixIndex[ii] - long int VrIdAstroPValue = -1; // - - VrIdAstroPValue = numOfStarPos - comlsqr.mapStar[myid][0]; - if (VrIdAstroPValue == -1) + if(barConstraint){ + for(int i=0;i0) numOfStarPos=firstStarConstr; // number of star associated to matrixIndex[ii] + long int VrIdAstroPValue=-1; // + + VrIdAstroPValue=numOfStarPos-comlsqr.mapStar[myid][0]; + if(VrIdAstroPValue==-1) { - printf("PE=%d ERROR. Can't find gsrId for precondvect.\n", myid); - MPI_Abort(MPI_COMM_WORLD, 1); + printf("PE=%d ERROR. Can't find gsrId for precondvect.\n",myid); + MPI_Abort(MPI_COMM_WORLD,1); exit(EXIT_FAILURE); } - for (int ns = 0; ns < nAstroPSolved * numOfBarStar; ns++) + for(int ns=0;ns= nunkSplit || ncolumn < 0) - { - printf("ERROR. PE=%d ncolumn=%ld ii=%ld matrixIndex[ii]=%ld\n", myid, ncolumn, ii, + if (ncolumn >= nunkSplit || ncolumn < 0 ) { + printf("ERROR. PE=%d ncolumn=%ld ii=%ld matrixIndex[ii]=%ld\n",myid, ncolumn, ii, matrixIndex[ii]); - MPI_Abort(MPI_COMM_WORLD, 1); + MPI_Abort(MPI_COMM_WORLD,1); exit(EXIT_FAILURE); } preCondVect[ncolumn] += systemMatrix[aIndex] * systemMatrix[aIndex]; - if (preCondVect[ncolumn] == 0.0) - printf("Astrometric: preCondVect[%ld]=0.0\n", ncolumn); + if(preCondVect[ncolumn]==0.0) + printf("Astrometric: preCondVect[%ld]=0.0\n", ncolumn); aIndex++; } // @@ -2877,328 +2558,291 @@ int main(int argc, char **argv) ///// end precondvect for barConstr ///// precondvect for instrConstr - if (nElemIC > 0) - { - for (int i = 0; i < nElemIC; i++) - { - ncolumn = offsetInstrParam + (VroffsetAttParam - offsetAttParam) + instrCol[mapNoss[myid] * nInstrPSolved + i]; - if (ncolumn >= nunkSplit || ncolumn < 0) - { - printf("ERROR on instrConstr. PE=%d ncolumn=%ld i=%d\n", myid, ncolumn, i); - MPI_Abort(MPI_COMM_WORLD, 1); + if(nElemIC>0){ + for(int i=0;i= nunkSplit || ncolumn < 0 ) { + printf("ERROR on instrConstr. PE=%d ncolumn=%ld i=%d\n",myid,ncolumn, i); + MPI_Abort(MPI_COMM_WORLD,1); exit(EXIT_FAILURE); } preCondVect[ncolumn] += systemMatrix[aIndex] * systemMatrix[aIndex]; - if (preCondVect[ncolumn] == 0.0 && debugMode) - printf("Instrument: PE=%d preCondVect[%ld]=0.0 aIndex=%ld systemMatrix[aIndex]=%12.9lf\n", myid, ncolumn, aIndex, systemMatrix[aIndex]); + if(preCondVect[ncolumn]==0.0 && debugMode) + printf("Instrument: PE=%d preCondVect[%ld]=0.0 aIndex=%ld systemMatrix[aIndex]=%12.9lf\n",myid, ncolumn,aIndex,systemMatrix[aIndex]); aIndex++; + } } //////////////// - + + MPI_Barrier(MPI_COMM_WORLD); - + // ACCUMULATE d // double *dcopy; - dcopy = (double *)calloc(nAttParam, sizeof(double)); - if (!dcopy) - exit(err_malloc("dcopy", myid)); - mpi_allreduce(&preCondVect[VrIdAstroPDimMax * nAstroPSolved], dcopy, (long int)nAttParam, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - for (i = 0; i < nAttParam; i++) + dcopy=(double *)calloc(nAttParam,sizeof(double)); + if(!dcopy) exit(err_malloc("dcopy",myid)); + mpi_allreduce(&preCondVect[ VrIdAstroPDimMax*nAstroPSolved],dcopy,(long int) nAttParam,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); + for(i=0;i nAttParam && ii - VrIdAstroPDimMax * nAstroPSolved < nAttParam + nInstrParam) - printf("ERROR Instr ZERO column: PE=%d preCondVect[%ld]=0.0 InstrParam=%ld \n", myid, ii, ii - (VrIdAstroPDimMax * nAstroPSolved + nAttParam)); - if (ii - VrIdAstroPDimMax * nAstroPSolved > nAttParam + nInstrParam) - printf("ERROR Global ZERO column: PE=%d preCondVect[%ld]=0.0 GlobalParam=%ld \n", myid, ii, ii - (VrIdAstroPDimMax * nAstroPSolved + nAttParam + nInstrParam)); - MPI_Abort(MPI_COMM_WORLD, 1); + if(ii-VrIdAstroPDimMax*nAstroPSolvednAttParam && ii-VrIdAstroPDimMax*nAstroPSolvednAttParam+nInstrParam) + printf("ERROR Global ZERO column: PE=%d preCondVect[%ld]=0.0 GlobalParam=%ld \n",myid,ii, ii-(VrIdAstroPDimMax*nAstroPSolved+nAttParam+nInstrParam)); + MPI_Abort(MPI_COMM_WORLD,1); exit(EXIT_FAILURE); } preCondVect[ii] = 1.0 / sqrt(preCondVect[ii]); } - for (ii = VrIdAstroPDimMax * nAstroPSolved; ii < VrIdAstroPDimMax * nAstroPSolved + nAttParam + nInstrParam + nGlobalParam; ii++) - { - if (preCondVect[ii] == 0.0) + for (ii = VrIdAstroPDimMax*nAstroPSolved; ii < VrIdAstroPDimMax*nAstroPSolved + nAttParam + nInstrParam + nGlobalParam; ii++) { + if(preCondVect[ii]==0.0) { - printf("ERROR non-Astrometric ZERO column: PE=%d preCondVect[%ld]=0.0\n", myid, ii); - MPI_Abort(MPI_COMM_WORLD, 1); + printf("ERROR non-Astrometric ZERO column: PE=%d preCondVect[%ld]=0.0\n",myid,ii); + MPI_Abort(MPI_COMM_WORLD,1); exit(EXIT_FAILURE); } preCondVect[ii] = 1.0 / sqrt(preCondVect[ii]); } - } - else - { - if (myid == 0) - printf("Setting preCondVect to 1.0\n"); - for (ii = 0; ii < VrIdAstroPDim * nAstroPSolved; ii++) - { - if (preCondVect[ii] == 0.0) + } else{ + if(myid==0) printf("Setting preCondVect to 1.0\n"); + for (ii = 0; ii < VrIdAstroPDim*nAstroPSolved; ii++) { + if(preCondVect[ii]==0.0) { - printf("ERROR Astrometric ZERO column: PE=%d preCondVect[%ld]=0.0 Star=%ld\n", myid, ii, ii / nAstroPSolved); - MPI_Abort(MPI_COMM_WORLD, 1); + printf("ERROR Astrometric ZERO column: PE=%d preCondVect[%ld]=0.0 Star=%ld\n",myid,ii,ii/nAstroPSolved); + MPI_Abort(MPI_COMM_WORLD,1); exit(EXIT_FAILURE); } preCondVect[ii] = 1.0; } - for (ii = VrIdAstroPDimMax * nAstroPSolved; ii < VrIdAstroPDimMax * nAstroPSolved + nAttParam + nInstrParam + nGlobalParam; ii++) - { - if (preCondVect[ii] == 0.0) + for (ii = VrIdAstroPDimMax*nAstroPSolved; ii < VrIdAstroPDimMax*nAstroPSolved + nAttParam + nInstrParam + nGlobalParam; ii++) { + if(preCondVect[ii]==0.0) { - if (ii - VrIdAstroPDimMax * nAstroPSolved < nAttParam) - printf("ERROR Att ZERO column: PE=%d preCondVect[%ld]=0.0 AttParam=%ld \n", myid, ii, ii - VrIdAstroPDimMax * nAstroPSolved); - if (ii - VrIdAstroPDimMax * nAstroPSolved > nAttParam && ii - VrIdAstroPDimMax * nAstroPSolved < nAttParam + nInstrParam) - printf("ERROR Instr ZERO column: PE=%d preCondVect[%ld]=0.0 InstrParam=%ld \n", myid, ii, ii - (VrIdAstroPDimMax * nAstroPSolved + nAttParam)); - if (ii - VrIdAstroPDimMax * nAstroPSolved > nAttParam + nInstrParam) - printf("ERROR Global ZERO column: PE=%d preCondVect[%ld]=0.0 GlobalParam=%ld \n", myid, ii, ii - (VrIdAstroPDimMax * nAstroPSolved + nAttParam + nInstrParam)); - MPI_Abort(MPI_COMM_WORLD, 1); + if(ii-VrIdAstroPDimMax*nAstroPSolvednAttParam && ii-VrIdAstroPDimMax*nAstroPSolvednAttParam+nInstrParam) + printf("ERROR Global ZERO column: PE=%d preCondVect[%ld]=0.0 GlobalParam=%ld \n",myid,ii, ii-(VrIdAstroPDimMax*nAstroPSolved+nAttParam+nInstrParam)); + MPI_Abort(MPI_COMM_WORLD,1); exit(EXIT_FAILURE); } preCondVect[ii] = 1.0; } + } - - if (myid == 0) + + if(myid==0) { printf("Computation of the preconditioning vector finished.\n"); } - comlsqr.nvinc = 0; - comlsqr.parOss = (long)nparam; - comlsqr.nunk = nunk; - comlsqr.offsetAttParam = offsetAttParam; - comlsqr.offsetInstrParam = offsetInstrParam; - comlsqr.offsetGlobParam = offsetGlobParam; - comlsqr.nAttParam = nAttParam; - comlsqr.instrConst[0] = instrConst[0]; - comlsqr.instrConst[1] = instrConst[1]; - comlsqr.instrConst[2] = instrConst[2]; - comlsqr.instrConst[3] = instrConst[3]; - comlsqr.timeCPR = timeCPR; - comlsqr.timeLimit = timeLimit; - comlsqr.itnCPR = itnCPR; - comlsqr.itnCPRstop = itnCPRstop; - comlsqr.itnLimit = itnlim; - comlsqr.Test = 0; //it is not a running test but a production run - - initThread(matrixIndex, &comlsqr); - - endTime = MPI_Wtime() - endTime; + comlsqr.nvinc=0; + comlsqr.parOss=(long) nparam; + comlsqr.nunk=nunk; + comlsqr.offsetAttParam=offsetAttParam; + comlsqr.offsetInstrParam=offsetInstrParam; + comlsqr.offsetGlobParam=offsetGlobParam; + comlsqr.nAttParam=nAttParam; + comlsqr.instrConst[0]=instrConst[0]; + comlsqr.instrConst[1]=instrConst[1]; + comlsqr.instrConst[2]=instrConst[2]; + comlsqr.instrConst[3]=instrConst[3]; + comlsqr.timeCPR=timeCPR; + comlsqr.timeLimit=timeLimit; + comlsqr.itnCPR=itnCPR; + comlsqr.itnCPRstop=itnCPRstop; + comlsqr.itnLimit=itnlim; + comlsqr.Test=0; //it is not a running test but a production run + + initThread(matrixIndex,&comlsqr); + + + endTime=MPI_Wtime()-endTime; MPI_Barrier(MPI_COMM_WORLD); - + //////// WRITE BIN FILES and FileConstr_GsrSolProps.dat - + //////////////////////////// noiter - if (noIter) - { - if (myid == 0) - printf("\nEnd run: -noiter option givens.\n"); - + if(noIter){ + if(myid==0) printf("\nEnd run: -noiter option givens.\n"); + MPI_Finalize(); exit(EXIT_SUCCESS); - + } /////////////// MAIN CALL - + ///////////// // This function computes the product of system matrix by precondVect. This avoids to compute the produsct in aprod for each iteration. - if (myid == 0 && debugMode) + if(myid==0 && debugMode) { - printf("TEST LSQR START nobs=%ld, nunk=%ld, damp=%f, knownTerms[0]=%f, knownTerms[%ld]=%f, atol=%f btol=%f conlim=%f itnlim=%ld systemMatrix[0]=%f, systemMatrix[%ld]=%f matrixIndex[0]=%ld matrixIndex[%ld]=%ld instrCol[0]=%d instrCol[%ld]=%d preCondVect[0]=%f preCondVect[%ld]=%f preCondVect[%ld]=%f nunkSplit=%ld\n", nobs, nunk, damp, knownTerms[0], mapNoss[myid] - 1, knownTerms[mapNoss[myid] - 1], atol, btol, conlim, itnlim, systemMatrix[0], mapNcoeff[myid] - 1, systemMatrix[mapNcoeff[myid] - 1], matrixIndex[0], mapNoss[myid] * 2 - 1, matrixIndex[mapNoss[myid] * 2 - 1], instrCol[0], mapNoss[myid] * nInstrPSolved - 1, instrCol[mapNoss[myid] * nInstrPSolved - 1], preCondVect[0], VrIdAstroPDim * nAstroPSolved - 1, preCondVect[VrIdAstroPDim * nAstroPSolved - 1], VrIdAstroPDim * nAstroPSolved, preCondVect[VrIdAstroPDim * nAstroPSolved], nunkSplit); + printf("TEST LSQR START nobs=%ld, nunk=%ld, damp=%f, knownTerms[0]=%f, knownTerms[%ld]=%f, atol=%f btol=%f conlim=%f itnlim=%ld systemMatrix[0]=%f, systemMatrix[%ld]=%f matrixIndex[0]=%ld matrixIndex[%ld]=%ld instrCol[0]=%d instrCol[%ld]=%d preCondVect[0]=%f preCondVect[%ld]=%f preCondVect[%ld]=%f nunkSplit=%ld\n",nobs, nunk, damp, knownTerms[0], mapNoss[myid]-1,knownTerms[mapNoss[myid]-1], atol, btol,conlim,itnlim, systemMatrix[0],mapNcoeff[myid]-1,systemMatrix[mapNcoeff[myid]-1], matrixIndex[0],mapNoss[myid]*2-1, matrixIndex[mapNoss[myid]*2-1], instrCol[0], mapNoss[myid]*nInstrPSolved -1,instrCol[mapNoss[myid]*nInstrPSolved -1], preCondVect[0],VrIdAstroPDim*nAstroPSolved-1, preCondVect[VrIdAstroPDim*nAstroPSolved-1], VrIdAstroPDim*nAstroPSolved, preCondVect[VrIdAstroPDim*nAstroPSolved], nunkSplit); } - precondSystemMatrix(systemMatrix, preCondVect, matrixIndex, instrCol, comlsqr); + precondSystemMatrix(systemMatrix, preCondVect, matrixIndex,instrCol,comlsqr); //systemMatrix is passed to lsqr already conditioned. - if (myid == 0) - { + if(myid==0) { printf("System built, ready to call LSQR.\nPlease wait. System solution is underway..."); } //////////////////// - startTime = MPI_Wtime(); + startTime=MPI_Wtime(); seconds[1] = time(NULL); tot_sec[0] = seconds[1] - seconds[0]; - comlsqr.totSec = tot_sec[0]; - if (myid == 0) - printf("Starting lsqr after sec: %ld\n", tot_sec[0]); + comlsqr.totSec=tot_sec[0]; + if(myid==0) printf("Starting lsqr after sec: %ld\n", tot_sec[0]); chdir(wpath); - if (outputDirOpt) - chdir(outputDir); // go to output dir + if(outputDirOpt) chdir(outputDir); // go to output dir lsqr(nobs, nunk, damp, knownTerms, vVect, wVect, xSolution, standardError, atol, btol, conlim, - (int)itnlim, &istop, &itn, &anorm, &acond, &rnorm, &arnorm, - &xnorm, systemMatrix, matrixIndex, instrCol, instrConstrIlung, preCondVect, comlsqr); - + (int) itnlim, &istop, &itn, &anorm, &acond, &rnorm, &arnorm, + &xnorm, systemMatrix, matrixIndex, instrCol, instrConstrIlung,preCondVect,comlsqr); + /////////////////////////// MPI_Barrier(MPI_COMM_WORLD); - endTime = MPI_Wtime(); - double clockTime = MPI_Wtime(); - if (myid == 0) - printf("Global Time for lsqr =%f sec \n", endTime - startTime); + endTime=MPI_Wtime(); + double clockTime=MPI_Wtime(); + if(myid==0) printf("Global Time for lsqr =%f sec \n",endTime-startTime); seconds[2] = time(NULL); tot_sec[1] = seconds[2] - seconds[1]; - - long thetaCol = 0, muthetaCol = 0; + + long thetaCol=0, muthetaCol=0; ldiv_t res_ldiv; - long flagTheta = 0, flagMuTheta = 0; - - if (nAstroPSolved == 2) - { - thetaCol = 1; - muthetaCol = 0; + long flagTheta=0, flagMuTheta=0; + + if(nAstroPSolved==2) { + thetaCol=1; + muthetaCol=0; } - else if (nAstroPSolved == 3) - { - thetaCol = 2; - muthetaCol = 0; + else if(nAstroPSolved==3) { + thetaCol=2; + muthetaCol=0; } - else if (nAstroPSolved == 4) - { - thetaCol = 1; - muthetaCol = 3; + else if(nAstroPSolved==4) { + thetaCol=1; + muthetaCol=3; } - else if (nAstroPSolved == 5) - { - thetaCol = 2; - muthetaCol = 4; + else if(nAstroPSolved==5) { + thetaCol=2; + muthetaCol=4; } - + double epsilon; - double localSumX = 0, localSumXsq = 0, sumX = 0, sumXsq = 0, average = 0, rms = 0; - double dev = 0, localMaxDev = 0, maxDev = 0; - + double localSumX=0, localSumXsq=0, sumX=0, sumXsq=0, average=0, rms=0; + double dev=0, localMaxDev=0, maxDev=0; + ///////// Each PE runs over the its Astrometric piece - if (muthetaCol == 0) - for (ii = 0; ii < VrIdAstroPDim * nAstroPSolved; ii++) - { - res_ldiv = ldiv((ii - thetaCol), nAstroPSolved); - flagTheta = res_ldiv.rem; - if (flagTheta == 0) - { - xSolution[ii] *= (-preCondVect[ii]); - if (idtest) + if(muthetaCol==0) + for(ii=0; ii localMaxDev) - localMaxDev = dev; + epsilon=xSolution[ii]+1.0; + localSumX-=epsilon; + dev=fabs(epsilon); + if(dev>localMaxDev) localMaxDev=dev; } } else { - xSolution[ii] *= preCondVect[ii]; // the corrections in theta are converted for consistency with the naming conventions in the Data Model to corrections in delta by a change of sign (Mantis Issue 0013081) - if (idtest) + xSolution[ii]*=preCondVect[ii]; // the corrections in theta are converted for consistency with the naming conventions in the Data Model to corrections in delta by a change of sign (Mantis Issue 0013081) + if(idtest) { - epsilon = xSolution[ii] - 1.0; - localSumX += epsilon; - dev = fabs(epsilon); - if (dev > localMaxDev) - localMaxDev = dev; + epsilon=xSolution[ii]-1.0; + localSumX+=epsilon; + dev=fabs(epsilon); + if(dev>localMaxDev) localMaxDev=dev; } + } - if (idtest) - localSumXsq += epsilon * epsilon; - standardError[ii] *= preCondVect[ii]; + if(idtest) localSumXsq+=epsilon*epsilon; + standardError[ii]*=preCondVect[ii]; } else - for (ii = 0; ii < VrIdAstroPDim * nAstroPSolved; ii++) - { - res_ldiv = ldiv((ii - thetaCol), nAstroPSolved); - flagTheta = res_ldiv.rem; - res_ldiv = ldiv((ii - muthetaCol), nAstroPSolved); - flagMuTheta = res_ldiv.rem; - if ((flagTheta == 0) || (flagMuTheta == 0)) - { - xSolution[ii] *= (-preCondVect[ii]); - if (idtest) - { - epsilon = xSolution[ii] + 1.0; - localSumX -= epsilon; - dev = fabs(epsilon); - if (dev > localMaxDev) - localMaxDev = dev; + for(ii=0; iilocalMaxDev) localMaxDev=dev; } - } - else - { - xSolution[ii] *= preCondVect[ii]; // the corrections in theta are converted for consistency with the naming conventions in the Data Model to corrections in delta by a change of sign (Mantis Issue 0013081) - if (idtest) - { - epsilon = xSolution[ii] - 1.0; - localSumX += epsilon; - dev = fabs(epsilon); - if (dev > localMaxDev) - localMaxDev = dev; + } else { + xSolution[ii]*=preCondVect[ii]; // the corrections in theta are converted for consistency with the naming conventions in the Data Model to corrections in delta by a change of sign (Mantis Issue 0013081) + if(idtest) { + epsilon=xSolution[ii]-1.0; + localSumX+=epsilon; + dev=fabs(epsilon); + if(dev>localMaxDev) localMaxDev=dev; } } - if (idtest) - localSumXsq += epsilon * epsilon; - standardError[ii] *= preCondVect[ii]; + if(idtest) localSumXsq+=epsilon*epsilon; + standardError[ii]*=preCondVect[ii]; } //////////// End of de-preconditioning for the Astrometric unknowns - + //////////// Then only PE=0 runs over the shared unknowns (Attitude, Instrument, and Global) - if (myid == 0) - for (ii = VroffsetAttParam; ii < nunkSplit; ii++) - { - xSolution[ii] *= preCondVect[ii]; - if (idtest) - { - localSumX += (xSolution[ii] - 1.0); - dev = fabs(1.0 - xSolution[ii]); - if (dev > localMaxDev) - localMaxDev = dev; - localSumXsq += (xSolution[ii] - 1.0) * (xSolution[ii] - 1.0); + if(myid==0) + for(ii=VroffsetAttParam; iilocalMaxDev) localMaxDev=dev; + localSumXsq+=(xSolution[ii]-1.0)*(xSolution[ii]-1.0); } - standardError[ii] *= preCondVect[ii]; + standardError[ii]*=preCondVect[ii]; } //////////// End of de-preconditioning for the shared unknowns - + + //////////////// TEST per verificare le somme di idtest.... da commentare/eliminare /* if(idtest) @@ -3210,7 +2854,7 @@ int main(int argc, char **argv) } */ //////////////// Fine TEST - + free(systemMatrix); free(matrixIndex); free(instrCol); @@ -3219,31 +2863,30 @@ int main(int argc, char **argv) free(wVect); free(preCondVect); - if (idtest) + if(idtest) { - MPI_Reduce(&localSumX, &sumX, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); - MPI_Reduce(&localSumXsq, &sumXsq, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); - MPI_Reduce(&localMaxDev, &maxDev, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD); + MPI_Reduce(&localSumX,&sumX,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD); + MPI_Reduce(&localSumXsq,&sumXsq,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD); + MPI_Reduce(&localMaxDev,&maxDev,1,MPI_DOUBLE,MPI_MAX,0,MPI_COMM_WORLD); } - - if (myid == 0) + + if(myid==0) { - if (idtest) + if(idtest) { - average = sumX / nunk; - rms = pow(sumXsq / nunk - pow(average, 2.0), 0.5); + average=sumX/nunk; + rms=pow(sumXsq/nunk-pow(average,2.0),0.5); printf("Average deviation from ID solution: %le.\n", average); printf(" rms: %le.\n", rms); printf("Maximum deviation from ID solution: %le.\n", maxDev); } } - - if (istop == 1000 && wrsol == 0) + + if(istop==1000 && wrsol==0) { - if (myid == 0) - { - printf("Reached limit at itn=%d. Execution stopped. CPR written!\n", itn); - ffcont = fopen("CPR_CONT", "w"); + if(myid==0){ + printf("Reached limit at itn=%d. Execution stopped. CPR written!\n",itn); + ffcont=fopen("CPR_CONT","w"); fclose(ffcont); } MPI_Finalize(); @@ -3251,304 +2894,283 @@ int main(int argc, char **argv) } /////////////// ///////////// Initialize the output filename - if (istop == 1000) - { - sprintf(filenameAstroResults, "%s%d%s", "GsrAstroParamSolution_intermediate_", itn, ".bin"); // file storing the Astrometric Parameters - sprintf(filenameAttResults, "%s%d%s", "GsrAttitudeParamSolution_intermediate_", itn, ".bin"); // file storing the Attitude Parameters - sprintf(filenameInstrResults, "%s%d%s", "GsrInstrParamSolution_intermediate_", itn, ".bin"); // file storing the Instrument Parameters - sprintf(filenameGlobalResults, "%s%d%s", "GsrGlobalParamSolution_intermediate_", itn, ".bin"); // file storing the Global Parameters - sprintf(filenameSolPropsFinal, "GsrFinal_intermediate_%d_%s", itn, argv[argc - 1]); - } - else - { - if (myid == 0) - { + if(istop==1000){ + sprintf(filenameAstroResults, "%s%d%s", "GsrAstroParamSolution_intermediate_",itn,".bin"); // file storing the Astrometric Parameters + sprintf(filenameAttResults, "%s%d%s","GsrAttitudeParamSolution_intermediate_",itn,".bin"); // file storing the Attitude Parameters + sprintf(filenameInstrResults, "%s%d%s","GsrInstrParamSolution_intermediate_",itn,".bin"); // file storing the Instrument Parameters + sprintf(filenameGlobalResults, "%s%d%s","GsrGlobalParamSolution_intermediate_",itn,".bin"); // file storing the Global Parameters + sprintf(filenameSolPropsFinal,"GsrFinal_intermediate_%d_%s",itn, argv[argc-1]); + } else{ + if(myid==0){ printf("Execution finished END_FILE written!\n"); chdir(wpath); - ffcont = fopen("END_FILE", "w"); + ffcont=fopen("END_FILE","w"); fclose(ffcont); system("rm CPR_CONT"); - if (outputDirOpt) - chdir(outputDir); // go to output dir - } - sprintf(filenameAstroResults, "%s", "GsrAstroParamSolution.bin"); // file storing the Astrometric Parameters - sprintf(filenameAttResults, "%s", "GsrAttitudeParamSolution.bin"); // file storing the Attitude Parameters - sprintf(filenameInstrResults, "%s", "GsrInstrParamSolution.bin"); // file storing the Instrument Parameters - sprintf(filenameGlobalResults, "%s", "GsrGlobalParamSolution.bin"); // file storing the Global Parameters - sprintf(filenameSolPropsFinal, "GsrFinal_%s", argv[argc - 1]); + if(outputDirOpt) chdir(outputDir); // go to output dir + } + sprintf(filenameAstroResults, "%s", "GsrAstroParamSolution.bin"); // file storing the Astrometric Parameters + sprintf(filenameAttResults, "%s","GsrAttitudeParamSolution.bin"); // file storing the Attitude Parameters + sprintf(filenameInstrResults, "%s","GsrInstrParamSolution.bin"); // file storing the Instrument Parameters + sprintf(filenameGlobalResults, "%s","GsrGlobalParamSolution.bin"); // file storing the Global Parameters + sprintf(filenameSolPropsFinal,"GsrFinal_%s", argv[argc-1]); } - if (debugMode && myid == 0) - printf("Output %s %s %s %s %s\n", filenameSolProps, filenameAstroResults, filenameAttResults, filenameInstrResults, filenameGlobalResults); + if(debugMode && myid==0) printf("Output %s %s %s %s %s\n",filenameSolProps,filenameAstroResults, filenameAttResults, filenameInstrResults, filenameGlobalResults); ///////////////////////////////////////////// - + MPI_Status statusMpi; if (myid == 0) { printf("Processing finished.\n"); fflush(stdout); - for (ii = 0; ii < 10; ii++) - printf("xSolution[%ld]=%16.12le \t standardError[%ld]=%16.12le\n", ii, xSolution[ii], ii, standardError[ii]); + for (ii = 0; ii < 10; ii++) printf("xSolution[%ld]=%16.12le \t standardError[%ld]=%16.12le\n", ii, xSolution[ii],ii,standardError[ii]); } - + ////////// Writing final solution - - if (myid == 0) + + if(myid==0) { - + ////////// Writing the raw results to the files GsrFinal_GsrSolProps.dat - - fpSolPropsFinal = fopen(filenameSolPropsFinal, "w"); + + + fpSolPropsFinal=fopen(filenameSolPropsFinal,"w"); if (!fpSolPropsFinal) { - printf("Error while open %s\n", filenameSolPropsFinal); - MPI_Abort(MPI_COMM_WORLD, 1); + printf("Error while open %s\n",filenameSolPropsFinal); + MPI_Abort(MPI_COMM_WORLD,1); exit(EXIT_FAILURE); } - fprintf(fpSolPropsFinal, "sphereId= %ld\n", sphereId); - fprintf(fpSolPropsFinal, "nStar= %ld\n", nStar); - fprintf(fpSolPropsFinal, "nAttParam= %d\n", nAttParam); - fprintf(fpSolPropsFinal, "nInstrParam= %d\n", nInstrParam); - fprintf(fpSolPropsFinal, "nInstrParamTot= %d\n", nInstrParamTot); - fprintf(fpSolPropsFinal, "nGlobalParam= %d\n", nGlobalParam); - fprintf(fpSolPropsFinal, "nAstroPSolved= %d\n", nAstroPSolved); - fprintf(fpSolPropsFinal, "nInstrPSolved= %d\n", nInstrPSolved); - fprintf(fpSolPropsFinal, "nFoVs= %d\n", nFoVs); - fprintf(fpSolPropsFinal, "nCCDs= %d\n", nCCDs); - fprintf(fpSolPropsFinal, "nPixelColumns= %d\n", nPixelColumns); - fprintf(fpSolPropsFinal, "nTimeIntervals= %d\n", nTimeIntervals); - fprintf(fpSolPropsFinal, "lSQRacond= %lf\n", acond); - fprintf(fpSolPropsFinal, "lSQRanorm= %lf\n", anorm); - fprintf(fpSolPropsFinal, "lSQRarnorm= %lf\n", arnorm); - fprintf(fpSolPropsFinal, "lSQRitNumb= %d\n", itn); - fprintf(fpSolPropsFinal, "lSQRrnorm= %lf\n", rnorm); - fprintf(fpSolPropsFinal, "lSQRstopCond= %d\n", istop); - fprintf(fpSolPropsFinal, "lSQRxnorm= %lf\n", xnorm); + fprintf(fpSolPropsFinal, "sphereId= %ld\n",sphereId) ; + fprintf(fpSolPropsFinal, "nStar= %ld\n",nStar) ; + fprintf(fpSolPropsFinal, "nAttParam= %d\n",nAttParam) ; + fprintf(fpSolPropsFinal, "nInstrParam= %d\n",nInstrParam) ; + fprintf(fpSolPropsFinal, "nInstrParamTot= %d\n",nInstrParamTot) ; + fprintf(fpSolPropsFinal, "nGlobalParam= %d\n",nGlobalParam) ; + fprintf(fpSolPropsFinal, "nAstroPSolved= %d\n",nAstroPSolved) ; + fprintf(fpSolPropsFinal, "nInstrPSolved= %d\n",nInstrPSolved) ; + fprintf(fpSolPropsFinal, "nFoVs= %d\n",nFoVs); + fprintf(fpSolPropsFinal, "nCCDs= %d\n",nCCDs); + fprintf(fpSolPropsFinal, "nPixelColumns= %d\n",nPixelColumns); + fprintf(fpSolPropsFinal, "nTimeIntervals= %d\n",nTimeIntervals); + fprintf(fpSolPropsFinal, "lSQRacond= %lf\n",acond) ; + fprintf(fpSolPropsFinal, "lSQRanorm= %lf\n",anorm) ; + fprintf(fpSolPropsFinal, "lSQRarnorm= %lf\n",arnorm) ; + fprintf(fpSolPropsFinal, "lSQRitNumb= %d\n",itn) ; + fprintf(fpSolPropsFinal, "lSQRrnorm= %lf\n",rnorm) ; + fprintf(fpSolPropsFinal, "lSQRstopCond= %d\n",istop) ; + fprintf(fpSolPropsFinal, "lSQRxnorm= %lf\n",xnorm) ; fclose(fpSolPropsFinal); - + ////////////////////// Writing GsrAstroParamSolution.bin - if (nAstroPSolved) + if(nAstroPSolved) { - long testOnStars = 0; - fpAstroR = fopen(filenameAstroResults, "wb"); + long testOnStars=0; + fpAstroR=fopen(filenameAstroResults,"wb"); if (!fpAstroR) { - printf("Error while open %s\n", filenameAstroResults); - MPI_Abort(MPI_COMM_WORLD, 1); + printf("Error while open %s\n",filenameAstroResults); + MPI_Abort(MPI_COMM_WORLD,1); exit(EXIT_FAILURE); } - fwrite(&sphereId, sizeof(long), 1, fpAstroR); - xAstro = (double *)calloc(VrIdAstroPDimMax * nAstroP, sizeof(double)); + fwrite(&sphereId,sizeof(long),1,fpAstroR); + xAstro = (double *) calloc(VrIdAstroPDimMax*nAstroP, sizeof(double)); if (!xAstro) { printf("Error allocating xAstro\n"); - MPI_Abort(MPI_COMM_WORLD, 1); + MPI_Abort(MPI_COMM_WORLD,1); exit(EXIT_FAILURE); } - for (ii = 0; ii < VrIdAstroPDim; ii++) + for(ii=0; ii