octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Implications of indexing changes for code that calls Fortran


From: John W. Eaton
Subject: Implications of indexing changes for code that calls Fortran
Date: Mon, 2 Jan 2017 12:02:46 -0500
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Icedove/45.4.0

With the recent changes for octave_idx_type, some changes will be needed for most code that calls Fortran. I've already made these changes for Octave itself, but Octave Forge code that passes integers to Fortran code is currently broken unless Octave is built with --disable-64. Most such code assumes that octave_idx_type is the same size as a Fortran INTEGER but that is no longer always the case. Instead, octave_f77_integer_type (AKA F77_INT) is now the same size as a Fortran INTEGER and it may not always be the same size as octave_idx_type.

As an example, here are the relevant parts of sl_mb05nd.cc from the control package:

  #include <f77-fcn.h>

  [...]

  extern "C"
  {
      int F77_FUNC (mb05nd, MB05ND)
                   (octave_idx_type& N, double& DELTA,
                    double* A, octave_idx_type& LDA,
                    double* EX, octave_idx_type& LDEX,
                    double* EXINT, octave_idx_type& LDEXINT,
                    double& TOL,
                    octave_idx_type* IWORK,
                    double* DWORK, octave_idx_type& LDWORK,
                    octave_idx_type& INFO);
  }

  [...]

        // arguments in
        Matrix a = args(0).matrix_value ();
        double delta = args(1).double_value ();
        double tol = args(2).double_value ();

        octave_idx_type n = a.rows ();
        octave_idx_type lda = max (1, n);
        octave_idx_type ldex = max (1, n);
        octave_idx_type ldexin = max (1, n);

        // arguments out
        Matrix ex (ldex, n);
        Matrix exint (ldexin, n);

        // workspace
        octave_idx_type ldwork = max (1, 2*n*n);
        OCTAVE_LOCAL_BUFFER (octave_idx_type, iwork, n);
        OCTAVE_LOCAL_BUFFER (double, dwork, ldwork);

        // error indicators
        octave_idx_type info = 0;

        // SLICOT routine MB05ND
        F77_XFCN (mb05nd, MB05ND,
                 (n, delta,
                  a.fortran_vec (), lda,
                  ex.fortran_vec (), ldex,
                  exint.fortran_vec (), ldexin,
                  tol,
                  iwork,
                  dwork, ldwork,
                  info));

Instead, this code needs to be written something like this:

  #include <f77-fcn.h>

  [...]

  // Not sure of the best test to use here
  // but we need something...
  #if defined (OCTAVE_HAVE_F77_INT_TYPEDEF)
  #  define TO_F77_INT(x) octave::to_f77_int (x)
  #else
  typedef octave_idx_type F77_INT
  #  define TO_F77_INT(x) (x)
  #endif

  #if ! defined F77_RET_TYPE

  extern "C"
  {
      F77_RET_T F77_FUNC (mb05nd, MB05ND)
                   (F77_INT& N, double& DELTA,
                    double* A, F77_INT& LDA,
                    double* EX, F77_INT& LDEX,
                    double* EXINT, F77_INT& LDEXINT,
                    double& TOL,
                    F77_INT* IWORK,
                    double* DWORK, F77_INT& LDWORK,
                    F77_INT& INFO);
  }

  [...]

        // arguments in
        Matrix a = args(0).matrix_value ();
        double delta = args(1).double_value ();
        double tol = args(2).double_value ();

        F77_INT n = TO_F77_INT (a.rows ());
        F77_INT lda = max (1, n);
        F77_INT ldex = max (1, n);
        F77_INT ldexin = max (1, n);

        // arguments out
        Matrix ex (ldex, n);
        Matrix exint (ldexin, n);

        // workspace
        F77_INT ldwork = max (1, 2*n*n);
        OCTAVE_LOCAL_BUFFER (F77_INT, iwork, n);
        OCTAVE_LOCAL_BUFFER (double, dwork, ldwork);

        // error indicators
        F77_INT info = 0;

        // SLICOT routine MB05ND
        F77_XFCN (mb05nd, MB05ND,
                 (n, delta,
                  a.fortran_vec (), lda,
                  ex.fortran_vec (), ldex,
                  exint.fortran_vec (), ldexin,
                  tol,
                  iwork,
                  dwork, ldwork,
                  info));

I'm certainly willing to help make these changes.

jwe



reply via email to

[Prev in Thread] Current Thread [Next in Thread]