[Pw_forum] compile as a C++ library (prototype)

Filippo Spiga spiga.filippo at gmail.com
Wed Apr 10 18:34:12 CEST 2013


Dear Denis,

this is an interesting proof of concepts actually, good job. I am
personally curious to understand more about how you are planning to use
PWscf as a library by coupling it with other codes (C/C++ codes presumably
or pre-/post-processing tools. Sharing your view might help to understand
how to improve the user usage experience of PWscf and QE in general.

Regards,
Filippo



--
Mr. Filippo SPIGA, M.Sc.
http://filippospiga.me ~ skype: filippo.spiga

«Nobody will drive us out of Cantor's paradise.» ~ David Hilbert



On Mon, Apr 8, 2013 at 5:35 PM, Denis Davydov <davydden at gmail.com> wrote:

> Dear all,
>
> After some trial and error, following advices given here, i come up with
> the solution on how to make a c++ library from PW with a controllable MPI
> communicator. Everything compiles fine with a small example, but i did not
> yet implement passing input file name.
>
> In a hope that it will be useful / interesting for other users /
> developers, i write a quick list of how to achieve it below.
> Things can definitely be made more pretty, i would be grateful for any
> advices.
> Maybe a more clean version of this can make it to a release one day. I
> think such an interface makes it easier to combine different codes while
> having a full control over MPI.
> .check_pw.x.j  runs fine so far.  I did not try anything else yet.
>
> I hope the content below is appropriate for this mailing list, please,
> excuse me if it is not.
>
> HOWTO:
> 1. pwscf.f90 -- i wrapped the main function in another function.
>
> PROGRAM pwscf
>   USE parallel_include
> !
>   INTEGER :: comm = mpi_comm_world
>   INTEGER :: sz
>   CHARACTER(len=256) ::name
>   INTEGER :: do_init = 1
>   WRITE (*,*) ' pwscf  do_init= ', do_init
>
>   CALL pwscf2(comm,do_init,name,sz)
>
> END PROGRAM pwscf
> SUBROUTINE pwscf2 (input_comm,do_init, in_string,in_size)
>> USE parallel_include
>> INTEGER,  INTENT (IN)            :: input_comm
> CHARACTER(len=256), INTENT (IN)  :: in_string
> INTEGER, INTENT (IN)             :: in_size
> INTEGER, INTENT (IN)             :: do_init
>
> #ifdef __MPI
>   !
>   CALL set_mp_comm(input_comm, do_init)
>>
> 2. In parallel_include.f90 the last function in the above is defined as:
> ...
> INTEGER, PUBLIC :: qe_mp_world = mpi_comm_world
> LOGICAL, PUBLIC :: do_mpi_init = .TRUE.
>> CONTAINS
>
>     SUBROUTINE set_mp_comm(comm, do_init)
>         IMPLICIT NONE
>         INTEGER, INTENT(IN) :: comm
>         INTEGER, INTENT(IN) :: do_init
>
>         do_mpi_init = (do_init.EQ.1)
>         qe_mp_world = comm
>
>         RETURN
>       END SUBROUTINE set_mp_comm
>
> 3. In mp.f90 and mp_global.f90 i replaced all the occurrence of
> mpi_comm_world with a new
> communicator qe_mp_world, which by default is equal to mpi_comm_world.
> In addition MPI_Init and MPI_Finalized are wrapped in IF statement, e.g.
> IF (do_mpi_init) CALL mpi_init(ierr).
> We don't want to run those if MPI was initialized already externally.
>
> 4. a c++ wrapper looks like:
> #include "pw.h"
>
> extern"C" {
>   void pwscf2_(int * comm,int *do_init , char *file, int * size);
> }
>
> void qe_run(char *name, MPI_Comm my_comm )
> {
>    MPI_Fint    fcomm;
>    fcomm = MPI_Comm_c2f(my_comm);
>    int size = sizeof(name);
>    int do_init = 0;
>    pwscf2_(&fcomm, &do_init, name, &size);
> }
>
> with a trivial header:
> #include "mpi.h"
> void qe_run(char *name, MPI_Comm my_comm );
>
> The whole thing can be run as:
> #include "pw.h"
> using namespace std;
>
> int
> main(int argc, char* argv[])
> {
> // Initialize the MPI library:
>  MPI::Init(argc, argv);
>
> int me,nprocs;
>  MPI_Comm_rank(MPI_COMM_WORLD,&me);
> MPI_Comm_size(MPI_COMM_WORLD,&nprocs);
>
> char name [] = "my_input.in";
>  qe_run(name, MPI_COMM_WORLD);
>
> // Tell the MPI library to release all resources it is using:
>  MPI::Finalize();
> return 0;
> }
>
> 5. Compiling:
> All the c++ files are compiled in a usual way with mpic++.
> The wrapper-library is compiled within PW/Makefile using:
>
> MPI_LINK_FLAGS = $(shell mpic++ --showme:link)
> CPP_LINK_FLAGS = -L/opt/local/lib/gcc47/ -lstdc++
> libpwc++.a : pw.x
>  $(LD) -shared -fpic $(LDFLAGS) pw.o $(PWOBJS) libpw.a $(QEMODS)
> $(LIBOBJS) $(LIBS) $(MPI_LINK_FLAGS) $(CPP_LINK_FLAGS) -o $@
>
>
> I did not yet look at how to exactly to pass the input file,
> but that should not be a big deal anyway.
>
>
> Kind regards,
> Denis
>
>
> _______________________________________________
> Pw_forum mailing list
> Pw_forum at pwscf.org
> http://pwscf.org/mailman/listinfo/pw_forum
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.quantum-espresso.org/pipermail/users/attachments/20130410/61f06939/attachment.html>


More information about the users mailing list