From 2451ac413848718a1dd666ce6f6464e974680f47 Mon Sep 17 00:00:00 2001 From: "Kevin M. Rosenberg" Date: Fri, 9 Jun 2000 01:35:33 +0000 Subject: [PATCH] r90: Convert MPI structure to C++ class --- ChangeLog | 10 ++- NEWS | 7 +- TODO | 4 +- include/Makefile.am | 3 +- include/array2d.h | 31 +++++++++ include/ct.h | 59 +++++------------ include/imagefile.h | 14 ++-- include/ir.h | 115 +++----------------------------- include/kmath.h | 126 ++--------------------------------- include/kstddef.h | 6 +- include/mpiworld.h | 75 +++++++++++++++++++++ man/Makefile.am | 2 +- man/ctrec.1 | 15 +++-- man/{sdf-1.1 => if-1.1} | 25 +++---- man/{sdf2img.1 => if2img.1} | 27 ++++---- man/{sdfinfo.1 => ifinfo.1} | 25 +++---- man/{phm2sdf.1 => phm2if.1} | 21 +++--- man/phm2rs.1 | 11 ++-- src/Makefile.am | 7 +- src/ctrec.cpp | 128 ++++++++++++++---------------------- src/mpiworld.cpp | 66 +++++++++++++++++++ src/phm2if.cpp | 105 ++++++++++++----------------- src/phm2rs.cpp | 125 ++++++++++++++--------------------- 23 files changed, 446 insertions(+), 561 deletions(-) create mode 100644 include/mpiworld.h rename man/{sdf-1.1 => if-1.1} (69%) rename man/{sdf2img.1 => if2img.1} (75%) rename man/{sdfinfo.1 => ifinfo.1} (70%) rename man/{phm2sdf.1 => phm2if.1} (81%) create mode 100644 src/mpiworld.cpp diff --git a/ChangeLog b/ChangeLog index a50541a..6b72c05 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,8 +1,11 @@ 0.6.0-b1 - 6/6/2000 First C++ conversions - Portable IF (image file) format implemented to replace SDF + Portable IF (image file) format implemented with objects (SDF removed) + - Now all data files are cross-platform compatible Converted from MPI to MPI++ - + Converted backprojection to object-oriented + Removed MTX from libkmath as no longer need -- replaced with C++ matrices + 0.5.4 - 6/4/2000 Simpilifed endian handling @@ -54,4 +57,5 @@ added MPI support via LAM library 1983-84 - Developed under MS-DOS and IBM EGA graphics \ No newline at end of file + Developed under MS-DOS and IBM EGA graphics + diff --git a/NEWS b/NEWS index 1da3fcb..d10d07d 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,3 @@ -0.5.3 - May 11, 2000 -Numerous bug fixes -Added Microsoft Windows compatibility +Now, CTSim uses C++ and has cross-platform compatible data files. -0.5.0 - April 27, 2000 -This is the first open source release +In the next release, interactive graphics will be added. diff --git a/TODO b/TODO index 6aad0ba..b39cb5e 100644 --- a/TODO +++ b/TODO @@ -4,10 +4,9 @@ MISCELLANEOUS Integrate low-level X11 graphics, replace all low-level driver code in libgraph. All the high-level graphics routines are in place. -Make SDF file format cross-platform compatible - Integrate audio drivers into libcio -- used for the interactive CT display. + PROPOSED MENU STRUCTURE ======================= File @@ -30,6 +29,7 @@ Compare 1D column plots Single Image statistics + PROPOSED HDF FILE FORMAT ======================== diff --git a/include/Makefile.am b/include/Makefile.am index 5cb06e6..065df98 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1,4 +1,5 @@ -noinst_HEADERS=ascii.h cio.h ct.h ezplot.h ir.h keyboard.h kmath.h kstddef.h pol.h sgp.h array2d.h imagefile.h +noinst_HEADERS=ascii.h cio.h ct.h ezplot.h ir.h keyboard.h kmath.h kstddef.h pol.h sgp.h array2d.h imagefile.h backproj.h mpiworld.h + diff --git a/include/array2d.h b/include/array2d.h index 01c2729..30b92d4 100644 --- a/include/array2d.h +++ b/include/array2d.h @@ -1,3 +1,34 @@ +/***************************************************************************** +** FILE IDENTIFICATION +** +** Name: array2d.h +** Purpose: 2-dimension array classes +** Programmer: Kevin Rosenberg +** Date Started: June 2000 +** +** This is part of the CTSim program +** Copyright (C) 1983-2000 Kevin Rosenberg +** +** $Id: array2d.h,v 1.3 2000/06/09 01:35:33 kevin Exp $ +** $Log: array2d.h,v $ +** Revision 1.3 2000/06/09 01:35:33 kevin +** Convert MPI structure to C++ class +** +** +** 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 +** published by the Free Software Foundation. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +******************************************************************************/ + #ifndef ARRAY2D_H #define ARRAY2D_H diff --git a/include/ct.h b/include/ct.h index d43353d..02992b3 100644 --- a/include/ct.h +++ b/include/ct.h @@ -1,39 +1,15 @@ /***************************************************************************** -** This is part of the CTSim program -** Copyright (C) 1983-2000 Kevin Rosenberg -** -** $Id: ct.h,v 1.11 2000/06/07 10:12:09 kevin Exp $ -** $Log: ct.h,v $ -** Revision 1.11 2000/06/07 10:12:09 kevin -** Upgraded from MPI to MPI++ -** -** Revision 1.10 2000/06/07 07:43:39 kevin -** *** empty log message *** -** -** Revision 1.9 2000/06/07 03:49:54 kevin -** *** empty log message *** -** -** Revision 1.8 2000/06/07 02:30:27 kevin -** Added C++ image files -** -** Revision 1.7 2000/06/07 00:59:38 kevin -** added imagefiles -** -** Revision 1.6 2000/05/24 22:48:17 kevin -** First functional version of SDF library for X-window +** FILE IDENTIFICATION ** -** Revision 1.5 2000/05/11 01:04:44 kevin -** Added Microsoft Windows compatibility +** Name: ct.h +** Purpose: Master header file for CTSim +** Programmer: Kevin Rosenberg +** Date Started: Aug 1984 ** -** Revision 1.4 2000/05/03 19:51:41 kevin -** function renaming for phantoms and phantom elements -** -** Revision 1.3 2000/04/30 19:17:35 kevin -** Set up include files for conditional SGP -** -** Revision 1.2 2000/04/28 14:14:16 kevin -** *** empty log message *** +** This is part of the CTSim program +** Copyright (C) 1983-2000 Kevin Rosenberg ** +** $Id: ct.h,v 1.12 2000/06/09 01:35:33 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 @@ -48,9 +24,6 @@ ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ******************************************************************************/ -/*---------------------------------------------------------------------*/ -/* HEADER FILE FOR TOMOGRAPY SYSTEM */ -/*---------------------------------------------------------------------*/ #ifndef CT_H #define CT_H @@ -146,6 +119,7 @@ #ifdef HAVE_MPI #include "mpi++.h" +#include "mpiworld.h" #endif #include "kstddef.h" @@ -158,17 +132,16 @@ #include "sgp.h" #endif -#ifdef __cplusplus - #include - #include +#include +#include - using namespace std; - - #include "array2d.h" - #include "imagefile.h" -#endif +using namespace std; +#include "array2d.h" +#include "imagefile.h" #include "ir.h" +#include "backproj.h" + #endif diff --git a/include/imagefile.h b/include/imagefile.h index 3c1bb9a..19f5db0 100644 --- a/include/imagefile.h +++ b/include/imagefile.h @@ -233,6 +233,7 @@ template Array2dFile::~Array2dFile (void) { fileClose (); + delete array; } @@ -240,11 +241,10 @@ template void Array2dFile::fileClose (void) { - headerWrite (); - if (file_id >= 0 && array != NULL) { - arrayDataWrite (); - close (file_id); - file_id = -1; + if (file_id >= 0) { + headerWrite (); + close (file_id); + file_id = -1; } } @@ -434,7 +434,7 @@ Array2dFile::arrayDataWrite (void) for (unsigned int ix = 0; ix < mNX; ix++) for (unsigned int iy = 0; iy < mNY; iy++) { T value = array->array_data[ix][iy]; - ConvertNetworkOrder (&value, sizeof(T)); + ConvertReverseNetworkOrder (&value, sizeof(T)); write (file_id, &value, mPixelSize); } @@ -455,7 +455,7 @@ Array2dFile::arrayDataRead (void) for (int ix = 0; ix < mNX; ix++) for (unsigned int iy = 0; iy < mNY; iy++) { read (file_id, &pixelBuffer, mPixelSize); - ConvertNetworkOrder (&pixelBuffer, sizeof(T)); + ConvertReverseNetworkOrder (&pixelBuffer, sizeof(T)); array->array_data[ix][iy] = pixelBuffer; } diff --git a/include/ir.h b/include/ir.h index e1661db..cadc91b 100644 --- a/include/ir.h +++ b/include/ir.h @@ -1,78 +1,15 @@ /***************************************************************************** -** This is part of the CTSim program -** Copyright (C) 1983-2000 Kevin Rosenberg -** -** $Id: ir.h,v 1.23 2000/06/07 10:12:09 kevin Exp $ -** $Log: ir.h,v $ -** Revision 1.23 2000/06/07 10:12:09 kevin -** Upgraded from MPI to MPI++ -** -** Revision 1.22 2000/06/07 07:43:39 kevin -** *** empty log message *** -** -** Revision 1.21 2000/06/07 03:49:54 kevin -** *** empty log message *** -** -** Revision 1.20 2000/06/07 02:30:27 kevin -** Added C++ image files -** -** Revision 1.19 2000/06/07 00:59:38 kevin -** added imagefiles -** -** Revision 1.18 2000/06/05 01:32:45 kevin -** Added C++ compatibility -** -** Revision 1.17 2000/06/03 06:29:08 kevin -** *** empty log message *** -** -** Revision 1.16 2000/05/24 22:48:17 kevin -** First functional version of SDF library for X-window -** -** Revision 1.15 2000/05/16 04:33:17 kevin -** Updated documentation -** -** Revision 1.14 2000/05/11 14:07:00 kevin -** Added support for Windows NT -** -** Revision 1.13 2000/05/08 20:00:48 kevin -** ANSI C changes -** -** Revision 1.12 2000/05/07 12:46:19 kevin -** made c++ compatible -** -** Revision 1.11 2000/05/05 02:37:31 kevin -** renamed phmelm to pelm -** -** Revision 1.10 2000/05/04 18:16:34 kevin -** renamed filter definitions -** -** Revision 1.9 2000/05/04 04:29:18 kevin -** *** empty log message *** -** -** Revision 1.8 2000/05/04 04:25:55 kevin -** Renamed phantom and phantom-element functions/variables +** FILE IDENTIFICATION ** -** Revision 1.7 2000/05/03 19:51:41 kevin -** function renaming for phantoms and phantom elements +** Name: ir.h +** Purpose: Master Image Reconstruction Header +** Programmer: Kevin Rosenberg +** Date Started: July 1, 1984 ** -** Revision 1.6 2000/05/03 08:49:49 kevin -** Code cleanup -** -** Revision 1.5 2000/05/02 20:00:25 kevin -** *** empty log message *** -** -** Revision 1.4 2000/05/02 15:31:39 kevin -** code cleaning -** -** Revision 1.3 2000/04/29 23:24:29 kevin -** *** empty log message *** -** -** Revision 1.2 2000/04/28 14:14:16 kevin -** *** empty log message *** -** -** Revision 1.1.1.1 2000/04/28 13:02:43 kevin -** Initial CVS import for first public release +** This is part of the CTSim program +** Copyright (C) 1983-2000 Kevin Rosenberg ** +** $Id: ir.h,v 1.24 2000/06/09 01:35:33 kevin Exp $ ** ** ** This program is free software; you can redistribute it and/or modify @@ -89,11 +26,6 @@ ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ******************************************************************************/ -/* ir.h Header File for Image Reconstruction System - * Programmer: Kevin Rosenberg - * Date Started: 7-1-84 - */ - #ifndef IR_H #define IR_H @@ -351,28 +283,6 @@ const static int RAYSUM_TRACE_ROW_ATTEN=18; * FUNCTION DECLARATIONS ************************************************************************/ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#ifdef HAVE_MPI -#define CT_MPI_MAX_PROCESS 128 -struct mpi_ct_st -{ - int my_rank; - int nproc; - int base_local_work_units; - int remainder_work_units; - int local_work_units [CT_MPI_MAX_PROCESS]; - int start_work_unit [CT_MPI_MAX_PROCESS]; - MPI::Intracomm comm; -}; - -extern struct mpi_ct_st mpi_ct; -void mpi_ct_calc_work_units(const unsigned int global_work_units); -#endif - - /* convolve.c */ double convolve (const double f1[], const double f2[], const double dx, const int n, const int np, const FunctionSymmetry func_type); double convolve_both (const double f1[], const double f2[], const double dx, const int n, const int np); @@ -435,7 +345,7 @@ int raysum_collect(RAYSUM *rs, const DETECTOR *det, const PHANTOM *phm, const in void rayview(const PHANTOM *phm, DETARRAY *darray, const DETECTOR *det, const double xd1, const double yd1, const double xd2, const double yd2, const double xs1, const double ys1, const double xs2, const double ys2, const int unit_pulse); double phm_ray_attenuation (const PHANTOM *phm, const double x1, const double y1, const double x2, const double y2); double pelm_ray_attenuation (PELM *pelm, const double x1, const double y1, const double x2, const double y2); -int pelm_clip_line (const PELM *pelm, double *x1, double *y1, double *x2, double *y2); +int pelm_clip_line (const PELM *pelm, double& x1, double& y1, double& x2, double& y2); void raysum_trace_show_param (const char *label, const char *fmt, int row, int color, ...); /* scanner.c */ @@ -460,9 +370,6 @@ int detarray_read(RAYSUM *rs, DETARRAY *darray, const int view_num); int detarray_write(RAYSUM *rs, const DETARRAY *darray, const int view_num); int raysum_print(const RAYSUM *rs); -#ifdef __cplusplus -} - /* From phm2image.cpp */ void phm_to_imagefile (const PHANTOM *phm, ImageFile& im, const int col_start, const int col_count, const int nsample, const int trace); int pelm_is_point_inside(PELM *obj, const double x, const double y, const CoordType coord_type); @@ -505,8 +412,4 @@ int backproj_calc_id2 (const RAYSUM *rs, ImageFile& im, const double *t, const double view_angle, const int interp_type); void backproj_term_id2 (const RAYSUM *rs, ImageFile& im); - -#endif /* __cplusplus */ - - #endif diff --git a/include/kmath.h b/include/kmath.h index 5bac1be..ed8de01 100644 --- a/include/kmath.h +++ b/include/kmath.h @@ -2,8 +2,11 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2000 Kevin Rosenberg ** -** $Id: kmath.h,v 1.10 2000/06/07 00:59:38 kevin Exp $ +** $Id: kmath.h,v 1.11 2000/06/09 01:35:33 kevin Exp $ ** $Log: kmath.h,v $ +** Revision 1.11 2000/06/09 01:35:33 kevin +** Convert MPI structure to C++ class +** ** Revision 1.10 2000/06/07 00:59:38 kevin ** added imagefiles ** @@ -78,111 +81,9 @@ extern "C" { #define ASSUMEDZERO 1E-10 -/* codes for C data types */ - -#define DT_CHAR 1 -#define DT_INT 2 -#define DT_LONG 3 -#define DT_FLOAT 4 -#define DT_DOUBLE 5 -#define DT_UINT32 6 -#define DT_STRING 7 - -typedef char *CMTX_1D; -typedef CMTX_1D *CMTX_2D; -typedef CMTX_2D *CMTX_3D; - -typedef int *IMTX_1D; -typedef IMTX_1D *IMTX_2D; -typedef IMTX_2D *IMTX_3D; - -typedef float *FMTX_1D; -typedef FMTX_1D *FMTX_2D; -typedef FMTX_2D *FMTX_3D; - -typedef double *DMTX_1D; -typedef DMTX_1D *DMTX_2D; -typedef DMTX_2D *DMTX_3D; - typedef double GRFMTX_2D[3][3]; typedef double GRFMTX_3D[4][4]; -union elem_val_un { /* holds an element value */ - char c; - int i; - long int l; - float f; - double d; -}; - -typedef union elem_val_un MTX_ELEM_VAL; - - -union elem_ptr_un { /* holds a pointer to a 1D vector of any type */ - char *c; - int *i; - long int *l; - float *f; - double *d; -}; - -typedef union elem_ptr_un MTX_1D; -typedef MTX_1D *MTX_2D; -typedef MTX_2D *MTX_3D; - -union mtx_val_ptr_un { /* pointer to matrix values */ - MTX_1D m1; - MTX_2D m2; - MTX_3D m3; -}; - -typedef union mtx_val_ptr_un MTX_PTR; - -struct matrix_st { - unsigned int order; /* order, or dimension, of matrix */ - unsigned int elemtype; /* element type */ - unsigned int elemsize; /* size of element in bytes */ - unsigned int nx, ny, nz; /* size of matrix in each dimension */ - MTX_PTR val; /* pointer to matrix values */ -}; - -typedef struct matrix_st MTX; -typedef struct matrix_st *MTXP; - -/* DEFINITION IDENTIFICATION - * - * Definitions to access a matrix element from an matrix - * - -#define me1(mtx,x)\ - (mtx->elemtype == DT_FLOAT ? mtx->val.m1.f[x] :\ - (mtx->elemtype == DT_DOUBLE ? mtx->val.m1.d[x] :\ - (mtx->elemtype == DT_INT ? mtx->val.m1.i[x] :\ - (mtx->elemtype == DT_LONG ? mtx->val.m1.l[x] :\ - (mtx->elemtype == DT_CHAR ? mtx->val.m1.c[x] :\ - 0\ - ))))) - -#define me2(mtx,x,y)\ - (mtx->elemtype == DT_FLOAT ? mtx->val.m2[x].f[y] :\ - (mtx->elemtype == DT_DOUBLE ? mtx->val.m2[x].d[y] :\ - (mtx->elemtype == DT_INT ? mtx->val.m2[x].i[y] :\ - (mtx->elemtype == DT_LONG ? mtx->val.m2[x].l[y] :\ - (mtx->elemtype == DT_CHAR ? mtx->val.m2[x].c[y] :\ - 0\ - ))))) - - -#define me3(mtx,x,y,z)\ - (mtx->elemtype == DT_FLOAT ? mtx->val.m3[x][y].f[z] :\ - (mtx->elemtype == DT_DOUBLE ? mtx->val.m3[x][y].d[z] :\ - (mtx->elemtype == DT_INT ? mtx->val.m3[x][y].i[z] :\ - (mtx->elemtype == DT_LONG ? mtx->val.m3[x][y].l[z] :\ - (mtx->elemtype == DT_CHAR ? mtx->val.m3[x][y].c[z] :\ - 0\ - ))))) -*/ - /* clip.c */ int clip_rect(double *x1, double *y1, double *x2, double *y2, const double rect[4]); int clip_segment(double *x1, double *y1, double *x2, double *y2, const double u, const double v); @@ -197,25 +98,6 @@ long int lnearest(double x); double fmax(const double a, const double b); void minmax_dvector(const double array[], const int pts, double *xmin, double *xmax); -/* mtx_disp.c */ -void mtx_show(const MTX *mtx); -void mtx_prt(const MTX *mtx, FILE *fp); -int mtx_prt_elem(const MTX *mtx, FILE *fp, unsigned int x, unsigned int y, unsigned int z); - -/* mtx_elem.c */ -int mtx_get_elem(const MTX *mtx, MTX_ELEM_VAL *me, const int x, const int y, const int z); -int mtx_put_elem(MTX *mtx, const MTX_ELEM_VAL *me, unsigned int x, unsigned int y, unsigned int z); - -/* mtx_inp.c */ -int mtx_inp_elem(const char *prompt, MTX_ELEM_VAL *mev, const int dtype); - -/* mtx_main.c */ -MTX *mtx_init(const unsigned int order, const unsigned int elem_type, const unsigned int nx, const unsigned int ny, const unsigned int nz); -MTX *mtx_clr(MTX *mtx); -int mtx_free(MTX *mtx); -int mtx_elem_size(const int dt); -int mtx_check(const MTX *mtx, const char *func_name); - /* norm_ang.c */ double norm_ang(double theta); diff --git a/include/kstddef.h b/include/kstddef.h index 917e59d..00fbddd 100644 --- a/include/kstddef.h +++ b/include/kstddef.h @@ -2,8 +2,11 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2000 Kevin Rosenberg ** -** $Id: kstddef.h,v 1.14 2000/06/07 03:49:54 kevin Exp $ +** $Id: kstddef.h,v 1.15 2000/06/09 01:35:33 kevin Exp $ ** $Log: kstddef.h,v $ +** Revision 1.15 2000/06/09 01:35:33 kevin +** Convert MPI structure to C++ class +** ** Revision 1.14 2000/06/07 03:49:54 kevin ** *** empty log message *** ** @@ -318,6 +321,7 @@ int write_nfloat32 (float const *f, int fd); int read_nfloat64 (double *d, int fd); int write_nfloat64 (double const *d, int fd); void ConvertNetworkOrder (void* buffer, size_t bytes); +void ConvertReverseNetworkOrder (void* buffer, size_t bytes); #ifdef __cplusplus } diff --git a/include/mpiworld.h b/include/mpiworld.h new file mode 100644 index 0000000..74042b3 --- /dev/null +++ b/include/mpiworld.h @@ -0,0 +1,75 @@ +/***************************************************************************** +** FILE IDENTIFICATION +** +** Name: mpiworld.h +** Purpose: MPIWorld classes +** Programmer: Kevin Rosenberg +** Date Started: June 6, 2000 +** +** This is part of the CTSim program +** Copyright (C) 1983-2000 Kevin Rosenberg +** +** $id$ +** +** 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 +** published by the Free Software Foundation. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +******************************************************************************/ + +#include +#include + + +class MPIWorld +{ + public: + MPIWorld (int& argc, char**& argv); + + void setTotalWorkUnits (int totalUnits); + + int getRank (void) const + { return m_myRank; } + + int getNumProcessors (void) const + { return m_nProcessors; } + + int getStartWorkUnit (int rank) const + { return m_vStartWorkUnit [rank]; } + + int getEndWorkUnit (int rank) const + { return m_vEndWorkUnit [rank]; } + + int getLocalWorkUnits (int rank) const + { return m_vLocalWorkUnits [rank]; } + + int getMyStartWorkUnit (void) const + { return m_vStartWorkUnit [m_myRank]; } + + int getMyEndWorkUnit (void) const + { return m_vEndWorkUnit [m_myRank]; } + + int getMyLocalWorkUnits (void) const + { return m_vLocalWorkUnits [m_myRank]; } + + MPI::Intracomm getComm() + { return m_comm; } + +private: + int m_myRank; + int m_nProcessors; + vector m_vLocalWorkUnits; + vector m_vStartWorkUnit; + vector m_vEndWorkUnit; + MPI::Intracomm m_comm; +}; + + diff --git a/man/Makefile.am b/man/Makefile.am index 286439f..18b5ae4 100644 --- a/man/Makefile.am +++ b/man/Makefile.am @@ -1,3 +1,3 @@ -man_MANS=ctrec.1 phm2rs.1 phm2sdf.1 sdf2img.1 sdfinfo.1 sdf-1.1 +man_MANS=ctrec.1 phm2rs.1 phm2if.1 if2img.1 ifinfo.1 if-1.1 info_INFO=ctsim.texi EXTRA_DIST = $(man_MANS) $(info_INFO) diff --git a/man/ctrec.1 b/man/ctrec.1 index 995e818..5a8f642 100644 --- a/man/ctrec.1 +++ b/man/ctrec.1 @@ -4,8 +4,11 @@ .\" .\" Author: Kevin Rosenberg .\" -.\" $Id: ctrec.1,v 1.2 2000/05/03 08:43:46 kevin Exp $ +.\" $Id: ctrec.1,v 1.3 2000/06/09 01:35:33 kevin Exp $ .\" $Log: ctrec.1,v $ +.\" Revision 1.3 2000/06/09 01:35:33 kevin +.\" Convert MPI structure to C++ class +.\" .\" Revision 1.2 2000/05/03 08:43:46 kevin .\" *** empty log message *** .\" @@ -21,7 +24,7 @@ .Sh DESCRIPTION .Nm reconstucts image data from raysum projections collected by CT scanner. It uses -.Xr rs 1 +.Xr phm2rs 1 for projection data generation. .Pp .Nm @@ -55,8 +58,8 @@ Kevin Rosenberg, M.D. .Nm was first written in 1983 using MS-DOS and an EGA display adapter. In 1999 it was ported to GNU/Linux. .Sh SEE ALSO -.Xr phm2sdf 1 , +.Xr phm2if 1 , .Xr phm2rs 1 , -.Xr rs2sdf 1 , -.Xr sdf2img 1 , -.Xr sdfinfo 1 \ No newline at end of file +.Xr rs2if 1 , +.Xr if2img 1 , +.Xr ifinfo 1 \ No newline at end of file diff --git a/man/sdf-1.1 b/man/if-1.1 similarity index 69% rename from man/sdf-1.1 rename to man/if-1.1 index 3a2c615..919dae7 100644 --- a/man/sdf-1.1 +++ b/man/if-1.1 @@ -1,27 +1,30 @@ .\" -*- nroff -*- .\" -.\" sdf-1.1 +.\" if-1.1 .\" .\" Author: Kevin Rosenberg .\" -.\" $Id: sdf-1.1,v 1.1 2000/05/03 08:43:46 kevin Exp $ -.\" $Log: sdf-1.1,v $ +.\" $Id: if-1.1,v 1.1 2000/06/09 01:35:33 kevin Exp $ +.\" $Log: if-1.1,v $ +.\" Revision 1.1 2000/06/09 01:35:33 kevin +.\" Convert MPI structure to C++ class +.\" .\" Revision 1.1 2000/05/03 08:43:46 kevin .\" *** empty log message *** .\" .\" .Dd April 19, 2000 -.Dt SDF-1 1 +.Dt IF-1 1 .Os .Sh NAME -.Nm sdf-1 -.Nd Single SDF (Standard Data File) Transformation +.Nm if-1 +.Nd Single IF (Image File) Transformation .Sh SYNOPSIS -.Nm sdf-1 sdffile outfile [OPTIONS] +.Nm if-1 iffile outfile [OPTIONS] .Sh DESCRIPTION .Pp .Nm -Transforms a single SDF file. +Transforms a single IF file. .Pp The options are as follows: .Bl -tag -width Ds @@ -47,6 +50,6 @@ was first written in 1983 using MS-DOS and an EGA display adapter. In 1999 it wa .Sh SEE ALSO .Xr ctrec 1 , .Xr phm2rs 1 , -.Xr phm2sdf 1 , -.Xr rs2sdf 1 , -.Xr sdfinfo 1 \ No newline at end of file +.Xr phm2if 1 , +.Xr rs2if 1 , +.Xr ifinfo 1 \ No newline at end of file diff --git a/man/sdf2img.1 b/man/if2img.1 similarity index 75% rename from man/sdf2img.1 rename to man/if2img.1 index 60a9d07..5d807db 100644 --- a/man/sdf2img.1 +++ b/man/if2img.1 @@ -1,27 +1,30 @@ .\" -*- nroff -*- .\" -.\" sdf2img.1 +.\" if2img.1 .\" .\" Author: Kevin Rosenberg .\" -.\" $Id: sdf2img.1,v 1.2 2000/05/03 08:43:46 kevin Exp $ -.\" $Log: sdf2img.1,v $ +.\" $Id: if2img.1,v 1.1 2000/06/09 01:35:33 kevin Exp $ +.\" $Log: if2img.1,v $ +.\" Revision 1.1 2000/06/09 01:35:33 kevin +.\" Convert MPI structure to C++ class +.\" .\" Revision 1.2 2000/05/03 08:43:46 kevin .\" *** empty log message *** .\" .\" .Dd April 19, 2000 -.Dt SDF2IMG 1 +.Dt IF2IMG 1 .Os .Sh NAME -.Nm sdf2img -.Nd SDF (Standard Data File) to Image +.Nm if2img +.Nd IF (Image File) to Image .Sh SYNOPSIS -.Nm sdf2img sdffile outfile [OPTIONS] +.Nm if2img iffile outfile [OPTIONS] .Sh DESCRIPTION .Pp .Nm -converts an 2D SDF file to a viewable image file. +converts an 2D IF file to a viewable image file. .Pp The options are as follows: .Bl -tag -width Ds @@ -40,7 +43,7 @@ Set maximum intensity of window (overrides --auto) .It Fl Fl stats Print image statistics .It Fl Fl labels -Print SDF labels +Print IF labels .It Fl Fl debug Set debug mode .It Fl Fl verbose @@ -57,6 +60,6 @@ was first written in 1983 using MS-DOS and an EGA display adapter. In 1999 it wa .Sh SEE ALSO .Xr ctrec 1 , .Xr phm2rs 1 , -.Xr phm2sdf 1 , -.Xr rs2sdf 1 , -.Xr sdfinfo 1 \ No newline at end of file +.Xr phm2if 1 , +.Xr rs2if 1 , +.Xr ifinfo 1 \ No newline at end of file diff --git a/man/sdfinfo.1 b/man/ifinfo.1 similarity index 70% rename from man/sdfinfo.1 rename to man/ifinfo.1 index 253a29b..d06caff 100644 --- a/man/sdfinfo.1 +++ b/man/ifinfo.1 @@ -1,27 +1,30 @@ .\" -*- nroff -*- .\" -.\" sdf2info.1 +.\" if2info.1 .\" .\" Author: Kevin Rosenberg .\" -.\" $Id: sdfinfo.1,v 1.2 2000/05/03 08:43:46 kevin Exp $ -.\" $Log: sdfinfo.1,v $ +.\" $Id: ifinfo.1,v 1.1 2000/06/09 01:35:33 kevin Exp $ +.\" $Log: ifinfo.1,v $ +.\" Revision 1.1 2000/06/09 01:35:33 kevin +.\" Convert MPI structure to C++ class +.\" .\" Revision 1.2 2000/05/03 08:43:46 kevin .\" *** empty log message *** .\" .\" .Dd April 19, 2000 -.Dt SDF2INFO 1 +.Dt IF2INFO 1 .Os .Sh NAME -.Nm sdfinfo -.Nd Print SDF (Standard Data File) Information +.Nm ifinfo +.Nd Print IF (Image File) Information .Sh SYNOPSIS -.Nm sdfinfo sdffile [OPTIONS] +.Nm ifinfo iffile [OPTIONS] .Sh DESCRIPTION .Pp .Nm -prints information about an SDF file +prints information about an IF file .Pp The options are as follows: .Bl -tag -width Ds @@ -49,6 +52,6 @@ was first written in 1983 using MS-DOS and an EGA display adapter. In 1999 it wa .Sh SEE ALSO .Xr ctrec 1 , .Xr phm2rs 1 , -.Xr phm2sdf 1 , -.Xr rs2sdf 1 , -.Xr sdf2img 1 \ No newline at end of file +.Xr phm2if 1 , +.Xr rs2if 1 , +.Xr if2img 1 \ No newline at end of file diff --git a/man/phm2sdf.1 b/man/phm2if.1 similarity index 81% rename from man/phm2sdf.1 rename to man/phm2if.1 index 0bc74c5..eeea25f 100644 --- a/man/phm2sdf.1 +++ b/man/phm2if.1 @@ -1,23 +1,26 @@ .\" -*- nroff -*- .\" -.\" phm2sdf.1 +.\" phm2if.1 .\" .\" Author: Kevin Rosenberg .\" -.\" $Id: phm2sdf.1,v 1.2 2000/05/03 08:43:46 kevin Exp $ -.\" $Log: phm2sdf.1,v $ +.\" $Id: phm2if.1,v 1.1 2000/06/09 01:35:33 kevin Exp $ +.\" $Log: phm2if.1,v $ +.\" Revision 1.1 2000/06/09 01:35:33 kevin +.\" Convert MPI structure to C++ class +.\" .\" Revision 1.2 2000/05/03 08:43:46 kevin .\" *** empty log message *** .\" .\" .Dd April 19, 2000 -.Dt PHM2SDF 1 +.Dt PHM2IF 1 .Os .Sh NAME -.Nm phm2sdf +.Nm phm2if .Nd Generate Phantom (generate phantom for computed tomography simulator) .Sh SYNOPSIS -.Nm phm2sdf outfile nx ny [--phantom phantom-name] [--picfile filename] [OPTIONS] +.Nm phm2if outfile nx ny [--phantom phantom-name] [--picfile filename] [OPTIONS] .Sh DESCRIPTION .Nm generates phantom images for comparisons to reconstructions for CTsim. @@ -59,7 +62,7 @@ Kevin Rosenberg, M.D. .Nm was first written in 1983 using MS-DOS and an EGA display adapter. In 1999 it was ported to GNU/Linux. .Sh SEE ALSO -.Xr rs2sdf 1 , +.Xr rs2if 1 , .Xr ctrec 1 , -.Xr sdf2img 1 , -.Xr sdfstats 1 \ No newline at end of file +.Xr if2img 1 , +.Xr ifstats 1 \ No newline at end of file diff --git a/man/phm2rs.1 b/man/phm2rs.1 index c0a1064..2e377bb 100644 --- a/man/phm2rs.1 +++ b/man/phm2rs.1 @@ -4,8 +4,11 @@ .\" .\" Author: Kevin Rosenberg .\" -.\" $Id: phm2rs.1,v 1.2 2000/05/03 08:43:46 kevin Exp $ +.\" $Id: phm2rs.1,v 1.3 2000/06/09 01:35:33 kevin Exp $ .\" $Log: phm2rs.1,v $ +.\" Revision 1.3 2000/06/09 01:35:33 kevin +.\" Convert MPI structure to C++ class +.\" .\" Revision 1.2 2000/05/03 08:43:46 kevin .\" *** empty log message *** .\" @@ -53,7 +56,7 @@ Kevin Rosenberg, M.D. was fiphm2rst written in 1983 using MS-DOS and an EGA display adapter. In 1999 it was ported to GNU/Linux. .Sh SEE ALSO .Xr ctrec 1 , -.Xr phm2sdf 1 , +.Xr phm2if 1 , .Xr rs2img 1 , -.Xr sdf2img 1 , -.Xr sdfinfo 1 \ No newline at end of file +.Xr if2img 1 , +.Xr ifinfo 1 \ No newline at end of file diff --git a/src/Makefile.am b/src/Makefile.am index 61ef42b..8420182 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ bin_PROGRAMS = ctsim ctrec phm2rs rs2if @lamprograms@ ifinfo phm2if if-1 if-2 i bin_SCRIPTS = sample-ctrec.sh EXTRA_PROGRAMS = ctrec-lam phm2rs-lam phm2if-lam INCLUDES=@my_includes@ -EXTRA_DIST=Makefile.nt +EXTRA_DIST=Makefile.nt mpiworld.cpp ctsim_SOURCES = ctsim.cpp ctsim_LDADD = @ctlibs@ @@ -30,9 +30,12 @@ phm2if_lam_LDADD=@ctlamlibs@ phm2rs_lam_SOURCES=phm2rs.cpp phm2rs_lam_LDADD=@ctlamlibs@ +realclean: + rm -f *.pgm *.if *~ *.rs + if USE_LAM CC_LAM = $(lamdir)/bin/balky -LAM_EXTRA_SRC = ../libir/mpi_ct.cpp +LAM_EXTRA_SRC = mpiworld.cpp ctrec-lam: ctrec.cpp $(CC_LAM) @DEFS@ $(CFLAGS) $(INCLUDES) -DHAVE_MPI ctrec.cpp -o ctrec-lam $(LDFLAGS) $(LAM_EXTRA_SRC) @ctlibs@ diff --git a/src/ctrec.cpp b/src/ctrec.cpp index fed86ee..68b9ff6 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.4 2000/06/08 16:43:10 kevin Exp $ +** $Id: ctrec.cpp,v 1.5 2000/06/09 01:35:33 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 @@ -92,13 +92,13 @@ ctrec_usage (const char *program) #ifdef HAVE_MPI -static void mpi_scatter_rs (RAYSUM *rs_global, RAYSUM *rs_local, const int debug); +static void mpi_scatter_rs (MPIWorld& mpiWorld, RAYSUM *rs_global, RAYSUM *rs_local, const int debug); #endif static void print_raysum_info(const RAYSUM *rs); int -ctrec_main (const int argc, char *const argv[]) +ctrec_main (int argc, char * argv[]) { ImageFile *im_global = NULL; RAYSUM *rs_global = NULL; @@ -119,22 +119,10 @@ ctrec_main (const int argc, char *const argv[]) #ifdef HAVE_MPI ImageFile *im_local; RAYSUM *rs_local; - int mpi_argc = argc; - char **mpi_argv = (char **) argv; int mpi_nview, mpi_ndet; double mpi_detinc, mpi_rotinc, mpi_phmlen; double mpi_t1, mpi_t2, mpi_t, mpi_t_g; - - MPI::Init (mpi_argc, mpi_argv); - mpi_ct.comm = MPI::COMM_WORLD.Dup(); - mpi_ct.nproc = mpi_ct.comm.Get_size(); - mpi_ct.my_rank = mpi_ct.comm.Get_rank(); - - if (mpi_ct.nproc > CT_MPI_MAX_PROCESS) { - sys_error(ERR_FATAL, "Number of mpi processes (%d) exceeds max processes (%d)", - mpi_ct.nproc, CT_MPI_MAX_PROCESS); - exit(1); - } + MPIWorld mpiWorld (argc, argv); #endif #ifdef HAVE_MPI @@ -144,7 +132,7 @@ ctrec_main (const int argc, char *const argv[]) #endif #ifdef HAVE_MPI - if (mpi_ct.my_rank == 0) { + if (mpiWorld.getRank() == 0) { #endif while (1) { int c = getopt_long(argc, argv, "", my_options, NULL); @@ -236,7 +224,7 @@ ctrec_main (const int argc, char *const argv[]) #endif #ifdef HAVE_MPI - if (mpi_ct.my_rank == 0) { + if (mpiWorld.getRank() == 0) { rs_global = raysum_open (rs_name); raysum_read (rs_global); if (opt_verbose) @@ -250,32 +238,32 @@ ctrec_main (const int argc, char *const argv[]) } mpi_t1 = MPI::Wtime(); - mpi_ct.comm.Bcast (&opt_verbose, 1, MPI::INT, 0); - mpi_ct.comm.Bcast (&opt_debug, 1, MPI::INT, 0); - mpi_ct.comm.Bcast (&opt_trace, 1, MPI::INT, 0); - mpi_ct.comm.Bcast (&opt_filter, 1, MPI::INT, 0); - mpi_ct.comm.Bcast (&opt_interp, 1, MPI::INT, 0); - mpi_ct.comm.Bcast (&opt_filter_param, 1, MPI::DOUBLE, 0); - mpi_ct.comm.Bcast (&opt_interp_param, 1, MPI::INT, 0); - mpi_ct.comm.Bcast (&opt_backproj, 1, MPI::INT, 0); - mpi_ct.comm.Bcast (&mpi_ndet, 1, MPI::INT, 0); - mpi_ct.comm.Bcast (&mpi_nview, 1, MPI::INT, 0); - mpi_ct.comm.Bcast (&mpi_detinc, 1, MPI::DOUBLE, 0); - mpi_ct.comm.Bcast (&mpi_phmlen, 1, MPI::DOUBLE, 0); - mpi_ct.comm.Bcast (&mpi_rotinc, 1, MPI::DOUBLE, 0); - mpi_ct.comm.Bcast (&nx, 1, MPI::INT, 0); - mpi_ct.comm.Bcast (&ny, 1, MPI::INT, 0); + 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); + mpiWorld.getComm().Bcast (&opt_filter, 1, MPI::INT, 0); + mpiWorld.getComm().Bcast (&opt_interp, 1, MPI::INT, 0); + mpiWorld.getComm().Bcast (&opt_filter_param, 1, MPI::DOUBLE, 0); + mpiWorld.getComm().Bcast (&opt_interp_param, 1, MPI::INT, 0); + mpiWorld.getComm().Bcast (&opt_backproj, 1, MPI::INT, 0); + mpiWorld.getComm().Bcast (&mpi_ndet, 1, MPI::INT, 0); + mpiWorld.getComm().Bcast (&mpi_nview, 1, MPI::INT, 0); + mpiWorld.getComm().Bcast (&mpi_detinc, 1, MPI::DOUBLE, 0); + mpiWorld.getComm().Bcast (&mpi_phmlen, 1, MPI::DOUBLE, 0); + 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; - mpi_ct.comm.Reduce(&mpi_t, &mpi_t_g, 1, MPI::DOUBLE, MPI::MAX, 0); - if (mpi_ct.my_rank == 0) + 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); } - mpi_ct_calc_work_units(mpi_nview); + mpiWorld.setTotalWorkUnits (mpi_nview); - rs_local = raysum_create (NULL, mpi_ct.local_work_units[mpi_ct.my_rank], mpi_ndet); + rs_local = raysum_create (NULL, mpiWorld.getMyLocalWorkUnits(), mpi_ndet); rs_local->ndet = mpi_ndet; rs_local->nview = mpi_nview; @@ -285,16 +273,16 @@ ctrec_main (const int argc, char *const argv[]) if (opt_verbose) mpi_t1 = MPI::Wtime(); - mpi_scatter_rs(rs_global, rs_local, opt_debug); + mpi_scatter_rs(mpiWorld, rs_global, rs_local, opt_debug); if (opt_verbose) { mpi_t2 = MPI::Wtime(); mpi_t = mpi_t2 - mpi_t1; - mpi_ct.comm.Reduce(&mpi_t, &mpi_t_g, 1, MPI::DOUBLE, MPI::MAX, 0); - if (mpi_ct.my_rank == 0) + 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); } - if (mpi_ct.my_rank == 0) { + if (mpiWorld.getRank() == 0) { im_global = new ImageFile (im_filename, nx, ny); im_global->adf.fileCreate(); } @@ -317,8 +305,8 @@ ctrec_main (const int argc, char *const argv[]) mpi_t2 = MPI::Wtime(); mpi_t = mpi_t2 - mpi_t1; - mpi_ct.comm.Reduce(&mpi_t, &mpi_t_g, 1, MPI::DOUBLE, MPI::MAX, 0); - if (mpi_ct.my_rank == 0 && opt_verbose) + 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, @@ -333,26 +321,26 @@ ctrec_main (const int argc, char *const argv[]) int nyLocal = im_local->adf.ny(); ImageFileArray vLocal = im_local->getArray(); ImageFileArray vGlobal = NULL; - if (mpi_ct.my_rank == 0) + if (mpiWorld.getRank() == 0) vGlobal = im_global->getArray(); for (int ix = 0; ix < nxLocal; ix++) { void *recvbuf = NULL; - if (mpi_ct.my_rank == 0) + if (mpiWorld.getRank() == 0) recvbuf = vGlobal[ix]; - mpi_ct.comm.Reduce(vLocal[ix], recvbuf, nyLocal, im_local->getMPIDataType(), MPI::SUM, 0); + 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; - mpi_ct.comm.Reduce (&mpi_t, &mpi_t_g, 1, MPI::DOUBLE, MPI::MAX, 0); - if (mpi_ct.my_rank == 0) + 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 (mpi_ct.my_rank == 0) + if (mpiWorld.getRank() == 0) time_end = MPI::Wtime(); #else time_end = td_current_sec(); @@ -360,7 +348,7 @@ ctrec_main (const int argc, char *const argv[]) #ifdef HAVE_MPI - if (mpi_ct.my_rank == 0) + if (mpiWorld.getRank() == 0) #endif { raysum_close (rs_global); @@ -382,40 +370,26 @@ ctrec_main (const int argc, char *const argv[]) #ifdef HAVE_MPI -static void mpi_scatter_rs (RAYSUM *rs_global, RAYSUM *rs_local, const int opt_debug) +static void mpi_scatter_rs (MPIWorld& mpiWorld, RAYSUM *rs_global, RAYSUM *rs_local, const int opt_debug) { - int iproc; - int end_work_unit; - int iw = 0; - - if (mpi_ct.my_rank == 0) { - for (iproc = 0; iproc < mpi_ct.nproc; iproc++) { - end_work_unit = mpi_ct.start_work_unit[iproc] + mpi_ct.local_work_units[iproc] - 1; - - for (iw = mpi_ct.start_work_unit[iproc]; iw <= end_work_unit; iw++) { - mpi_ct.comm.Send(&rs_global->view[iw]->ndet, 1, MPI::INT, iproc, 0); - mpi_ct.comm.Send(&rs_global->view[iw]->view_angle, 1, MPI::DOUBLE, iproc, 0); - mpi_ct.comm.Send(rs_global->view[iw]->detval, rs_global->ndet, MPI::FLOAT, iproc, 0); + 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); } } } - if (opt_debug) - fprintf(stdout, "Receiving rs data in process %d\n", mpi_ct.my_rank); - - end_work_unit = mpi_ct.local_work_units[mpi_ct.my_rank] - 1; - for (iw = 0; iw <= end_work_unit; iw++) { + for (int iw = 0; iw < mpiWorld.getMyLocalWorkUnits(); iw++) { MPI::Status status; - mpi_ct.comm.Recv(&rs_local->view[iw]->ndet, 1, MPI::INT, 0, 0, status); - mpi_ct.comm.Recv(&rs_local->view[iw]->view_angle, 1, MPI::DOUBLE, 0, 0, status); - mpi_ct.comm.Recv(rs_local->view[iw]->detval, rs_local->ndet, MPI::FLOAT, 0, 0, status); - } - rs_local->nview = mpi_ct.local_work_units[mpi_ct.my_rank]; - if (opt_debug) { - mpi_ct.comm.Barrier(); - fprintf(stdout, "Done with mpi_scatter_rs in process %2d\n", mpi_ct.my_rank); + 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); } + rs_local->nview = mpiWorld.getMyLocalWorkUnits(); } #endif @@ -434,7 +408,7 @@ static void print_raysum_info(const RAYSUM *rs) #ifndef NO_MAIN int -main (const int argc, char *const argv[]) +main (int argc, char* argv[]) { return (ctrec_main(argc, argv)); } diff --git a/src/mpiworld.cpp b/src/mpiworld.cpp new file mode 100644 index 0000000..f5631f1 --- /dev/null +++ b/src/mpiworld.cpp @@ -0,0 +1,66 @@ +/***************************************************************************** +** FILE IDENTIFICATION +** +** Name: mpiworld.cpp +** Purpose: MPI Support class +** Programmer: Kevin Rosenberg +** Date Started: June 2000 +** +** This is part of the CTSim program +** Copyright (C) 1983-2000 Kevin Rosenberg +** +** $Id: mpiworld.cpp,v 1.1 2000/06/09 01:35:33 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 +** published by the Free Software Foundation. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +******************************************************************************/ + +#include +#include + + +MPIWorld::MPIWorld (int& argc, char**& argv) +{ + MPI::Init (argc, argv); + m_comm = MPI::COMM_WORLD.Dup(); + m_nProcessors = m_comm.Get_size(); + m_myRank = m_comm.Get_rank(); + m_vLocalWorkUnits.reserve (m_nProcessors); + m_vStartWorkUnit.reserve (m_nProcessors); + m_vEndWorkUnit.reserve (m_nProcessors); +} + + +void +MPIWorld::setTotalWorkUnits(int totalWorkUnits) +{ + if (m_nProcessors < 1) + return; + + int baseLocalWorkUnits = totalWorkUnits / m_nProcessors; + int remainderWorkUnits = totalWorkUnits % m_nProcessors; + + int currWorkUnits = 0; + for (int iProc = 0; iProc < m_nProcessors; iProc++) { + m_vLocalWorkUnits[iProc] = baseLocalWorkUnits; + if (iProc < remainderWorkUnits) + m_vLocalWorkUnits[iProc]++; + + m_vStartWorkUnit[iProc] = currWorkUnits; + m_vEndWorkUnit[iProc] = m_vStartWorkUnit[iProc] + m_vLocalWorkUnits[iProc] - 1; + + currWorkUnits += m_vLocalWorkUnits[iProc]; + } + +} + diff --git a/src/phm2if.cpp b/src/phm2if.cpp index 9b2b33b..66ceb47 100644 --- a/src/phm2if.cpp +++ b/src/phm2if.cpp @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2000 Kevin Rosenberg ** -** $Id: phm2if.cpp,v 1.5 2000/06/08 16:43:10 kevin Exp $ +** $Id: phm2if.cpp,v 1.6 2000/06/09 01:35:33 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 @@ -103,11 +103,11 @@ phm2sdf_usage (const char *program) } #ifdef HAVE_MPI -void mpi_gather_image (ImageFile* im_global, ImageFile* im_local, const int opt_debug); +void mpi_gather_image (MPIWorld& mpiWorld, ImageFile* im_global, ImageFile* im_local, const int opt_debug); #endif int -phm2sdf_main (const int argc, char *const argv[]) +phm2sdf_main (int argc, char* argv[]) { ImageFile* im_global = NULL; PHANTOM *phm = NULL; @@ -127,20 +127,9 @@ phm2sdf_main (const int argc, char *const argv[]) int opt_verbose = 0; double time_start=0, time_end=0; #ifdef HAVE_MPI - ImageFile* im_local = NULL; - int mpi_argc = argc; - char **mpi_argv = (char **) argv; double mpi_t1, mpi_t2, mpi_t, mpi_t_g; - - MPI::Init (mpi_argc, mpi_argv); - mpi_ct.comm = MPI::COMM_WORLD.Dup (); - mpi_ct.nproc = mpi_ct.comm.Get_size(); - mpi_ct.my_rank = mpi_ct.comm.Get_rank(); - - if (mpi_ct.nproc > CT_MPI_MAX_PROCESS) { - sys_error(ERR_FATAL, "Number of mpi processes (%d) exceeds max processes (%d)", - mpi_ct.nproc, CT_MPI_MAX_PROCESS); - } + ImageFile* im_local = NULL; + MPIWorld mpiWorld (argc, argv); #endif #ifdef HAVE_MPI @@ -150,7 +139,7 @@ phm2sdf_main (const int argc, char *const argv[]) #endif #ifdef HAVE_MPI - if (mpi_ct.my_rank == 0) { + if (mpiWorld.getRank() == 0) { #endif strcpy(opt_desc, ""); @@ -174,7 +163,7 @@ phm2sdf_main (const int argc, char *const argv[]) strncpy(opt_phmfilename, optarg, sizeof(opt_phmfilename)); phm = phm_create_from_file(opt_phmfilename); #ifdef HAVE_MPI - if (mpi_ct.my_rank == 0) + if (mpiWorld.getRank() == 0) fprintf(stderr, "Can't use phantom from file in MPI mode\n"); return (1); #endif @@ -304,29 +293,29 @@ phm2sdf_main (const int argc, char *const argv[]) #ifdef HAVE_MPI mpi_t1 = MPI::Wtime(); - mpi_ct.comm.Bcast (&opt_verbose, 1, MPI::INT, 0); - mpi_ct.comm.Bcast (&opt_debug, 1, MPI::INT, 0); - mpi_ct.comm.Bcast (&opt_trace, 1, MPI::INT, 0); - mpi_ct.comm.Bcast (&opt_nx, 1, MPI::INT, 0); - mpi_ct.comm.Bcast (&opt_ny, 1, MPI::INT, 0); - mpi_ct.comm.Bcast (&opt_nsample, 1, MPI::INT, 0); - mpi_ct.comm.Bcast (&opt_phmnum, 1, MPI::INT, 0); - mpi_ct.comm.Bcast (&opt_filter, 1, MPI::INT, 0); - mpi_ct.comm.Bcast (&opt_filter_domain, 1, MPI::INT, 0); - mpi_ct.comm.Bcast (&opt_filter_param, 1, MPI::DOUBLE, 0); - mpi_ct.comm.Bcast (&opt_filter_bw, 1, MPI::DOUBLE, 0); + 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); + mpiWorld.getComm().Bcast (&opt_nx, 1, MPI::INT, 0); + mpiWorld.getComm().Bcast (&opt_ny, 1, MPI::INT, 0); + mpiWorld.getComm().Bcast (&opt_nsample, 1, MPI::INT, 0); + mpiWorld.getComm().Bcast (&opt_phmnum, 1, MPI::INT, 0); + mpiWorld.getComm().Bcast (&opt_filter, 1, MPI::INT, 0); + mpiWorld.getComm().Bcast (&opt_filter_domain, 1, MPI::INT, 0); + mpiWorld.getComm().Bcast (&opt_filter_param, 1, MPI::DOUBLE, 0); + mpiWorld.getComm().Bcast (&opt_filter_bw, 1, MPI::DOUBLE, 0); if (opt_verbose) { mpi_t2 = MPI::Wtime(); mpi_t = mpi_t2 - mpi_t1; - mpi_ct.comm.Reduce (&mpi_t, &mpi_t_g, 1, MPI::DOUBLE, MPI::MAX, 0); - if (mpi_ct.my_rank == 0) + 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); } - mpi_ct_calc_work_units(opt_nx); + mpiWorld.setTotalWorkUnits (opt_nx); - if (mpi_ct.my_rank == 0) { + if (mpiWorld.getRank() == 0) { im_global = new ImageFile (opt_outfile, opt_nx, opt_ny); im_global->adf.fileCreate(); } @@ -341,7 +330,7 @@ phm2sdf_main (const int argc, char *const argv[]) #ifdef HAVE_MPI else { - if (mpi_ct.my_rank == 0) + if (mpiWorld.getRank() == 0) fprintf(stderr, "phmnum < 0\n"); exit(1); } @@ -351,33 +340,33 @@ phm2sdf_main (const int argc, char *const argv[]) ImageFileArray v; #ifdef HAVE_MPI - if (mpi_ct.my_rank == 0) + if (mpiWorld.getRank() == 0) v = im_global->getArray (); if (phm->type == P_UNIT_PULSE) { - if (mpi_ct.my_rank == 0) { + if (mpiWorld.getRank() == 0) { v[opt_nx/2][opt_ny/2] = 1.; calctime = 0; } } else if (opt_filter != -1) { - if (mpi_ct.my_rank == 0) { + if (mpiWorld.getRank() == 0) { image_filter_response (*im_global, opt_filter_domain, opt_filter_bw, opt_filter, opt_filter_param, opt_trace); calctime = 0; } } else { - mpi_ct.comm.Barrier(); + mpiWorld.getComm().Barrier(); if (opt_verbose) mpi_t1 = MPI::Wtime(); - phm_to_imagefile (phm, *im_local, mpi_ct.start_work_unit[mpi_ct.my_rank], mpi_ct.local_work_units[mpi_ct.my_rank], opt_nsample, opt_trace); + phm_to_imagefile (phm, *im_local, mpiWorld.getMyStartWorkUnit(), mpiWorld.getMyLocalWorkUnits(), opt_nsample, opt_trace); if (opt_verbose) { mpi_t2 = MPI::Wtime(); mpi_t = mpi_t2 - mpi_t1; - mpi_ct.comm.Reduce(&mpi_t, &mpi_t_g, 1, MPI::DOUBLE, MPI::MAX, 0); - if (mpi_ct.my_rank == 0) + mpiWorld.getComm().Reduce(&mpi_t, &mpi_t_g, 1, MPI::DOUBLE, MPI::MAX, 0); + if (mpiWorld.getRank() == 0) printf("Time to compile phm = %f secs, Max time = %f\n", mpi_t, mpi_t_g); } - mpi_gather_image(im_global, im_local, opt_debug); + mpi_gather_image (mpiWorld, im_global, im_local, opt_debug); } #else v = im_global->getArray (); @@ -403,7 +392,7 @@ phm2sdf_main (const int argc, char *const argv[]) #endif #ifdef HAVE_MPI - if (mpi_ct.my_rank == 0) + if (mpiWorld.getRank() == 0) #endif { im_global->adf.arrayDataWrite (); @@ -433,31 +422,23 @@ phm2sdf_main (const int argc, char *const argv[]) #ifdef HAVE_MPI -void mpi_gather_image (ImageFile* im_global, ImageFile* im_local, const int opt_debug) +void mpi_gather_image (MPIWorld& mpiWorld, ImageFile* im_global, ImageFile* im_local, const int opt_debug) { ImageFileArray vLocal = im_local->getArray(); ImageFileArray vGlobal = NULL; - if (mpi_ct.my_rank == 0) - vGlobal = im_global->getArray(); int nyLocal = im_local->ny(); - - int end_work_unit = mpi_ct.local_work_units[mpi_ct.my_rank] - 1; - for (int iw = 0; iw <= end_work_unit; iw++) { - mpi_ct.comm.Send(vLocal[iw], nyLocal, im_local->getMPIDataType(), 0, 0); - } - - if (mpi_ct.my_rank == 0) { - for (int iproc = 0; iproc < mpi_ct.nproc; iproc++) { - end_work_unit = mpi_ct.start_work_unit[iproc] + mpi_ct.local_work_units[iproc] - 1; - if (opt_debug) { - fprintf(stdout, "Recv rs data from process %d (%d-%d)\n", iproc, mpi_ct.start_work_unit[iproc], end_work_unit); - fflush(stdout); - } + if (mpiWorld.getRank() == 0) + vGlobal = im_global->getArray(); + + for (int iw = 0; iw < mpiWorld.getMyLocalWorkUnits(); iw++) + mpiWorld.getComm().Send(vLocal[iw], nyLocal, im_local->getMPIDataType(), 0, 0); - for (int iw = mpi_ct.start_work_unit[iproc]; iw <= end_work_unit; iw++) { + if (mpiWorld.getRank() == 0) { + for (int iProc = 0; iProc < mpiWorld.getNumProcessors(); iProc++) { + for (int iw = mpiWorld.getStartWorkUnit(iProc); iw <= mpiWorld.getEndWorkUnit(iProc); iw++) { MPI::Status status; - mpi_ct.comm.Recv(vGlobal[iw], nyLocal, im_local->getMPIDataType(), iproc, 0, status); + mpiWorld.getComm().Recv(vGlobal[iw], nyLocal, im_local->getMPIDataType(), iProc, 0, status); } } } @@ -467,7 +448,7 @@ void mpi_gather_image (ImageFile* im_global, ImageFile* im_local, const int opt_ #ifndef NO_MAIN int -main (const int argc, char *const argv[]) +main (int argc, char* argv[]) { return (phm2sdf_main(argc, argv)); } diff --git a/src/phm2rs.cpp b/src/phm2rs.cpp index ed9c9e0..ac30c59 100644 --- a/src/phm2rs.cpp +++ b/src/phm2rs.cpp @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2000 Kevin Rosenberg ** -** $Id: phm2rs.cpp,v 1.3 2000/06/08 16:43:10 kevin Exp $ +** $Id: phm2rs.cpp,v 1.4 2000/06/09 01:35:33 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 @@ -50,10 +50,6 @@ static struct option phm2rs_options[] = void phm2rs_usage (const char *program) { -#ifdef HAVE_MPI -if (mpi_ct.my_rank == 0) - { -#endif fprintf(stdout,"usage: %s outfile ndet nview [--phantom phantom-name] [--phmfile filename] [OPTIONS]\n", kbasename(program)); fprintf(stdout,"Calculate raysums (projections) through phantom object, either\n"); fprintf(stdout,"a predefined --phantom or a --phmfile\n"); @@ -81,18 +77,14 @@ if (mpi_ct.my_rank == 0) fprintf(stdout," --debug Debug mode\n"); fprintf(stdout," --version Print version\n"); fprintf(stdout," --help Print this help message\n"); -#ifdef HAVE_MPI - } - mpi_ct.comm.Abort(1); -#endif } #ifdef HAVE_MPI -void mpi_gather_rs (RAYSUM *rs_global, RAYSUM *rs_local, const int opt_debug); +void mpi_gather_rs (MPIWorld& mpiWorld, RAYSUM *rs_global, RAYSUM *rs_local, const int opt_debug); #endif int -phm2rs_main (const int argc, char *const argv[]) +phm2rs_main (int argc, char* argv[]) { DETECTOR *det; PHANTOM *phm = NULL; @@ -108,29 +100,19 @@ phm2rs_main (const int argc, char *const argv[]) double opt_rotangle = 1; double time_start = 0, time_end = 0; -#ifndef HAVE_MPI - time_start = td_current_sec(); -#else - RAYSUM *rs_local; - int mpi_argc = argc; - char **mpi_argv = (char **) argv; +#ifdef HAVE_MPI double mpi_t1 = 0, mpi_t2 = 0, mpi_t, mpi_t_g; - - MPI::Init (mpi_argc, mpi_argv); - mpi_ct.comm = MPI::COMM_WORLD.Dup (); - mpi_ct.nproc = mpi_ct.comm.Get_size(); - mpi_ct.my_rank = mpi_ct.comm.Get_rank(); - - if (mpi_ct.nproc > CT_MPI_MAX_PROCESS) { - sys_error(ERR_FATAL, "Number of mpi processes (%d) exceeds max processes (%d)", - mpi_ct.nproc, CT_MPI_MAX_PROCESS); - } + RAYSUM *rs_local; + MPIWorld mpiWorld (argc, argv); time_start = MPI::Wtime(); +#else + time_start = td_current_sec(); #endif + #ifdef HAVE_MPI - if (mpi_ct.my_rank == 0) { + if (mpiWorld.getRank() == 0) { #endif strcpy(opt_desc, ""); strcpy(opt_phmfilename, ""); @@ -152,7 +134,7 @@ phm2rs_main (const int argc, char *const argv[]) break; case O_PHMFILE: #ifdef HAVE_MPI - if (mpi_ct.my_rank == 0) + if (mpiWorld.getRank() == 0) fprintf(stderr, "Can not read phantom from file in MPI mode\n"); return (1); #endif @@ -256,17 +238,17 @@ phm2rs_main (const int argc, char *const argv[]) #endif #ifdef HAVE_MPI - mpi_ct.comm.Barrier (); - mpi_ct.comm.Bcast (&opt_rotangle, 1, MPI::DOUBLE, 0); - mpi_ct.comm.Bcast (&opt_nview, 1, MPI::INT, 0); - mpi_ct.comm.Bcast (&opt_ndet, 1, MPI::INT, 0); - mpi_ct.comm.Bcast (&opt_nray, 1, MPI::INT, 0); - mpi_ct.comm.Bcast (&opt_phmnum, 1, MPI::INT, 0); - mpi_ct.comm.Bcast (&opt_verbose, 1, MPI::INT, 0); - mpi_ct.comm.Bcast (&opt_debug, 1, MPI::INT, 0); - mpi_ct.comm.Bcast (&opt_trace, 1, MPI::INT, 0); - - if (mpi_ct.my_rank > 0 && opt_phmnum >= 0) + mpiWorld.getComm().Barrier (); + mpiWorld.getComm().Bcast (&opt_rotangle, 1, MPI::DOUBLE, 0); + mpiWorld.getComm().Bcast (&opt_nview, 1, MPI::INT, 0); + mpiWorld.getComm().Bcast (&opt_ndet, 1, MPI::INT, 0); + mpiWorld.getComm().Bcast (&opt_nray, 1, MPI::INT, 0); + mpiWorld.getComm().Bcast (&opt_phmnum, 1, MPI::INT, 0); + 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); + + if (mpiWorld.getRank() > 0 && opt_phmnum >= 0) phm = phm_create (opt_phmnum); #endif @@ -274,36 +256,39 @@ phm2rs_main (const int argc, char *const argv[]) det = detector_create (phm, DETECTOR_PARALLEL, opt_ndet, opt_nview, opt_nray, opt_rotangle); #ifdef HAVE_MPI - mpi_ct_calc_work_units(opt_nview); - if (mpi_ct.my_rank == 0) { + mpiWorld.setTotalWorkUnits (opt_nview); + + if (mpiWorld.getRank() == 0) { rs_global = raysum_create_from_det (opt_outfile, det); raysum_alloc_views(rs_global); } rs_local = raysum_create_from_det (NULL, det); - rs_local->nview = mpi_ct.local_work_units[mpi_ct.my_rank]; + rs_local->nview = mpiWorld.getMyLocalWorkUnits(); if (opt_debug) - printf("rs_local->nview = %d (process %d)\n", rs_local->nview, mpi_ct.my_rank); + printf("rs_local->nview = %d (process %d)\n", rs_local->nview, mpiWorld.getRank()); if (opt_verbose) mpi_t1 = MPI::Wtime(); - raysum_collect (rs_local, det, phm, mpi_ct.start_work_unit[mpi_ct.my_rank], opt_trace, FALSE); + raysum_collect (rs_local, det, phm, mpiWorld.getMyStartWorkUnit(), opt_trace, FALSE); if (opt_verbose) { mpi_t2 = MPI::Wtime(); mpi_t = mpi_t2 - mpi_t1; - mpi_ct.comm.Reduce(&mpi_t, &mpi_t_g, 1, MPI::DOUBLE, MPI::MAX, 0); - if (mpi_ct.my_rank == 0) + mpiWorld.getComm().Reduce(&mpi_t, &mpi_t_g, 1, MPI::DOUBLE, MPI::MAX, 0); + if (mpiWorld.getRank() == 0) printf("Time to collect rs = %f secs, Max = %f secs\n", mpi_t, mpi_t_g); } if (opt_verbose) mpi_t1 = MPI::Wtime(); - mpi_gather_rs(rs_global, rs_local, opt_debug); + + mpi_gather_rs (mpiWorld, rs_global, rs_local, opt_debug); + if (opt_verbose) { mpi_t2 = MPI::Wtime(); mpi_t = mpi_t2 - mpi_t1; - mpi_ct.comm.Reduce(&mpi_t, &mpi_t_g, 1, MPI::DOUBLE, MPI::MAX, 0); - if (mpi_ct.my_rank == 0) + mpiWorld.getComm().Reduce(&mpi_t, &mpi_t_g, 1, MPI::DOUBLE, MPI::MAX, 0); + if (mpiWorld.getRank() == 0) printf("Time to gather rs = %f secs, Max = %f secs\n", mpi_t, mpi_t_g); } #else @@ -315,7 +300,7 @@ phm2rs_main (const int argc, char *const argv[]) time_end = td_current_sec(); #else time_end = MPI::Wtime(); - if (mpi_ct.my_rank == 0) + if (mpiWorld.getRank() == 0) #endif { rs_global->calctime = time_end - time_start; @@ -327,7 +312,7 @@ phm2rs_main (const int argc, char *const argv[]) } #ifdef HAVE_MPI - if (mpi_ct.my_rank == 0) + if (mpiWorld.getRank() == 0) #endif { raysum_write (rs_global); @@ -349,34 +334,22 @@ phm2rs_main (const int argc, char *const argv[]) */ #ifdef HAVE_MPI -void mpi_gather_rs (RAYSUM *rs_global, RAYSUM *rs_local, const int opt_debug) +void mpi_gather_rs (MPIWorld& mpiWorld, RAYSUM *rs_global, RAYSUM *rs_local, const int opt_debug) { - int iproc; - int end_work_unit; - int iw; - - end_work_unit = mpi_ct.local_work_units[mpi_ct.my_rank] - 1; - for (iw = 0; iw <= end_work_unit; iw++) { - mpi_ct.comm.Send(&rs_local->view[iw]->view_angle, 1, MPI::DOUBLE, 0, 0); - mpi_ct.comm.Send(&rs_local->view[iw]->ndet, 1, MPI::INT, 0, 0); - mpi_ct.comm.Send(rs_local->view[iw]->detval, rs_local->ndet, MPI::FLOAT, 0, 0); + for (int iw = 0; iw < mpiWorld.getMyLocalWorkUnits(); iw++) { + mpiWorld.getComm().Send(&rs_local->view[iw]->view_angle, 1, MPI::DOUBLE, 0, 0); + mpiWorld.getComm().Send(&rs_local->view[iw]->ndet, 1, MPI::INT, 0, 0); + mpiWorld.getComm().Send(rs_local->view[iw]->detval, rs_local->ndet, MPI::FLOAT, 0, 0); } - if (mpi_ct.my_rank == 0) { - for (iproc = 0; iproc < mpi_ct.nproc; iproc++) { - end_work_unit = mpi_ct.start_work_unit[iproc] - + mpi_ct.local_work_units[iproc] - - 1; - - if (opt_debug) - fprintf(stdout, "Recv rs data from process %d\n", iproc); - - for (iw = mpi_ct.start_work_unit[iproc]; iw <= end_work_unit; iw++) { + if (mpiWorld.getRank() == 0) { + for (int iProc = 0; iProc < mpiWorld.getNumProcessors(); iProc++) { + for (int iw = mpiWorld.getStartWorkUnit(iProc); iw <= mpiWorld.getEndWorkUnit(iProc); iw++) { MPI::Status status; - mpi_ct.comm.Recv(&rs_global->view[iw]->view_angle, 1, MPI::DOUBLE, iproc, 0, status); - mpi_ct.comm.Recv(&rs_global->view[iw]->ndet, 1, MPI::INT, iproc, 0, status); - mpi_ct.comm.Recv(rs_global->view[iw]->detval, rs_global->ndet, MPI::FLOAT, iproc, 0, status); + mpiWorld.getComm().Recv(&rs_global->view[iw]->view_angle, 1, MPI::DOUBLE, iProc, 0, status); + mpiWorld.getComm().Recv(&rs_global->view[iw]->ndet, 1, MPI::INT, iProc, 0, status); + mpiWorld.getComm().Recv(rs_global->view[iw]->detval, rs_global->ndet, MPI::FLOAT, iProc, 0, status); } } } @@ -387,7 +360,7 @@ void mpi_gather_rs (RAYSUM *rs_global, RAYSUM *rs_local, const int opt_debug) #ifndef NO_MAIN int -main (const int argc, char *const argv[]) +main (int argc, char* argv[]) { return (phm2rs_main(argc, argv)); } -- 2.34.1