LIB: Difference between revisions

1,137 bytes added ,  3 April
m
link to documentation
(→‎Client code example: separate assignment of cformat from its definition. Reason: otherwise, a static variable results)
m (link to documentation)
 
(10 intermediate revisions by the same user not shown)
Line 1: Line 1:
The possibility of using external libraries (that are loaded at runtime) has been available in C/C++ for a long time, but in Fortran became only available as of Fortran2003.  
The possibility of using external libraries (that are loaded at runtime) has been available in C/C++ for a long time, but in Fortran became only available as of Fortran2003.  


In the case of XDS, frame-reading and computation can be separated starting with version November-2016. This allows users/companies to develop their own specialized frame-reading libraries, and relieves the XDS maintainers from implementing even more file formats. The feature was developed in order to be able to natively (i.e. without temporary intermediates) read the HDF5 files written for data from the [[Eiger]] detector.
In the case of XDS, frame-reading and computation can be separated starting with version November-2016. The [https://xds.mr.mpg.de/html_doc/xds_parameters.html#LIB= LIB=] keyword allows users/companies to develop their own specialized frame-reading libraries, and relieves the XDS maintainers from implementing even more file formats. The feature was developed in order to be able to natively (i.e. without temporary intermediates) read the HDF5 files written for data from the [[Eiger]] detector.


In the following, small examples are given for
In the following, small examples are given for
Line 22: Line 22:
! ifort -qopenmp generic_data_plugin.f90 test_generic_host.f90 -o test_generic_host
! ifort -qopenmp generic_data_plugin.f90 test_generic_host.f90 -o test_generic_host
! or
! or
! gfortran -O -fopenmp -ldl generic_data_plugin.f90 test_generic_host.f90 -o test_generic_host
! gfortran -O -fopenmp generic_data_plugin.f90 test_generic_host.f90 -ldl -o test_generic_host
! run with  
! run with  
! ./test_generic_host < test.in
! ./test_generic_host < test.in
Line 122: Line 122:
! This reads single data files which have a header of 7680 bytes
! This reads single data files which have a header of 7680 bytes
! Kay Diederichs 4/2017
! Kay Diederichs 4/2017
! Kay Diederichs 7/2021 add code for the case that fn_template has no '?', and simplify&comment gfortran command.
!
! compile with
! compile with
! ifort -fpic -shared -static-intel -qopenmp -traceback -sox test_generic_client.f90 -o libtest_generic_client.so
! ifort -fpic -shared -static-intel -qopenmp -qopenmp-link=static -traceback -sox test_generic_client.f90 -o libtest_generic_client.so
! (this includes all required compiler libraries into the libtest_generic_client.so library)
! or
! or
! gfortran -c -fpic test_generic_client.f90 && ld -shared test_generic_client.o -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5/ -lgfortran -o libtest_generic_client.so
! gfortran -fpic test_generic_client.f90 -shared -o libtest_generic_client.so
! (attention: the above - from "gfortran" to "libtest_generic_client.so" - is one looong line)
! (this does not include the compiler's libgfortran.so and libquadmath.so into the library; don't know how to achieve this so
! gfortran is only useful if it is anyway installed on the machine)
! The resulting file can be used with a LIB=./libtest_generic_client.so line in XDS.INP, and enables
! The resulting file can be used with a LIB=./libtest_generic_client.so line in XDS.INP, and enables
! reading of data files with a 7680 bytes header plus 1024*1024 pixels of integer data, without any record structure.
! reading of data files with a 7680 bytes header plus 1024*1024 pixels of integer data, without any record structure.


MODULE plugin_test_mod
MODULE plugin_test_mod
       CHARACTER :: fn_template*132=''
       CHARACTER :: fn_template*132='',cformat*6='(i4.4)'
       INTEGER  :: lenfn,firstqm,lastqm
       INTEGER  :: lenfn,firstqm,lastqm
END MODULE
END MODULE
Line 154: Line 158:
       firstqm=INDEX(fn_template,'?')
       firstqm=INDEX(fn_template,'?')
       lastqm =INDEX(fn_template,'?',BACK=.TRUE.)
       lastqm =INDEX(fn_template,'?',BACK=.TRUE.)
      IF (firstqm==0) THEN
        firstqm=lenfn-7
        lastqm =lenfn-4
      END IF
      WRITE(cformat(3:5),'(i1,a1,i1)')lastqm-firstqm+1,'.',lastqm-firstqm+1
END SUBROUTINE plugin_open
END SUBROUTINE plugin_open
!
!
Line 184: Line 193:
! local variables
! local variables
     INTEGER k,i,dummy
     INTEGER k,i,dummy
     CHARACTER :: fn*132,cformat*6
     CHARACTER :: fn*132
    cformat='(i4.4)'
     fn=fn_template
     fn=fn_template
    WRITE(cformat(3:5),'(i1,a1,i1)')lastqm-firstqm+1,'.',lastqm-firstqm+1
     IF (frame_number>0) WRITE(fn(firstqm:lastqm),cformat) frame_number
     IF (frame_number>0) WRITE(fn(firstqm:lastqm),cformat) frame_number
! -qopenmp compile option needs to be used otherwise race in writing fn
! -qopenmp compile option needs to be used otherwise race in writing fn
Line 253: Line 260:
        
        
       interface ! strlen is a standard C function from <string.h>
       interface ! strlen is a standard C function from <string.h>
         function strlen(string) result(len) bind(C,name="strlen")
         integer(int64) function strlen(string) result(len) bind(C,name="strlen")
            use iso_fortran_env, only : int64
             use iso_c_binding
             use iso_c_binding
             type(c_ptr), value :: string ! a C pointer
             type(c_ptr), value :: string ! a C pointer
Line 647: Line 655:


     ! now close the dl:
     ! now close the dl:
     status=dlclose(handle)
     status=0  ! inserted Feb 3, 2021 KD
!    status=dlclose(handle) ! commented out Feb 3, 2021 KD
     if(status/=0) then
     if(status/=0) then
       write(6,*) "[generic_data_plugin] - ERROR - Cannot open Handle"
       write(6,*) "[generic_data_plugin] - ERROR - Cannot open Handle"
Line 672: Line 681:
#3  0x00000000409b873d in clone () from /lib64/libc.so.6
#3  0x00000000409b873d in clone () from /lib64/libc.so.6
</pre>
</pre>
Google returns https://github.com/apple/cups/issues/4410 and https://bugzilla.redhat.com/show_bug.cgi?id=1065695 when searching for similar problems. Overall, this appears to be harmless and in fact I don't know how to change the code to make the segfault disappear  - I'd appreciate a patch!
Google returns https://github.com/apple/cups/issues/4410 and https://bugzilla.redhat.com/show_bug.cgi?id=1065695 when searching for similar problems. Overall, this appears to be harmless and in fact I don't know how to change the code to make the segfault disappear  - I'd appreciate a patch!  
Feb 3, 2021: commented out the line 'status=dlclose(handle)' and replaced it with 'status=0'. According to Sebastian Thorarensen this has no negative consequences on XDS, and solves the segfault problem.


== Existing implementations ==
== Existing implementations ==


# [https://github.com/dectris/neggia Dectris Neggia-plugin] to read HDF5 written by Dectris-supplied software of Eiger detectors
# [https://github.com/dectris/neggia Dectris Neggia-plugin] to read HDF5 written by Dectris-supplied software of Eiger detectors
# [https://github.com/DiamondLightSource/durin Diamond's Durin-plugin] to read HDF5 written by Eiger detectors at Diamond; latest binaries for MacOS and Linux (RHEL6) as well as example XDS.INP and source at https://github.com/DiamondLightSource/durin/releases/latest
# [https://github.com/DiamondLightSource/durin Diamond's Durin-plugin] to read HDF5 written by Eiger detectors at Diamond (and presumably elsewhere); latest binaries for MacOS and Linux (RHEL6) as well as example XDS.INP and source at https://github.com/DiamondLightSource/durin/releases/latest . A binary for M1 Mac is available - see [[Installation]]
# [https://git.embl.de/nikolova/xds-zcbf/ EMBL-Hamburg's zcbf-plugin] to read gzip-compressed CBF files without intermediate file
# [https://git.embl.de/nikolova/xds-zcbf/ EMBL-Hamburg's zcbf-plugin] to read gzip-compressed CBF files without intermediate file . A binary for M1 Mac is available - see [[Installation]].
 
Plugins for Linux and Intel-Mac can also be obtained through [https://www.globalphasing.com/autoproc/ GPhL's autoPROC].
 
See also [[Installation]].
 
== See also ==
# https://rosettacode.org/wiki/Call_a_function_in_a_shared_library#GNU_Fortran_on_Linux
2,653

edits