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
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
+
-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.
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
1D column plots
Single Image statistics
+
PROPOSED HDF FILE FORMAT
========================
-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
+
+/*****************************************************************************
+** 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
/*****************************************************************************
-** 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
** 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
#ifdef HAVE_MPI
#include "mpi++.h"
+#include "mpiworld.h"
#endif
#include "kstddef.h"
#include "sgp.h"
#endif
-#ifdef __cplusplus
- #include <iostream>
- #include <string>
+#include <iostream>
+#include <string>
- 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
Array2dFile<T>::~Array2dFile (void)
{
fileClose ();
+ delete array;
}
void
Array2dFile<T>::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;
}
}
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);
}
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;
}
/*****************************************************************************
-** 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
** 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
* 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);
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 */
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);
const double view_angle, const int interp_type);
void backproj_term_id2 (const RAYSUM *rs, ImageFile& im);
-
-#endif /* __cplusplus */
-
-
#endif
** 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
**
#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);
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);
** 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 ***
**
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
}
--- /dev/null
+/*****************************************************************************
+** 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 <mpi++.h>
+#include <vector.h>
+
+
+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<int> m_vLocalWorkUnits;
+ vector<int> m_vStartWorkUnit;
+ vector<int> m_vEndWorkUnit;
+ MPI::Intracomm m_comm;
+};
+
+
-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)
.\"
.\" Author: Kevin Rosenberg <kevin@rosenberg.net>
.\"
-.\" $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 ***
.\"
.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
.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
--- /dev/null
+.\" -*- nroff -*-
+.\"
+.\" if-1.1
+.\"
+.\" Author: Kevin Rosenberg <kevin@rosenberg.net>
+.\"
+.\" $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 IF-1 1
+.Os
+.Sh NAME
+.Nm if-1
+.Nd Single IF (Image File) Transformation
+.Sh SYNOPSIS
+.Nm if-1 iffile outfile [OPTIONS]
+.Sh DESCRIPTION
+.Pp
+.Nm
+Transforms a single IF file.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl Fl invert
+Inverts (negates) the image
+.It Fl Fl log
+Natural logrithm of image
+.It Fl Fl exp
+Natural exponential of image
+.It Fl Fl debug
+Set debug mode
+.It Fl Fl verbose
+Set verbose mode
+.It Fl Fl version
+Print version
+.It Fl Fl help
+Print terse help summary
+.Sh AUTHORS
+Kevin Rosenberg, M.D. <kevin@rosenberg.net>
+.Sh HISTORY
+.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 ctrec 1 ,
+.Xr phm2rs 1 ,
+.Xr phm2if 1 ,
+.Xr rs2if 1 ,
+.Xr ifinfo 1
\ No newline at end of file
--- /dev/null
+.\" -*- nroff -*-
+.\"
+.\" if2img.1
+.\"
+.\" Author: Kevin Rosenberg <kevin@rosenberg.net>
+.\"
+.\" $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 IF2IMG 1
+.Os
+.Sh NAME
+.Nm if2img
+.Nd IF (Image File) to Image
+.Sh SYNOPSIS
+.Nm if2img iffile outfile [OPTIONS]
+.Sh DESCRIPTION
+.Pp
+.Nm
+converts an 2D IF file to a viewable image file.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl Fl format Ar format-name
+Choose output image format
+.It Fl Fl center Ar center-mode
+Choose center of window (default is mode)
+.It Fl Fl auto Ar auto-mode
+Set automatic window mode (default is full)
+.It Fl Fl scaling Ar multiple
+Set scaling factor for output image (default is 1)
+.It Fl Fl min Ar minimum
+Set minimum intensity of window (overrides --auto)
+.It Fl Fl max Ar maximum
+Set maximum intensity of window (overrides --auto)
+.It Fl Fl stats
+Print image statistics
+.It Fl Fl labels
+Print IF labels
+.It Fl Fl debug
+Set debug mode
+.It Fl Fl verbose
+Set verbose mode
+.It Fl Fl version
+Print version
+.It Fl Fl help
+Print terse help summary
+.Sh AUTHORS
+Kevin Rosenberg, M.D. <kevin@rosenberg.net>
+.Sh HISTORY
+.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 ctrec 1 ,
+.Xr phm2rs 1 ,
+.Xr phm2if 1 ,
+.Xr rs2if 1 ,
+.Xr ifinfo 1
\ No newline at end of file
--- /dev/null
+.\" -*- nroff -*-
+.\"
+.\" if2info.1
+.\"
+.\" Author: Kevin Rosenberg <kevin@rosenberg.net>
+.\"
+.\" $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 IF2INFO 1
+.Os
+.Sh NAME
+.Nm ifinfo
+.Nd Print IF (Image File) Information
+.Sh SYNOPSIS
+.Nm ifinfo iffile [OPTIONS]
+.Sh DESCRIPTION
+.Pp
+.Nm
+prints information about an IF file
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl Fl labels
+Print history labels (default)
+.It Fl Fl stats
+Print image statistics (default)
+.It Fl Fl no-labels
+Do not print history labels
+.It Fl Fl no-stats
+Do not print image statistics
+.It Fl Fl debug
+Set debug mode
+.It Fl Fl verbose
+Set verbose mode
+.It Fl Fl version
+Print version
+.It Fl Fl help
+Print terse help summary
+.Sh AUTHORS
+Kevin Rosenberg, M.D. <kevin@rosenberg.net>
+.Sh HISTORY
+.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 ctrec 1 ,
+.Xr phm2rs 1 ,
+.Xr phm2if 1 ,
+.Xr rs2if 1 ,
+.Xr if2img 1
\ No newline at end of file
--- /dev/null
+.\" -*- nroff -*-
+.\"
+.\" phm2if.1
+.\"
+.\" Author: Kevin Rosenberg <kevin@rosenberg.net>
+.\"
+.\" $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 PHM2IF 1
+.Os
+.Sh NAME
+.Nm phm2if
+.Nd Generate Phantom (generate phantom for computed tomography simulator)
+.Sh SYNOPSIS
+.Nm phm2if outfile nx ny [--phantom phantom-name] [--picfile filename] [OPTIONS]
+.Sh DESCRIPTION
+.Nm
+generates phantom images for comparisons to reconstructions for CTsim.
+.Pp
+.Nm
+is configured to use a variety of options for phantom generation.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl Fl phantom Ar predefined-phantom-name
+Selects a predefined phantom name
+.It Fl Fl picfile Ar picfile
+Reads a picture file that defines a phantom
+.It Fl Fl filter Ar filter-name
+Generate a phantom image from a filter
+.It Fl Fl filter-param Ar x
+Set alpha level for Hamming filter
+.It Fl Fl filter-bw Ar bw
+Filter bandwidth (default is 1)
+.It Fl Fl filter-domain Ar domain
+Set domain to "spatial" or "freq"
+.It Fl Fl nsample Ar n
+Use n samples per X & Y direction for each pixel
+.It Fl Fl trace Ar level
+Set trace level (default is none)
+.It Fl Fl desc Ar description
+Save description in image file
+.It Fl Fl verbose
+Turn on verbose mode
+.It Fl Fl debug
+Turn on debug mode
+.It Fl Fl version
+Print version
+.It Fl Fl help
+Print terse help summary
+.Sh AUTHORS
+Kevin Rosenberg, M.D. <kevin@rosenberg.net>
+.Sh HISTORY
+.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 rs2if 1 ,
+.Xr ctrec 1 ,
+.Xr if2img 1 ,
+.Xr ifstats 1
\ No newline at end of file
.\"
.\" Author: Kevin Rosenberg <kevin@rosenberg.net>
.\"
-.\" $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 ***
.\"
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
+++ /dev/null
-.\" -*- nroff -*-
-.\"
-.\" phm2sdf.1
-.\"
-.\" Author: Kevin Rosenberg <kevin@rosenberg.net>
-.\"
-.\" $Id: phm2sdf.1,v 1.2 2000/05/03 08:43:46 kevin Exp $
-.\" $Log: phm2sdf.1,v $
-.\" Revision 1.2 2000/05/03 08:43:46 kevin
-.\" *** empty log message ***
-.\"
-.\"
-.Dd April 19, 2000
-.Dt PHM2SDF 1
-.Os
-.Sh NAME
-.Nm phm2sdf
-.Nd Generate Phantom (generate phantom for computed tomography simulator)
-.Sh SYNOPSIS
-.Nm phm2sdf outfile nx ny [--phantom phantom-name] [--picfile filename] [OPTIONS]
-.Sh DESCRIPTION
-.Nm
-generates phantom images for comparisons to reconstructions for CTsim.
-.Pp
-.Nm
-is configured to use a variety of options for phantom generation.
-.Pp
-The options are as follows:
-.Bl -tag -width Ds
-.It Fl Fl phantom Ar predefined-phantom-name
-Selects a predefined phantom name
-.It Fl Fl picfile Ar picfile
-Reads a picture file that defines a phantom
-.It Fl Fl filter Ar filter-name
-Generate a phantom image from a filter
-.It Fl Fl filter-param Ar x
-Set alpha level for Hamming filter
-.It Fl Fl filter-bw Ar bw
-Filter bandwidth (default is 1)
-.It Fl Fl filter-domain Ar domain
-Set domain to "spatial" or "freq"
-.It Fl Fl nsample Ar n
-Use n samples per X & Y direction for each pixel
-.It Fl Fl trace Ar level
-Set trace level (default is none)
-.It Fl Fl desc Ar description
-Save description in image file
-.It Fl Fl verbose
-Turn on verbose mode
-.It Fl Fl debug
-Turn on debug mode
-.It Fl Fl version
-Print version
-.It Fl Fl help
-Print terse help summary
-.Sh AUTHORS
-Kevin Rosenberg, M.D. <kevin@rosenberg.net>
-.Sh HISTORY
-.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 ctrec 1 ,
-.Xr sdf2img 1 ,
-.Xr sdfstats 1
\ No newline at end of file
+++ /dev/null
-.\" -*- nroff -*-
-.\"
-.\" sdf-1.1
-.\"
-.\" Author: Kevin Rosenberg <kevin@rosenberg.net>
-.\"
-.\" $Id: sdf-1.1,v 1.1 2000/05/03 08:43:46 kevin Exp $
-.\" $Log: sdf-1.1,v $
-.\" Revision 1.1 2000/05/03 08:43:46 kevin
-.\" *** empty log message ***
-.\"
-.\"
-.Dd April 19, 2000
-.Dt SDF-1 1
-.Os
-.Sh NAME
-.Nm sdf-1
-.Nd Single SDF (Standard Data File) Transformation
-.Sh SYNOPSIS
-.Nm sdf-1 sdffile outfile [OPTIONS]
-.Sh DESCRIPTION
-.Pp
-.Nm
-Transforms a single SDF file.
-.Pp
-The options are as follows:
-.Bl -tag -width Ds
-.It Fl Fl invert
-Inverts (negates) the image
-.It Fl Fl log
-Natural logrithm of image
-.It Fl Fl exp
-Natural exponential of image
-.It Fl Fl debug
-Set debug mode
-.It Fl Fl verbose
-Set verbose mode
-.It Fl Fl version
-Print version
-.It Fl Fl help
-Print terse help summary
-.Sh AUTHORS
-Kevin Rosenberg, M.D. <kevin@rosenberg.net>
-.Sh HISTORY
-.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 ctrec 1 ,
-.Xr phm2rs 1 ,
-.Xr phm2sdf 1 ,
-.Xr rs2sdf 1 ,
-.Xr sdfinfo 1
\ No newline at end of file
+++ /dev/null
-.\" -*- nroff -*-
-.\"
-.\" sdf2img.1
-.\"
-.\" Author: Kevin Rosenberg <kevin@rosenberg.net>
-.\"
-.\" $Id: sdf2img.1,v 1.2 2000/05/03 08:43:46 kevin Exp $
-.\" $Log: sdf2img.1,v $
-.\" Revision 1.2 2000/05/03 08:43:46 kevin
-.\" *** empty log message ***
-.\"
-.\"
-.Dd April 19, 2000
-.Dt SDF2IMG 1
-.Os
-.Sh NAME
-.Nm sdf2img
-.Nd SDF (Standard Data File) to Image
-.Sh SYNOPSIS
-.Nm sdf2img sdffile outfile [OPTIONS]
-.Sh DESCRIPTION
-.Pp
-.Nm
-converts an 2D SDF file to a viewable image file.
-.Pp
-The options are as follows:
-.Bl -tag -width Ds
-.It Fl Fl format Ar format-name
-Choose output image format
-.It Fl Fl center Ar center-mode
-Choose center of window (default is mode)
-.It Fl Fl auto Ar auto-mode
-Set automatic window mode (default is full)
-.It Fl Fl scaling Ar multiple
-Set scaling factor for output image (default is 1)
-.It Fl Fl min Ar minimum
-Set minimum intensity of window (overrides --auto)
-.It Fl Fl max Ar maximum
-Set maximum intensity of window (overrides --auto)
-.It Fl Fl stats
-Print image statistics
-.It Fl Fl labels
-Print SDF labels
-.It Fl Fl debug
-Set debug mode
-.It Fl Fl verbose
-Set verbose mode
-.It Fl Fl version
-Print version
-.It Fl Fl help
-Print terse help summary
-.Sh AUTHORS
-Kevin Rosenberg, M.D. <kevin@rosenberg.net>
-.Sh HISTORY
-.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 ctrec 1 ,
-.Xr phm2rs 1 ,
-.Xr phm2sdf 1 ,
-.Xr rs2sdf 1 ,
-.Xr sdfinfo 1
\ No newline at end of file
+++ /dev/null
-.\" -*- nroff -*-
-.\"
-.\" sdf2info.1
-.\"
-.\" Author: Kevin Rosenberg <kevin@rosenberg.net>
-.\"
-.\" $Id: sdfinfo.1,v 1.2 2000/05/03 08:43:46 kevin Exp $
-.\" $Log: sdfinfo.1,v $
-.\" Revision 1.2 2000/05/03 08:43:46 kevin
-.\" *** empty log message ***
-.\"
-.\"
-.Dd April 19, 2000
-.Dt SDF2INFO 1
-.Os
-.Sh NAME
-.Nm sdfinfo
-.Nd Print SDF (Standard Data File) Information
-.Sh SYNOPSIS
-.Nm sdfinfo sdffile [OPTIONS]
-.Sh DESCRIPTION
-.Pp
-.Nm
-prints information about an SDF file
-.Pp
-The options are as follows:
-.Bl -tag -width Ds
-.It Fl Fl labels
-Print history labels (default)
-.It Fl Fl stats
-Print image statistics (default)
-.It Fl Fl no-labels
-Do not print history labels
-.It Fl Fl no-stats
-Do not print image statistics
-.It Fl Fl debug
-Set debug mode
-.It Fl Fl verbose
-Set verbose mode
-.It Fl Fl version
-Print version
-.It Fl Fl help
-Print terse help summary
-.Sh AUTHORS
-Kevin Rosenberg, M.D. <kevin@rosenberg.net>
-.Sh HISTORY
-.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 ctrec 1 ,
-.Xr phm2rs 1 ,
-.Xr phm2sdf 1 ,
-.Xr rs2sdf 1 ,
-.Xr sdf2img 1
\ No newline at end of file
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@
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@
** 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
#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;
#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
#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);
#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)
}
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;
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();
}
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,
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();
#ifdef HAVE_MPI
- if (mpi_ct.my_rank == 0)
+ if (mpiWorld.getRank() == 0)
#endif
{
raysum_close (rs_global);
#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
#ifndef NO_MAIN
int
-main (const int argc, char *const argv[])
+main (int argc, char* argv[])
{
return (ctrec_main(argc, argv));
}
--- /dev/null
+/*****************************************************************************
+** 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 <mpi++.h>
+#include <mpiworld.h>
+
+
+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];
+ }
+
+}
+
** 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
}
#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;
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
#endif
#ifdef HAVE_MPI
- if (mpi_ct.my_rank == 0) {
+ if (mpiWorld.getRank() == 0) {
#endif
strcpy(opt_desc, "");
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
#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();
}
#ifdef HAVE_MPI
else {
- if (mpi_ct.my_rank == 0)
+ if (mpiWorld.getRank() == 0)
fprintf(stderr, "phmnum < 0\n");
exit(1);
}
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 ();
#endif
#ifdef HAVE_MPI
- if (mpi_ct.my_rank == 0)
+ if (mpiWorld.getRank() == 0)
#endif
{
im_global->adf.arrayDataWrite ();
#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);
}
}
}
#ifndef NO_MAIN
int
-main (const int argc, char *const argv[])
+main (int argc, char* argv[])
{
return (phm2sdf_main(argc, argv));
}
** 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
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");
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;
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, "");
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
#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
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
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;
}
#ifdef HAVE_MPI
- if (mpi_ct.my_rank == 0)
+ if (mpiWorld.getRank() == 0)
#endif
{
raysum_write (rs_global);
*/
#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);
}
}
}
#ifndef NO_MAIN
int
-main (const int argc, char *const argv[])
+main (int argc, char* argv[])
{
return (phm2rs_main(argc, argv));
}