Problem mit f2py und Common-Blöcken

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
darkstone
User
Beiträge: 3
Registriert: Samstag 19. Juli 2008, 11:54

Samstag 19. Juli 2008, 12:07

Hallo, ich bin gerade dabei mich in f2py einzuarbeiten . Leider komm ich gerade bei einem Testbeispiel nicht weiter.
Irgendwie mag f2py die Commonblöcke in Fortran nicht

Folgenden Fortran-Code möchte ich mit f2py in Python übersetzen.

Code: Alles auswählen

      program test
c
      integer  nint
      common /sizes/ NINT
c
      real  work(10)
c
      nint = 10
c
      call set(work)
c
      call output(work)
c
      end
c
c---------------
c
      subroutine set(work)
c
      integer  nint
      common /sizes/ nint
c
      integer  i
      real work(nint)
c
      do 10 i=1,nint
         work(i)=real(i)**2
 10   continue
c
      end
c-------------------------
c
      subroutine output(work)
c
      integer  nint
      common /sizes/ nint
c
      integer  i
      real work(nint)
c
      do 10 i=1,nint
         print*,work(i)
 10   continue
c
      end
c
Dies mach ich mit

f2py test.f -m test -h test.pyf

Code: Alles auswählen

Reading fortran codes...
	Reading file 'test.f' (format:fix,strict)
Post-processing...
	Block: test
			Block: test
			Block: set
			Block: output
Post-processing (stage 2)...
Saving signatures to file "./test.pyf"
gefolgt von
f2py -c test.pyf test.f --f90exec=/usr/bin/gfortran

Code: Alles auswählen

running build
running config_cc
unifing config_cc, config, build_clib, build_ext, build commands --compiler options
running config_fc
unifing config_fc, config, build_clib, build_ext, build commands --fcompiler options
running build_src
building extension "test" sources
creating /tmp/tmpYFlHNR
creating /tmp/tmpYFlHNR/src.linux-i686-2.5
f2py options: []
f2py: test.pyf
Reading fortran codes...
	Reading file 'test.pyf' (format:free)
Post-processing...
	Block: test
			Block: set
			Block: output
Post-processing (stage 2)...
Building modules...
	Building module "test"...
		Constructing wrapper function "set"...
		  set(work)
		Constructing wrapper function "output"...
		  output(work)
		Constructing COMMON block support for "sizes"...
		  nint
	Wrote C/API module "test" to file "/tmp/tmpYFlHNR/src.linux-i686-2.5/testmodule.c"
	Fortran 77 wrappers are saved to "/tmp/tmpYFlHNR/src.linux-i686-2.5/test-f2pywrappers.f"
  adding '/tmp/tmpYFlHNR/src.linux-i686-2.5/fortranobject.c' to sources.
  adding '/tmp/tmpYFlHNR/src.linux-i686-2.5' to include_dirs.
copying /usr/lib/python2.5/site-packages/numpy/f2py/src/fortranobject.c -> /tmp/tmpYFlHNR/src.linux-i686-2.5
copying /usr/lib/python2.5/site-packages/numpy/f2py/src/fortranobject.h -> /tmp/tmpYFlHNR/src.linux-i686-2.5
  adding '/tmp/tmpYFlHNR/src.linux-i686-2.5/test-f2pywrappers.f' to sources.
running build_ext
customize UnixCCompiler
customize UnixCCompiler using build_ext
customize GnuFCompiler
Could not locate executable g77
Could not locate executable f77
customize IntelFCompiler
Found executable /usr/bin/gfortran
Found executable /usr/bin/ifort
customize LaheyFCompiler
Could not locate executable lf95
lahey: no Fortran 77 compiler found
lahey: no Fortran 77 compiler found
customize PGroupFCompiler
Could not locate executable pgf77
pg: no Fortran 77 compiler found
Could not locate executable pgf90
pg: no Fortran 77 compiler found
customize AbsoftFCompiler
absoft: no Fortran 77 compiler found
absoft: no Fortran 77 compiler found
customize NAGFCompiler
Found executable /usr/bin/f95
customize VastFCompiler
customize GnuFCompiler
customize CompaqFCompiler
Could not locate executable fort
compaq: no Fortran 77 compiler found
compaq: no Fortran 77 compiler found
customize IntelItaniumFCompiler
customize IntelEM64TFCompiler
customize Gnu95FCompiler
Found executable /usr/bin/gfortran
customize Gnu95FCompiler
customize Gnu95FCompiler using build_ext
building 'test' extension
compiling C sources
C compiler: gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC

