我正在尝试将此CODE从Fortran转换为C。
这是我到目前为止所做的:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "mpi.h"
#define PRINT_NOTHING 0
#define PRINT_UP_TO_MESGS 1
#define PRINT_UP_TO_ARRAYS 2
#define PRINT_UP_TO_MATRICES 3
#define PRINT_LEVEL PRINT_UP_TO_MATRICES
/*! Parameters: */
#define TOTMEM 425053208
#define INTMEM 13107200
#define NTESTS 20
#define DLEN_ 9
#define DBLESZ 8 /*! Size of a DOUBLE PRE. */
#define MEMSIZ 425053208/8 /*! Memory for DOUBLE PRE. */
#define MASTER 0
#define MPI_ERROR_CODE_ERROR_GRID 1
#define MPI_ERROR_CODE_NOT_FACT 2
#define MPI_ERROR_CODE_NOT_SOLVE 3
#define BLACS_USER_WONT_FIN_MPI 0
#define BLACS_USER_WILL_FIN_MPI 1
#define DESCRIPTOR_SIZE 7
typedef enum {
FALSE,
TRUE
} logical;
/*! External subroutines: */
extern void Cblacs_barrier (int context,
char* scope);
extern void Cblacs_exit (int doneflag);
extern void Cblacs_get (int ,
int ,
int *context);
extern void Cblacs_gridexit (int context);
extern void Cblacs_gridinfo (int context,
int *our_nprow,
int *our_npcol,
int *my_prow,
int *my_pcol);
extern void Cblacs_gridinit (int* context,
char* order,
int nproc_rows,
int nproc_cols);
extern void Cblacs_pinfo (int *my_blacs_pid,
int *our_blacs_nprocs);
/* http://www.netlib.org/scalapack/explore-html/dd/d22/descinit_8f.html */
extern void descinit_ (int *desc,
int *m,
int *n,
int *mb,
int *nb,
int *irsrc,
int *icsrc,
int *ictxt,
int *lld,
int *info);
/* http://www.netlib.org/scalapack/explore-html/dc/d44/igsum2d___8c.html */
extern void igsum2d_ (int *contxt,
char *scope,
char *top,
int *m,
int *n,
int *a,
int *lda,
int *rdest,
int *cdest);
/* http://www.netlib.org/scalapack/explore-html/db/da1/pdbmatgen_8f.html */
extern void pdbmatgen_ (int *ictxt,
char *aform,
char *aform2,
int *bwl,
int *bwu,
int *n,
int *mb,
int *nb,
double *a,
int *lda,
int *iarow,
int *iacol,
int *iseed,
int *myrow,
int *mycol,
int *nprow,
int *npcol);
/* http://www.netlib.org/scalapack/explore-html/d8/dba/pdchekpad_8f.html */
extern void pdchekpad_ (int * ictxt,
char *mess,
int *m,
int *n,
double *a,
int *lda,
int *ipre,
int *ipost,
double *chkval);
/* http://www.netlib.org/scalapack/explore-html/d2/dc2/pddblaschk_8f.html */
extern void pddblaschk_ (char *symm,
char *uplo,
char *trans,
int *n,
int *bwl,
int *bwu,
int *nrhs,
double *x,
int *ix,
int *jx,
int *descx,
int *iaseed,
double *a,
int *ia,
int *ja,
int *desca,
int *ibseed,
double *anorm,
double *resid,
double *work,
int *worksiz);
/* http://www.netlib.org/scalapack/explore-html/d6/d3b/pdfillpad_8f.html */
extern void pdfillpad_ (int *ictxt,
int *m,
int *n,
double *a,
int *lda,
int *ipre,
int *ipost,
double *chkval);
/* http://www.netlib.org/scalapack/explore-html/d0/d2b/pdgbinfo_8f.html */
extern void pdgbinfo_ (char *summry,
int *nout,
char *trans,
int *nmat,
int *nval,
int *ldnval,
int *nbw,
int *bwlval,
int *bwuval,
int *ldbwval,
int *nnb,
int *nbval,
int *ldnbval,
int *nnr,
int *nrval,
int *ldnrval,
int *nnbr,
int *nbrval,
int *ldnbrval,
int *ngrids,
int *pval,
int *ldpval,
int *qval,
int *ldqval,
float *thresh,
double *work, /* Array to gather and bcast. */
int *iam,
int *nprocs);
/* http://www.netlib.org/scalapack/explore-html/dd/dad/pdgbtrf_8f.html */
extern void pdgbtrf_ (int *n,
int *bwl,
int *bwu,
double *a,
int *ja,
int *desca,
int *ipiv,
double *af,
int *laf,
double *work,
int *lwork,
int *info);
/* http://www.netlib.org/scalapack/explore-html/d9/dda/pdgbtrs_8f.html */
extern void pdgbtrs_ (char *trans,
int *n,
int *bwl,
int *bwu,
int *nrhs,
double *a,
int *ja,
int *desca,
int *ipiv,
double *b,
int *ib,
int *descb,
double *af,
int *laf,
double *work,
int *lwork,
int *info);
/*
http://www.netlib.org/scalapack/explore-html/d2/d66/_e_i_g_2pdmatgen_8f.html
*/
extern void pdmatgen_ (int *ictxt,
char *aform,
char *diag,
int *m,
int *n,
int *mb,
int *nb,
double *a,
int *lda,
int *iarow,
int *iacol,
int *iseed,
int *iroff,
int *irnum,
int *icoff,
int *icnum,
int *myrow,
int *mycol,
int *nprow,
int *npcol);
/* http://www.netlib.org/scalapack/explore-html/d2/dcd/sltimer_8f_source.html */
extern void slboot_ (void);
extern void slcombine_ (int *ictxt,
char *scope,
char *op,
char *timetype,
int *n,
int *ibeg,
double *times);
extern void sltimer_ ( int *i );
/*! External functions: */
/* http://www.netlib.org/scalapack/explore-html/d4/d48/numroc_8f.html */
extern int numroc_ (int *n,
int *nb,
int *iproc,
int *isrcproc,
int *nprocs);
/* http://www.netlib.org/scalapack/explore-html/df/dee/tools_8f.html#a67ae4efe5110e3297b1e9e3a46d8c78b */
extern logical lsame_ (char *ca,
char *cb);
/* http://www.netlib.org/scalapack/explore-html/db/dd0/pdlange_8f.html */
extern double pdlange_ (char *norm,
int *m,
int *n,
double *a,
int *ia,
int *ja,
int *desca,
double *work );
/*! Intrinsic functions: */
/* INTRINSIC DBLE, MAX, MIN, MOD */
inline double DBLE(int xx) { return (double) xx; }
inline double MAX(double xx, double yy) { return xx >= yy? xx: yy; }
inline double MIN(double xx, double yy) { return xx <= yy? xx: yy; }
inline int MOD(int xx, int yy) { return xx%yy; }
/*! PROGRAM PDGBDRIVER: */
int main (int argc, char **argv) {
/*! Parameters: */
int ntests = NTESTS; /* Number of num. tests to be performed */
// int BLOCK_CYCLIC_2D = 1;
// int DTYPE_ = 1;
// int CTXT_ = 2;
// int M_ = 3;
// int N_ = 4;
// int MB_ = 5;
// int NB_ = 6;
// int RSRC_ = 7;
// int CSRC_ = 8;
// int LLD_ = 9;
//
// double ZERO = 0.0;
// double PADVAL = -9923.0;
//
// int INT_ONE = 1;
/*! Local scalars: */
logical CHECK; /* Should or shouldn't I perform the num. tests? */
char TRANS; /* Should I transpose the matrix? */
// char PASSED[6];
char OUTFILE[80]; /* ? */
// int BWL;
// int BWU;
// int BW_NUM;
// int FILLIN_SIZE;
// int FREE_PTR;
// int H;
// int HH;
int I; /* Iterator per process grid. */
int IAM; /* My MPI process ID. */
int IASEED; /* Seed for random matrix A creation. */
int IBSEED; /* Seed for random matrix B creation. */
// int ICTXT;
// int ICTXTB;
// int IERR_TEMP;
// int IMIDPAD;
// int INFO;
// int IPA;
// int IPB;
// int IPOSTPAD;
// int IPREPAD;
// int IPW;
// int IPW_SIZE;
// int IPW_SOLVE;
// int IPW_SOLVE_SIZE;
// int IP_DRIVER_W;
// int IP_FILLIN;
// int J;
// int K;
/*! Data statements: */
// int KFAIL = 4;
// int KPASS = 4;
// int KSKIP = 4;
// int KTESTS = 4;
/*! Local scalars: (continued) */
// int MYCOL;
// int MYRHS_SIZE;
// int MYROW;
// int N;
// int NB;
int NBW; /* Number of bandwith values per matrix. */
int NGRIDS; /* Number of process grids to try for. */
int NMAT; /* Number of matrices */
int NNB; /* Number of sizes of NB (block column size). */
int NNBR;
int NNR;
int NOUT; /* Device out... o.O */
// int NP;
int NPCOL; /* Procs per row in processors grid/ */
int NPROCS; /* The size of OUR communicator. */
// int NPROCS_REAL;
int NPROW; /* Procs per row in processors grid/ */
// int NQ;
// int NRHS;
// int N_FIRST;
// int N_LAST;
// int WORKSIZ;
float THRESH; /* Threshold variable for numerical tests. */
// double ANORM;
// double NOPS;
// double NOPS2;
// double SRESID;
// double TMFLOPS;
// double TMFLOPS2;
/*! Local arrays: */
// int IPIV[INTMEM];
int BWLVAL[NTESTS]; /* Values of lower diagonals per matrix. */
int BWUVAL[NTESTS]; /* Values of upper diagonals per matrix. */
// int DESCA[7];
// int DESCA2D[DLEN_];
// int DESCB[7];
// int DESCB2D[DLEN_];
// int IERR[1];
int NBRVAL[NTESTS]; /* ? */
int NBVAL[NTESTS]; /* Column sizes per matrix. */
int NRVAL[NTESTS]; /* ? */
int NVAL[NTESTS]; /* Values of N for a given matrix. */
int PVAL[NTESTS]; /* Values for proc. rows. */
int QVAL[NTESTS]; /* Values for proc. cols. */
// double CTIME[2];
double *MEM; /* GLOABL array for broadcasting the information. */
// double WTIME[2];
/*! Executable statements: */
/*! Get starting information: */
Cblacs_pinfo(&IAM, &NPROCS);
IASEED = 100;
IBSEED = 200;
MEM = (double *) malloc(MEMSIZ);
pdgbinfo_(OUTFILE, &NOUT, &TRANS, &NMAT, NVAL, &ntests, &NBW,
BWLVAL, BWUVAL, &ntests, &NNB, NBVAL, &ntests, &NNR,
NRVAL, &ntests, &NNBR, NBRVAL, &ntests, &NGRIDS, PVAL,
&ntests, QVAL, &ntests, &THRESH, MEM, &IAM, &NPROCS);
CHECK = (THRESH >= 0.0f);
/*! Print headings: */
fprintf(stdout, "\n");
fprintf(stdout, "TIME TR N BWL BWU NB NRHS P Q L*U Time Slv Time MFLOPS MFLOP2 CHECK\n");
fprintf(stdout, "---- -- ------ --- --- ---- ----- ---- ---- -------- -------- -------- -------- ------\n");
fprintf(stdout, "\n");
fflush(stdout);
/*! Loop over different process grids: */
for (I = 1; I <= NGRIDS; I++) {
NPROW = PVAL[I - 1];
NPCOL = QVAL[I - 1];
fprintf(stdout, "Solving for a %d x %d grid!\n", NPROW, NPCOL);
}
free(MEM);
Cblacs_exit(0);
exit(EXIT_SUCCESS);
}
请原谅注释掉的变量,但就像我说的那样,我基本上是从头开始翻译参考驱动程序。
我的问题是,一旦我编写了for循环,它突然开始出现seg-faulting ...它之前正在工作。这是一个时髦的内存操作问题的明显迹象,这可能源于与C和Fortran之间的内存管理差异相关的问题。
至少,这是我的猜测。
有没有人知道可能出现的问题?
先谢谢!
答案 0 :(得分:7)
这里的根本问题实际上是在pdgbinfo
的调用中,从来没有真正打算从C调用(毕竟它在TESTING中);问题是字符串,实际上与数字数组的传递方式不同 - 长度总是传递(例如,您可以打印它们)。
你可以在C端模拟它,但它将高度依赖于编译器。最好的办法是将字符串拉出这些例程,或者使用ISO_C_BINDING生成相关fortran例程的可移植C接口。在F77代码中使用纯数字数组的例程应该不是问题。
已更新:如果您更改pdgbinfo.f
的开头和子例程声明,请执行以下操作:
SUBROUTINE PDGBINFO(CSUMMRY, NOUT, TRANS, NMAT, NVAL, LDNVAL, NBW,
& BWLVAL, BWUVAL, LDBWVAL, NNB, NBVAL, LDNBVAL,
& NNR, NRVAL, LDNRVAL, NNBR, NBRVAL, LDNBRVAL,
& NGRIDS, PVAL, LDPVAL, QVAL, LDQVAL, THRESH,
& WORK, IAM, NPROCS ) BIND(C)
use iso_c_binding
implicit none
*
*
*
* -- ScaLAPACK routine (version 1.7) --
* University of Tennessee, Knoxville, Oak Ridge National Laboratory,
* and University of California, Berkeley.
* November 15, 1997
*
* .. Scalar Arguments ..
CHARACTER(kind=c_char), intent(OUT) :: TRANS
CHARACTER(kind=c_char), dimension(*), intent(OUT) :: CSUMMRY
INTEGER(kind=c_int), intent(IN) :: IAM, LDNVAL, LDNBVAL,
& LDNRVAL, LDNBRVAL, LDPVAL,
& LDBWVAL, LDQVAL
INTEGER(kind=c_int), intent(INOUT) :: NPROCS
INTEGER(kind=c_int), intent(OUT) :: NOUT, NMAT, NBW, NNB,
& NNR, NNBR, NGRIDS
REAL(kind=c_float), intent(OUT) :: THRESH
INTEGER(kind=c_int), intent(OUT) :: NBRVAL( LDNBRVAL ),
& NBVAL( LDNBVAL ),
& NRVAL( LDNRVAL ), NVAL( LDNVAL ),
& BWLVAL( LDBWVAL),BWUVAL( LDBWVAL),
& PVAL( LDPVAL ), QVAL(LDQVAL), WORK( * )
CHARACTER(kind=c_char,len=100) :: SUMMRY
INTEGER :: c,sumlen
然后更改它读取文件的位置以将字符串复制到C数组中:
*
* Read name and unit number for summary output file
*
READ( NIN, FMT = * ) SUMMRY
** convert to C string
sumlen = len_trim(SUMMRY)
do c=1,sumlen
csummry(c) = summry(c:c)
enddo
csummry(sumlen+1) = c_null_char
然后,您应该能够在C程序中pdgbinfo
之后删除下划线,并使其以可在编译器套件中移植的方式工作。
答案 1 :(得分:1)
根据我从您的代码中读到的内容,您实际上从未检查过NGRIDS
的值。
我的猜测是它太大了,数组索引超出限制。
答案 2 :(得分:0)
这里建议的修改:
SUBROUTINE PDGBINFO( CSUMMRY, NOUT, TRANS, NMAT, NVAL, LDNVAL, NBW,
$ BWLVAL, BWUVAL, LDBWVAL, NNB, NBVAL, LDNBVAL,
$ NNR, NRVAL, LDNRVAL, NNBR, NBRVAL, LDNBRVAL,
$ NGRIDS, PVAL, LDPVAL, QVAL, LDQVAL, THRESH,
$ WORK, IAM, NPROCS ) BIND(C)
*
use iso_c_binding
implicit none
*
* .. Scalar Arguments ..
CHARACTER(kind=c_char), intent(out) :: TRANS
CHARACTER(kind=c_char), dimension(*), intent(OUT) :: CSUMMRY
INTEGER(kind=c_int), intent(in) :: IAM, LDNVAL, LDNBVAL,
$ LDNRVAL, LDNBRVAL, LDPVAL,
$ LDBWVAL, LDQVAL
INTEGER(kind=c_int), intent(inout) :: NPROCS
INTEGER(kind=c_int), intent(out) :: NOUT, NMAT, NBW, NNB,
$ NNR, NNBR, NGRIDS
REAL(KIND=C_FLOAT), intent(out) :: THRESH
* ..
* .. Array Arguments ..
INTEGER(kind=c_int), intent(out) :: NBRVAL( LDNBRVAL ), NBVAL( LDNBVAL ),
$ NRVAL( LDNRVAL ), NVAL( LDNVAL ),
$ BWLVAL( LDBWVAL), BWUVAL( LDBWVAL),
$ PVAL( LDPVAL ), QVAL(LDQVAL), WORK( * )
CHARACTER(KIND=c_char,len=100) :: SUMMRY
INTEGER :: c, sumlen
然而,这些会产生以下编译时错误:
[ejspeiro@node01 LIN]$ mpif90 -c -O3 pdgbinfo.f
pdgbinfo.f:5.54:
$ WORK, IAM, NPROCS ) BIND(C)
1
Error: Syntax error in SUBROUTINE statement at (1)
pdgbinfo.f:18.21:
CHARACTER(kind=c_char), intent(out) :: TRANS
1
Error: Parameter 'c_char' at (1) has not been declared or is a variable, which does not reduce to a constant expression
还有几个!
再次:
[ejspeiro@node01 LIN]$ mpif90 -v
mpif90 for the Intel(R) MPI Library 3.2 for Linux
Driving: gfortran -v -I/opt/intel/impi/3.2.0.011/include64/gfortran/4.1.0 -I/opt/intel/impi/3.2.0.011/include64 -L/opt/intel/impi/3.2.0.011/lib64 -Xlinker --enable-new-dtags -Xlinker -rpath -Xlinker /opt/intel/impi/3.2.0.011/lib64 -Xlinker -rpath -Xlinker /opt/intel/mpi-rt/3.2 -lmpi -lmpigf -lmpigi -lrt -lpthread -ldl -lgfortranbegin -lgfortran -lm -shared-libgcc
Using built-in specs.
Target: x86_64-redhat-linux6E
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --disable-gnu-unique-object --with-as=/usr/libexec/binutils220/as --enable-languages=c,c++,fortran --disable-libgcj --with-mpfr=/builddir/build/BUILD/gcc-4.4.7-20120601/obj-x86_64-redhat-linux6E/mpfr-install/ --with-ppl=/builddir/build/BUILD/gcc-4.4.7-20120601/obj-x86_64-redhat-linux6E/ppl-install --with-cloog=/builddir/build/BUILD/gcc-4.4.7-20120601/obj-x86_64-redhat-linux6E/cloog-install --with-tune=generic --with-arch_32=i586 --build=x86_64-redhat-linux6E
Thread model: posix
gcc version 4.4.7 20120313 (Red Hat 4.4.7-1) (GCC)
COMPILER_PATH=/usr/libexec/gcc/x86_64-redhat-linux6E/4.4.7/:/usr/libexec/gcc/x86_64-redhat-linux6E/4.4.7/:/usr/libexec/gcc/x86_64-redhat-linux6E/:/usr/lib/gcc/x86_64-redhat-linux6E/4.4.7/:/usr/lib/gcc/x86_64-redhat-linux6E/:/usr/libexec/gcc/x86_64-redhat-linux6E/4.4.7/:/usr/libexec/gcc/x86_64-redhat-linux6E/:/usr/lib/gcc/x86_64-redhat-linux6E/4.4.7/:/usr/lib/gcc/x86_64-redhat-linux6E/
LIBRARY_PATH=/usr/lib/gcc/x86_64-redhat-linux6E/4.4.7/:/usr/lib/gcc/x86_64-redhat-linux6E/4.4.7/:/usr/lib/gcc/x86_64-redhat-linux6E/4.4.7/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/app/intel/mkl/10.1.0.015/lib/em64t/:/opt/intel/Compiler/11.0/083/ipp/em64t/lib/:/opt/intel/Compiler/11.0/083/mkl/lib/em64t/:/opt/intel/Compiler/11.0/083/tbb/em64t/cc4.1.0_libc2.4_kernel2.6.16.21/lib/:/opt/intel/Compiler/11.0/083/ipp/em64t/lib/:/opt/intel/Compiler/11.0/083/mkl/lib/em64t/:/opt/intel/Compiler/11.0/083/tbb/em64t/cc4.1.0_libc2.4_kernel2.6.16.21/lib/:/usr/lib/gcc/x86_64-redhat-linux6E/4.4.7/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-I/opt/intel/impi/3.2.0.011/include64/gfortran/4.1.0' '-I/opt/intel/impi/3.2.0.011/include64' '-L/opt/intel/impi/3.2.0.011/lib64' '-shared-libgcc' '-mtune=generic'
/usr/libexec/gcc/x86_64-redhat-linux6E/4.4.7/collect2 --eh-frame-hdr -m elf_x86_64 --hash-style=gnu -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/gcc/x86_64-redhat-linux6E/4.4.7/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-redhat-linux6E/4.4.7/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux6E/4.4.7/crtbegin.o -L/opt/intel/impi/3.2.0.011/lib64 -L/usr/lib/gcc/x86_64-redhat-linux6E/4.4.7 -L/usr/lib/gcc/x86_64-redhat-linux6E/4.4.7 -L/usr/lib/gcc/x86_64-redhat-linux6E/4.4.7/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/app/intel/mkl/10.1.0.015/lib/em64t -L/opt/intel/Compiler/11.0/083/ipp/em64t/lib -L/opt/intel/Compiler/11.0/083/mkl/lib/em64t -L/opt/intel/Compiler/11.0/083/tbb/em64t/cc4.1.0_libc2.4_kernel2.6.16.21/lib -L/opt/intel/Compiler/11.0/083/ipp/em64t/lib -L/opt/intel/Compiler/11.0/083/mkl/lib/em64t -L/opt/intel/Compiler/11.0/083/tbb/em64t/cc4.1.0_libc2.4_kernel2.6.16.21/lib -L/usr/lib/gcc/x86_64-redhat-linux6E/4.4.7/../../.. --enable-new-dtags -rpath /opt/intel/impi/3.2.0.011/lib64 -rpath /opt/intel/mpi-rt/3.2 -lmpi -lmpigf -lmpigi -lrt -lpthread -ldl -lgfortranbegin -lgfortran -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-redhat-linux6E/4.4.7/crtend.o /usr/lib/gcc/x86_64-redhat-linux6E/4.4.7/../../../../lib64/crtn.o
/usr/lib/gcc/x86_64-redhat-linux6E/4.4.7/libgfortranbegin.a(fmain.o): In function `main':
(.text+0x26): undefined reference to `MAIN__'
collect2: ld returned 1 exit status