X-Git-Url: http://git.kpe.io/?p=ctsim.git;a=blobdiff_plain;f=src%2Fctrec.cpp;h=c9c3ead1f20c3ec1df854945278d9d27b9fd888c;hp=19278c98bbeb2443c3de464edf6fdcb5b9bc59e4;hb=031437896d0dc6cac70c16e5604b10f5aa4d0767;hpb=c481fbf2890e6e3a0a5479a9e53e685634ce411a diff --git a/src/ctrec.cpp b/src/ctrec.cpp index 19278c9..c9c3ead 100644 --- a/src/ctrec.cpp +++ b/src/ctrec.cpp @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2000 Kevin Rosenberg ** -** $Id: ctrec.cpp,v 1.7 2000/06/10 22:33:11 kevin Exp $ +** $Id: ctrec.cpp,v 1.8 2000/06/13 16:20:31 kevin Exp $ ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License (version 2) as @@ -26,6 +26,8 @@ ******************************************************************************/ #include "ct.h" +#include "timer.h" + enum {O_INTERP, O_FILTER, O_FILTER_PARAM, O_BACKPROJ, O_VERBOSE, O_TRACE, O_HELP, O_DEBUG, O_VERSION}; @@ -43,10 +45,11 @@ static struct option my_options[] = {0, 0, 0, 0} }; + void ctrec_usage (const char *program) { - cout << "usage: " << kbasename(program) << " raysum-file image-file nx-image ny-image [OPTIONS]" << endl; + cout << "usage: " << fileBasename(program) << " raysum-file image-file nx-image ny-image [OPTIONS]" << endl; cout << "Image reconstruction from raysum projections" << endl; cout << endl; cout << " raysum-file Input raysum file" << endl; @@ -92,19 +95,19 @@ ctrec_usage (const char *program) #ifdef HAVE_MPI -static void mpi_scatter_rs (MPIWorld& mpiWorld, RAYSUM *rs_global, RAYSUM *rs_local, const int debug); +static void ScatterProjectionsMPI (MPIWorld& mpiWorld, RAYSUM *rsGlobal, RAYSUM *rsLocal, const int debug); +static void ReduceImageMPI (MPIWorld& mpiWorld, ImageFile* imLocal, ImageFile* imGlobal); #endif int ctrec_main (int argc, char * argv[]) { - ImageFile *im_global = NULL; - RAYSUM *rs_global = NULL; + ImageFile *imGlobal = NULL; + RAYSUM *rsGlobal = NULL; char *rs_name, *im_filename = NULL; char remark[MAXREMARK]; char filt_name[80]; - double time_start = 0, time_end = 0; char *endptr; int opt_verbose = 0; int opt_debug = 0; @@ -116,19 +119,14 @@ ctrec_main (int argc, char * argv[]) BackprojType opt_backproj = O_BPROJ_DIFF2; int nx, ny; #ifdef HAVE_MPI - ImageFile *im_local; - RAYSUM *rs_local; + ImageFile *imLocal; + RAYSUM *rsLocal; int mpi_nview, mpi_ndet; double mpi_detinc, mpi_rotinc, mpi_phmlen; - double mpi_t1, mpi_t2, mpi_t, mpi_t_g; MPIWorld mpiWorld (argc, argv); #endif -#ifdef HAVE_MPI - time_start = MPI::Wtime(); -#else - time_start = td_current_sec(); -#endif + Timer timerProgram; #ifdef HAVE_MPI if (mpiWorld.getRank() == 0) { @@ -217,26 +215,26 @@ ctrec_main (int argc, char * argv[]) nx, ny, filt_name, name_of_interpolation (opt_interp), name_of_backproj(opt_backproj)); if (opt_verbose) - fprintf (stdout, "%s\n", remark); + cout << "Remark: " << remark << endl; #ifdef HAVE_MPI } #endif #ifdef HAVE_MPI if (mpiWorld.getRank() == 0) { - rs_global = raysum_open (rs_name); - raysum_read (rs_global); + rsGlobal = raysum_open (rs_name); + raysum_read (rsGlobal); if (opt_verbose) - raysum_print_info(rs_global); + raysum_print_info(rsGlobal); - mpi_ndet = rs_global->ndet; - mpi_nview = rs_global->nview; - mpi_detinc = rs_global->det_inc; - mpi_phmlen = rs_global->phmlen; - mpi_rotinc = rs_global->rot_inc; + mpi_ndet = rsGlobal->ndet; + mpi_nview = rsGlobal->nview; + mpi_detinc = rsGlobal->det_inc; + mpi_phmlen = rsGlobal->phmlen; + mpi_rotinc = rsGlobal->rot_inc; } - mpi_t1 = MPI::Wtime(); + TimerCollectiveMPI timerBcast (mpiWorld.getComm()); mpiWorld.getComm().Bcast (&opt_verbose, 1, MPI::INT, 0); mpiWorld.getComm().Bcast (&opt_debug, 1, MPI::INT, 0); mpiWorld.getComm().Bcast (&opt_trace, 1, MPI::INT, 0); @@ -252,144 +250,119 @@ ctrec_main (int argc, char * argv[]) mpiWorld.getComm().Bcast (&mpi_rotinc, 1, MPI::DOUBLE, 0); mpiWorld.getComm().Bcast (&nx, 1, MPI::INT, 0); mpiWorld.getComm().Bcast (&ny, 1, MPI::INT, 0); - if (opt_verbose) { - mpi_t2 = MPI::Wtime(); - mpi_t = mpi_t2 - mpi_t1; - mpiWorld.getComm().Reduce(&mpi_t, &mpi_t_g, 1, MPI::DOUBLE, MPI::MAX, 0); - if (mpiWorld.getRank() == 0) - printf("Time to Bcast vars = %f secs, Max time = %f\n", mpi_t, mpi_t_g); - } + if (opt_verbose) + timerBcast.timerEndAndReport ("Time to broadcast variables"); mpiWorld.setTotalWorkUnits (mpi_nview); - rs_local = raysum_create (NULL, mpiWorld.getMyLocalWorkUnits(), mpi_ndet); - rs_local->ndet = mpi_ndet; - rs_local->nview = mpi_nview; - rs_local->det_inc = mpi_detinc; - rs_local->phmlen = mpi_phmlen; - rs_local->rot_inc = mpi_rotinc; + rsLocal = raysum_create (NULL, mpiWorld.getMyLocalWorkUnits(), mpi_ndet); + rsLocal->ndet = mpi_ndet; + rsLocal->nview = mpi_nview; + rsLocal->det_inc = mpi_detinc; + rsLocal->phmlen = mpi_phmlen; + rsLocal->rot_inc = mpi_rotinc; + TimerCollectiveMPI timerScatter (mpiWorld.getComm()); + ScatterProjectionsMPI (mpiWorld, rsGlobal, rsLocal, opt_debug); if (opt_verbose) - mpi_t1 = MPI::Wtime(); - mpi_scatter_rs(mpiWorld, rs_global, rs_local, opt_debug); - if (opt_verbose) { - mpi_t2 = MPI::Wtime(); - mpi_t = mpi_t2 - mpi_t1; - mpiWorld.getComm().Reduce(&mpi_t, &mpi_t_g, 1, MPI::DOUBLE, MPI::MAX, 0); - if (mpiWorld.getRank() == 0) - printf("Time to scatter rs = %f secs, Max time = %f sec\n", mpi_t, mpi_t_g); - } + timerScatter.timerEndAndReport ("Time to scatter projections"); if (mpiWorld.getRank() == 0) { - im_global = new ImageFile (im_filename, nx, ny); - im_global->fileCreate(); + imGlobal = new ImageFile (im_filename, nx, ny); + imGlobal->fileCreate(); } - im_local = new ImageFile (nx, ny); + imLocal = new ImageFile (nx, ny); #else - rs_global = raysum_open (rs_name); - raysum_read (rs_global); + rsGlobal = raysum_open (rs_name); + raysum_read (rsGlobal); if (opt_verbose) - raysum_print_info(rs_global); + raysum_print_info(rsGlobal); - im_global = new ImageFile (im_filename, nx, ny); - im_global->fileCreate(); -#endif - -#ifdef HAVE_MPI - mpi_t1 = MPI::Wtime(); - proj_reconst (*im_local, rs_local, opt_filter, opt_filter_param, - opt_interp, opt_interp_param, opt_backproj, opt_trace); - - mpi_t2 = MPI::Wtime(); - mpi_t = mpi_t2 - mpi_t1; - mpiWorld.getComm().Reduce(&mpi_t, &mpi_t_g, 1, MPI::DOUBLE, MPI::MAX, 0); - if (mpiWorld.getRank() == 0 && opt_verbose) - printf("Time to reconstruct = %f, Max time = %f\n", mpi_t, mpi_t_g); -#else - proj_reconst (*im_global, rs_global, opt_filter, opt_filter_param, - opt_interp, opt_interp_param, opt_backproj, opt_trace); + imGlobal = new ImageFile (im_filename, nx, ny); + imGlobal->fileCreate(); #endif #ifdef HAVE_MPI + TimerCollectiveMPI timerReconstruct (mpiWorld.getComm()); + proj_reconst (*imLocal, rsLocal, opt_filter, opt_filter_param, opt_interp, opt_interp_param, opt_backproj, opt_trace); if (opt_verbose) - mpi_t1 = MPI::Wtime(); - - int nxLocal = im_local->nx(); - int nyLocal = im_local->ny(); - ImageFileArray vLocal = im_local->getArray(); - ImageFileArray vGlobal = NULL; - if (mpiWorld.getRank() == 0) - vGlobal = im_global->getArray(); - - for (int ix = 0; ix < nxLocal; ix++) { - void *recvbuf = NULL; - if (mpiWorld.getRank() == 0) - recvbuf = vGlobal[ix]; + timerReconstruct.timerEndAndReport ("Time to reconstruct"); - mpiWorld.getComm().Reduce(vLocal[ix], recvbuf, nyLocal, im_local->getMPIDataType(), MPI::SUM, 0); - } - - if (opt_verbose) { - mpi_t2 = MPI::Wtime(); - mpi_t = mpi_t2 - mpi_t1; - mpiWorld.getComm().Reduce (&mpi_t, &mpi_t_g, 1, MPI::DOUBLE, MPI::MAX, 0); - if (mpiWorld.getRank() == 0) - printf("Time to reduce image = %f secs, max time = %f\n", mpi_t, mpi_t_g); - } - - if (mpiWorld.getRank() == 0) - time_end = MPI::Wtime(); + TimerCollectiveMPI timerReduce (mpiWorld.getComm()); + ReduceImageMPI (mpiWorld, imLocal, imGlobal); + if (opt_verbose) + timerReduce.timerEndAndReport ("Time to reduce image"); #else - time_end = td_current_sec(); + proj_reconst (*imGlobal, rsGlobal, opt_filter, opt_filter_param, opt_interp, opt_interp_param, opt_backproj, opt_trace); #endif #ifdef HAVE_MPI if (mpiWorld.getRank() == 0) #endif { - raysum_close (rs_global); - double calctime = time_end - time_start; - im_global->arrayDataWrite (); - im_global->labelAdd (Array2dFileLabel::L_HISTORY, rs_global->remark, rs_global->calctime); - im_global->labelAdd (Array2dFileLabel::L_HISTORY, remark, calctime); - im_global->fileClose (); + raysum_close (rsGlobal); + double calctime = timerProgram.timerEnd(); + imGlobal->arrayDataWrite (); + imGlobal->labelAdd (Array2dFileLabel::L_HISTORY, rsGlobal->remark, rsGlobal->calctime); + imGlobal->labelAdd (Array2dFileLabel::L_HISTORY, remark, calctime); + imGlobal->fileClose (); if (opt_verbose) - cout << "Time active = " << calctime << " sec" << endl; + cout << "Run time: " << calctime << " seconds" << endl; } - #ifdef HAVE_MPI - MPI::Finalize(); + MPI::Finalize(); #endif - return (0); + return (0); } + +////////////////////////////////////////////////////////////////////////////////////// +// MPI Support Routines +// +////////////////////////////////////////////////////////////////////////////////////// + #ifdef HAVE_MPI -static void mpi_scatter_rs (MPIWorld& mpiWorld, RAYSUM *rs_global, RAYSUM *rs_local, const int opt_debug) +static void ScatterProjectionsMPI (MPIWorld& mpiWorld, RAYSUM *rsGlobal, RAYSUM *rsLocal, const int opt_debug) { if (mpiWorld.getRank() == 0) { for (int iProc = 0; iProc < mpiWorld.getNumProcessors(); iProc++) { for (int iw = mpiWorld.getStartWorkUnit(iProc); iw <= mpiWorld.getEndWorkUnit(iProc); iw++) { - mpiWorld.getComm().Send(&rs_global->view[iw]->ndet, 1, MPI::INT, iProc, 0); - mpiWorld.getComm().Send(&rs_global->view[iw]->view_angle, 1, MPI::DOUBLE, iProc, 0); - mpiWorld.getComm().Send(rs_global->view[iw]->detval, rs_global->ndet, MPI::FLOAT, iProc, 0); + mpiWorld.getComm().Send(&rsGlobal->view[iw]->ndet, 1, MPI::INT, iProc, 0); + mpiWorld.getComm().Send(&rsGlobal->view[iw]->view_angle, 1, MPI::DOUBLE, iProc, 0); + mpiWorld.getComm().Send(rsGlobal->view[iw]->detval, rsGlobal->ndet, MPI::FLOAT, iProc, 0); } } } for (int iw = 0; iw < mpiWorld.getMyLocalWorkUnits(); iw++) { MPI::Status status; + mpiWorld.getComm().Recv(&rsLocal->view[iw]->ndet, 1, MPI::INT, 0, 0, status); + mpiWorld.getComm().Recv(&rsLocal->view[iw]->view_angle, 1, MPI::DOUBLE, 0, 0, status); + mpiWorld.getComm().Recv(rsLocal->view[iw]->detval, rsLocal->ndet, MPI::FLOAT, 0, 0, status); + } + rsLocal->nview = mpiWorld.getMyLocalWorkUnits(); +} + +static void +ReduceImageMPI (MPIWorld& mpiWorld, ImageFile* imLocal, ImageFile* imGlobal) +{ + ImageFileArray vLocal = imLocal->getArray(); - mpiWorld.getComm().Recv(&rs_local->view[iw]->ndet, 1, MPI::INT, 0, 0, status); - mpiWorld.getComm().Recv(&rs_local->view[iw]->view_angle, 1, MPI::DOUBLE, 0, 0, status); - mpiWorld.getComm().Recv(rs_local->view[iw]->detval, rs_local->ndet, MPI::FLOAT, 0, 0, status); + for (int ix = 0; ix < imLocal->nx(); ix++) { + void *recvbuf = NULL; + if (mpiWorld.getRank() == 0) { + ImageFileArray vGlobal = imGlobal->getArray(); + recvbuf = vGlobal[ix]; + } + mpiWorld.getComm().Reduce (vLocal[ix], recvbuf, imLocal->ny(), imLocal->getMPIDataType(), MPI::SUM, 0); } - rs_local->nview = mpiWorld.getMyLocalWorkUnits(); } #endif + #ifndef NO_MAIN int main (int argc, char* argv[])