creating /tmp/tmpYFlHNR/tmp
creating /tmp/tmpYFlHNR/tmp/tmpYFlHNR
creating /tmp/tmpYFlHNR/tmp/tmpYFlHNR/src.linux-i686-2.5
compile options: '-I/tmp/tmpYFlHNR/src.linux-i686-2.5 -I/usr/lib/python2.5/site-packages/numpy/core/include -I/usr/include/python2.5 -c'
gcc: /tmp/tmpYFlHNR/src.linux-i686-2.5/testmodule.c


/tmp/tmpYFlHNR/src.linux-i686-2.5/testmodule.c: In Funktion »f2py_rout_test_set«:
/tmp/tmpYFlHNR/src.linux-i686-2.5/testmodule.c:150: Fehler: »nint« nicht deklariert (erste Benutzung in dieser Funktion)
/tmp/tmpYFlHNR/src.linux-i686-2.5/testmodule.c:150: Fehler: (Jeder nicht deklarierte Bezeichner wird nur einmal aufgeführt
/tmp/tmpYFlHNR/src.linux-i686-2.5/testmodule.c:150: Fehler: für jede Funktion in der er auftritt.)
/tmp/tmpYFlHNR/src.linux-i686-2.5/testmodule.c: In Funktion »f2py_rout_test_output«:
/tmp/tmpYFlHNR/src.linux-i686-2.5/testmodule.c:232: Fehler: »nint« nicht deklariert (erste Benutzung in dieser Funktion)
/tmp/tmpYFlHNR/src.linux-i686-2.5/testmodule.c: In Funktion »f2py_rout_test_set«:
/tmp/tmpYFlHNR/src.linux-i686-2.5/testmodule.c:150: Fehler: »nint« nicht deklariert (erste Benutzung in dieser Funktion)
/tmp/tmpYFlHNR/src.linux-i686-2.5/testmodule.c:150: Fehler: (Jeder nicht deklarierte Bezeichner wird nur einmal aufgeführt
/tmp/tmpYFlHNR/src.linux-i686-2.5/testmodule.c:150: Fehler: für jede Funktion in der er auftritt.)
/tmp/tmpYFlHNR/src.linux-i686-2.5/testmodule.c: In Funktion »f2py_rout_test_output«:
/tmp/tmpYFlHNR/src.linux-i686-2.5/testmodule.c:232: Fehler: »nint« nicht deklariert (erste Benutzung in dieser Funktion)
error: Command "gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/tmp/tmpYFlHNR/src.linux-i686-2.5 -I/usr/lib/python2.5/site-packages/numpy/core/include -I/usr/include/python2.5 -c /tmp/tmpYFlHNR/src.linux-i686-2.5/testmodule.c -o /tmp/tmpYFlHNR/tmp/tmpYFlHNR/src.linux-i686-2.5/testmodule.o" failed with exit status 1
Wie ihr seht bekomme ich den Fehler, dass nint nicht deklariert ist. Leider weiß ich momentan nicht wie ich das Problem lösen könnte ohne den kompletten Quelltext umzustrukturieren.
Mit gfortran, pathf90 und ifort kann ich den Quelltext problemlos übersetzen, also denke ich, dass der Fehler bei f2py liegt.

Wer kann mir helfen???
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Sonntag 20. Juli 2008, 22:23

Hallo und willkommen im Forum,

nein, der Fehler liegt tatsächlich bei Dir und nicht f2py ;-).

Du kannst keine ganzen Programme übersetzen. f2py ist dazu da Funktionen / subroutines in Python aufrufen zu können. Was Du möchtest ist vielleicht:

Code: Alles auswählen

      subroutine set(work, s)
c
      INTEGER  s,i
Cf2py intent(in) s
      REAL*8 work(s)
Cf2py intent(out) work
      do 10 i=1,s
         work(i)=real(i)**2
 10   continue
c
      end
