[Q-e-developers] [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/developers/attachments/20130410/61f06939/attachment.html>
More information about the developers
mailing list