1

このコードを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のメモリ管理の違いに関連する問題からおそらく発生します。

少なくとも、それは私の推測です。

誰かが何がうまくいかないかについての手がかりを持っていますか?

よろしくお願いします!

4

3 に答える 3

7

ここで、基本的な問題は実際にはへの呼び出しにありますがpdgbinfo、これは実際にはCから呼び出されることを意図したものではありませんでした(結局のところ、テスト中です)。問題は文字列です。これは実際には数値配列とは異なる方法で渡されます。たとえば、長さは常に渡されます(たとえば、文字列を出力できるようにするため)。

これを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コンパイラスイート間で移植可能な方法で機能させることができるはずです。

于 2013-03-21T03:03:24.813 に答える
1

私があなたのコードから読んだことから、あなたは実際に の値をチェックしていませんNGRIDS。私の推測では、大きすぎて、配列のインデックスが制限を超えていると思います。

于 2013-03-20T23:25:56.657 に答える