Wenn Du das übersetzt ($ f2py -c -m forum pythonforum.f --f90exec=/usr/bin/gfortran ) kannst Du in Python folgendes machen:

Code: Alles auswählen

>>> from forum import set
>>> x = set(3)
>>> x
array([ 1.,  4.,  9.])
Ist das ungefähr was Du suchst? Wie Du im Code gesehen hast, mußt Du f2py außerdem sagen, was die Funktion als Rückgabewert haben soll.

Noch eine Bemerkung zum Schluß: Du nutzt hoffentlich nicht das alte f2py, sondern das in numpy eingeschlossene? Mehr Info findest Du hier: http://www.scipy.org/F2py und auf der scipy-Mailingliste. (Ist wahrscheinlich Eulen nach Athen tragen, aber sicherheitshalber hier einmal aufgeführt.)

Gruß,
Christian

edit: intent(in) nachgetragen, außerdem: Ok, F90 sieht etwas anders aus, aber auch dazu gibt es Infor auf der scipy-Website verlinkt.
darkstone
User
Beiträge: 3
Registriert: Samstag 19. Juli 2008, 11:54

Montag 21. Juli 2008, 07:58

Das Problem daran ist, dass die Quelltexte für mich unveränderbar sind (zumindest so gut wie).

Das Programm hier stellt nur ein Beispiel dar, mit dem ich das gleiche Problem hab.

Die Commonblöcke ziehen sich durch das ganze Programm.

Das sind 35MB reiner Quelltext.

Aber danke trozdem... momentan tappe ich nämlich noch im Dunkeln

Andere Versionen hab ich auch schon ausprobiert. Momenten sogar die Version
Version: 2_4422 (3gf2py)
numpy Version: 1.0.4
dann noch verstion 2.4 und 2.5
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Montag 21. Juli 2008, 10:18

Hallo,

oh, tut mir leid. Ich habe mich schon lange nicht mehr mit Fortranwrapping beschäftigt. common-Blöcke sind möglich. Vor allem aber ist es möglich "F90 module data" zu nutzen. Ich habe das bei mir getestet und mit dem f77-Beispiel hatte ich keine Probleme, aber das f90-Beispiel bekomme ich nicht zum Laufen.

Vielleicht magst Du doch mal auf der numpy-Mailingliste nachfragen? Mir ist aber immer noch nicht verständlich, wieso Du ein *Programm* kompilieren und in Python einbinden willst und nicht ein *Modul*.

Gruß,
Christian
darkstone
User
Beiträge: 3
Registriert: Samstag 19. Juli 2008, 11:54

Dienstag 22. Juli 2008, 07:53

Hier noch ein weiteres Beispiel bei dem der Gleiche Fehler auftritt. Wiedermal erkennt er die Variablen im Commonblock nicht.

hier die main.f

Code: Alles auswählen

      program test

c

      integer  n1, n2

      common /sizes/ n1, n2

c

c dimension of array 'work' must be >= n1*n2 (set in subroutine 'set')

c

      real  work(1000)

c

      call set

c

      call compute(work)

c

      call output(work)

c

      end

c

und hier die passende sub.f

Code: Alles auswählen

c---------------

c

      subroutine set

c

      integer  n1, n2

      common /sizes/ n1, n2

c

      n1 = 5

      n2 = 10

c

      end



c---------------

c

      subroutine compute (work)

c

      integer  n1, n2

      common /sizes/ n1, n2

c

      integer  i,j

      real work(n1,n2)

c

      do 20 j=1,n2

         do 10 i=1,n1

            work(i,j) = real(i) * real(j)**2

 10      continue

 20   continue

c

      end



c-------------------------

c

      subroutine output(work)

c

      integer  nint

      common /sizes/ n1, n2

c

      integer  i, j

      real work(n1, n2)

c

      do 20 j=1,n2

         do 10 i=1,n1

            print*, i, '*',  j, '**2 = ', work(i,j)

 10      continue

 20   continue

c

      end

c


Es besteht weiterhin das Problem, dass f2py an der stelle wo er das C-Mudul erstellt Fehler ausgibt (vom gcc).

z.B.
" »n1« nicht deklariert (erste Benutzung in dieser Funktion)"

Mailingliste werde ich heute auch noch nutzen. Irgendwie muss das doch zu machen sein!!!
Antworten