Explorar o código

- preliminary steps for native Fortran support to StarPU-MPI

Olivier Aumage %!s(int64=9) %!d(string=hai) anos
pai
achega
6ff4416db6

+ 35 - 1
configure.ac

@@ -4,7 +4,7 @@
 # Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015  CNRS
 # Copyright (C) 2011  Télécom-SudParis
 # Copyright (C) 2011, 2012, 2014  INRIA
-# Copyright (C) 2015  Inria
+# Copyright (C) 2015, 2016  Inria
 #
 # StarPU is free software; you can redistribute it and/or modify
 # it under the terms of the GNU Lesser General Public License as published by
@@ -2133,9 +2133,43 @@ if test "x$FC" != "x"; then
 	fi
 	if test "x$enable_build_fortran" = "xyes" ; then
 		AC_DEFINE(STARPU_HAVE_FC, [], [Define this if a Fortran compiler is available])
+		if test x$use_mpi = xyes; then
+			AC_ARG_WITH(mpifort, [AS_HELP_STRING([--with-mpifort[=<path to mpifort>]],
+				    [Path of the mpifort compiler])],
+				    [
+				     if test x$withval = xyes; then
+					     AC_MSG_ERROR(--with-mpifort must be given a pathname)
+					     else
+						     mpifort_path=$withval
+					     fi
+					     ],
+					     [
+					      if test x$enable_simgrid = xyes ; then
+						      DEFAULT_MPIFORT=smpifort
+					      else
+						      DEFAULT_MPIFORT=mpifort
+					      fi
+					      # nothing was specified: default value is used
+					      AC_PATH_PROG(mpifort_path, $DEFAULT_MPIFORT, [no], [$simgrid_dir/bin:$PATH])
+					      ])
+
+			# We test if the MPIFORT compiler exists
+			if test ! -x $mpifort_path; then
+				#MPIFORT does not exists or is not executable
+				AC_MSG_RESULT(The mpifort compiler '$mpifort_path' does not have the execute permission)
+				use_mpi_fort=no
+			else
+				use_mpi_fort=yes
+
+				AC_MSG_CHECKING(mpifort path)
+				AC_MSG_RESULT($mpifort_path)
+				AC_SUBST(MPIFORT, $mpifort_path)
+			fi
+		fi
 	fi
 fi
 AM_CONDITIONAL([STARPU_HAVE_FC], [test "x$FC" != "x" -a "x$enable_build_fortran" = "xyes"])
+AM_CONDITIONAL([STARPU_HAVE_MPIFORT], [test "x$FC" != "x" -a "x$enable_build_fortran" = "xyes" -a "x$MPIFORT" != "x"])
 
 ###############################################################################
 #                                                                             #

+ 2 - 0
mpi/Makefile.am

@@ -2,6 +2,7 @@
 #
 # Copyright (C) 2009-2013, 2015  Université de Bordeaux
 # Copyright (C) 2010, 2011, 2012, 2013  CNRS
+# Copyright (C) 2016  Inria
 #
 # StarPU is free software; you can redistribute it and/or modify
 # it under the terms of the GNU Lesser General Public License as published by
@@ -21,6 +22,7 @@ pkgconfig_DATA = libstarpumpi.pc starpumpi-1.0.pc starpumpi-1.1.pc starpumpi-1.2
 
 versincludedir = $(includedir)/starpu/$(STARPU_EFFECTIVE_VERSION)
 versinclude_HEADERS = 					\
+	include/fstarpu_mpi_mod.f90			\
 	include/starpu_mpi.h
 
 showcheck:

+ 55 - 0
mpi/examples/Makefile.am

@@ -2,6 +2,7 @@
 #
 # Copyright (C) 2009-2013, 2015-2016  Université de Bordeaux
 # Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016  CNRS
+# Copyright (C) 2016  Inria
 #
 # StarPU is free software; you can redistribute it and/or modify
 # it under the terms of the GNU Lesser General Public License as published by
@@ -18,6 +19,8 @@ include $(top_srcdir)/starpu.mk
 
 CC=$(MPICC)
 CCLD=$(MPICC)
+FC=$(MPIFORT)
+FCLD=$(MPIFORT)
 
 if STARPU_HAVE_WINDOWS
 LOADER_BIN		=
@@ -263,6 +266,32 @@ starpu_mpi_EXAMPLES +=				\
 	matrix_mult/mm
 endif
 
+##########################################
+# Native Fortran MPI Matrix mult example #
+##########################################
+
+if STARPU_HAVE_MPIFORT
+if BUILD_EXAMPLES
+if !STARPU_SANITIZE
+examplebin_PROGRAMS +=		\
+	native_fortran/nf_mm
+
+native_fortran_nf_mm_SOURCES	=			\
+	native_fortran/nf_mm_cl.f90			\
+	$(top_srcdir)/mpi/include/fstarpu_mpi_mod.f90	\
+	$(top_srcdir)/include/fstarpu_mod.f90		\
+	native_fortran/nf_mm.f90
+
+native_fortran_nf_mm_LDADD =					\
+	../src/libstarpumpi-@STARPU_EFFECTIVE_VERSION@.la	\
+	-lm
+
+starpu_mpi_EXAMPLES +=				\
+	native_fortran/nf_mm
+endif
+endif
+endif
+
 ###################
 # complex example #
 ###################
@@ -320,3 +349,29 @@ starpu_mpi_EXAMPLES	+=			\
 	comm/mix_comm
 endif
 
+if STARPU_HAVE_MPIFORT
+if BUILD_EXAMPLES
+if !STARPU_SANITIZE
+# Native Fortran example
+# - list explicit dependences to control proper module files generation
+# - the overriding rule fully disables the corresponing default rule, thus
+#   the default rule body must be copied entirely
+fstarpu_mod.mod: fstarpu_mod.o
+fstarpu_mpi_mod.mod: fstarpu_mpi_mod.o
+nf_mm_cl.mod: nf_mm_cl.o
+
+fstarpu_mod.o: $(top_srcdir)/include/fstarpu_mod.f90
+	$(AM_V_FC)$(FC) $(native_fortran_nf_mm_FCFLAGS) $(FCFLAGS) -c -o $@ '$(top_srcdir)/'include/fstarpu_mod.f90
+
+fstarpu_mpi_mod.o: $(top_srcdir)/mpi/include/fstarpu_mpi_mod.f90 fstarpu_mod.mod
+	$(AM_V_FC)$(FC) $(native_fortran_nf_mm_FCFLAGS) $(FCFLAGS) -c -o $@ '$(top_srcdir)/'mpi/include/fstarpu_mpi_mod.f90
+
+nf_mm_cl.o: $(top_srcdir)/mpi/examples/native_fortran/nf_mm_cl.f90 fstarpu_mpi_mod.mod fstarpu_mod.mod
+	$(AM_V_FC)$(FC) $(native_fortran_nf_mm_FCFLAGS) $(FCFLAGS) -c -o $@ `test -f 'native_fortran/nf_mm_cl.f90' || echo '$(srcdir)/'`native_fortran/nf_mm_cl.f90
+
+nf_mm.o: $(top_srcdir)/mpi/examples/native_fortran/nf_mm.f90 nf_mm_cl.mod fstarpu_mpi_mod.mod fstarpu_mod.mod
+	$(AM_V_FC)$(FC) $(native_fortran_nf_mm_FCFLAGS) $(FCFLAGS) -c -o $@ `test -f 'native_fortran/nf_mm.f90' || echo '$(srcdir)/'`native_fortran/nf_mm.f90
+
+endif
+endif
+endif

+ 53 - 0
mpi/examples/native_fortran/nf_mm.f90

@@ -0,0 +1,53 @@
+! StarPU --- Runtime system for heterogeneous multicore architectures.
+!
+! Copyright (C) 2016  Inria
+!
+! StarPU is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Lesser General Public License as published by
+! the Free Software Foundation; either version 2.1 of the License, or (at
+! your option) any later version.
+!
+! StarPU is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+!
+! See the GNU Lesser General Public License in COPYING.LGPL for more details.
+
+program nf_mm
+        use iso_c_binding       ! C interfacing module
+        use fstarpu_mod         ! StarPU interfacing module
+        use fstarpu_mpi_mod     ! StarPU-MPI interfacing module
+        use nf_mm_cl
+        implicit none
+
+        integer(c_int) :: ncpu
+        integer(c_int) :: ret
+
+        ret = fstarpu_mpi_init(1)
+        print *,"fstarpu_mpi_init status:", ret
+        if (ret /= 0) then
+                stop 1
+        end if
+
+        ret = fstarpu_init(C_NULL_PTR)
+        if (ret == -19) then
+                stop 77
+        else if (ret /= 0) then
+                stop 1
+        end if
+
+        ! stop there if no CPU worker available
+        ncpu = fstarpu_cpu_worker_get_count()
+        if (ncpu == 0) then
+                call fstarpu_shutdown()
+                stop 77
+        end if
+
+        call fstarpu_shutdown()
+
+        ret = fstarpu_mpi_shutdown()
+        print *,"fstarpu_mpi_shutdown status:", ret
+        if (ret /= 0) then
+                stop 1
+        end if
+end program nf_mm

+ 25 - 0
mpi/examples/native_fortran/nf_mm_cl.f90

@@ -0,0 +1,25 @@
+! StarPU --- Runtime system for heterogeneous multicore architectures.
+!
+! Copyright (C) 2016  Inria
+!
+! StarPU is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Lesser General Public License as published by
+! the Free Software Foundation; either version 2.1 of the License, or (at
+! your option) any later version.
+!
+! StarPU is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+!
+! See the GNU Lesser General Public License in COPYING.LGPL for more details.
+
+module nf_mm_cl
+contains
+recursive subroutine cl_cpu_mult (buffers, cl_args) bind(C)
+        use iso_c_binding       ! C interfacing module
+        use fstarpu_mod         ! StarPU interfacing module
+        implicit none
+
+        type(c_ptr), value, intent(in) :: buffers, cl_args ! cl_args is unused
+end subroutine cl_cpu_mult
+end module nf_mm_cl

+ 196 - 0
mpi/include/fstarpu_mpi_mod.f90

@@ -0,0 +1,196 @@
+! StarPU --- Runtime system for heterogeneous multicore architectures.
+!
+! Copyright (C) 2016  Inria
+!
+! StarPU is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Lesser General Public License as published by
+! the Free Software Foundation; either version 2.1 of the License, or (at
+! your option) any later version.
+!
+! StarPU is distributed in the hope that it will be useful, but
+! WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+!
+! See the GNU Lesser General Public License in COPYING.LGPL for more details.
+
+module fstarpu_mpi_mod
+        use iso_c_binding
+        use fstarpu_mod
+        implicit none
+
+        ! TODO:
+        ! starpu_mpi_data_register
+        ! starpu_mpi_get_data_on_node
+        ! starpu_mpi_data_set_rank
+        ! starpu_mpi_init
+        ! starpu_mpi_shutdown
+        ! starpu_mpi_comm_rank
+        ! starpu_mpi_comm_size
+        ! starpu_mpi_task_insert
+
+        interface
+                ! == mpi/include/starpu_mpi.h ==
+                ! int starpu_mpi_isend(starpu_data_handle_t data_handle, starpu_mpi_req *req, int dest, int mpi_tag, MPI_Comm comm);
+                ! int starpu_mpi_irecv(starpu_data_handle_t data_handle, starpu_mpi_req *req, int source, int mpi_tag, MPI_Comm comm);
+                ! int starpu_mpi_send(starpu_data_handle_t data_handle, int dest, int mpi_tag, MPI_Comm comm);
+                ! int starpu_mpi_recv(starpu_data_handle_t data_handle, int source, int mpi_tag, MPI_Comm comm, MPI_Status *status);
+                ! int starpu_mpi_isend_detached(starpu_data_handle_t data_handle, int dest, int mpi_tag, MPI_Comm comm, void (*callback)(void *), void *arg);
+                ! int starpu_mpi_irecv_detached(starpu_data_handle_t data_handle, int source, int mpi_tag, MPI_Comm comm, void (*callback)(void *), void *arg);
+                ! int starpu_mpi_issend(starpu_data_handle_t data_handle, starpu_mpi_req *req, int dest, int mpi_tag, MPI_Comm comm);
+                ! int starpu_mpi_issend_detached(starpu_data_handle_t data_handle, int dest, int mpi_tag, MPI_Comm comm, void (*callback)(void *), void *arg);
+                ! int starpu_mpi_wait(starpu_mpi_req *req, MPI_Status *status);
+                ! int starpu_mpi_test(starpu_mpi_req *req, int *flag, MPI_Status *status);
+                ! int starpu_mpi_barrier(MPI_Comm comm);
+                ! int starpu_mpi_irecv_detached_sequential_consistency(starpu_data_handle_t data_handle, int source, int mpi_tag, MPI_Comm comm, void (*callback)(void *), void *arg, int sequential_consistency);
+
+                ! int starpu_mpi_init_comm(int *argc, char ***argv, int initialize_mpi, MPI_Comm comm);
+                ! -> cf fstarpu_mpi_init
+                ! int starpu_mpi_init(int *argc, char ***argv, int initialize_mpi);
+                ! -> cf fstarpu_mpi_init
+
+                ! int starpu_mpi_initialize(void) STARPU_DEPRECATED;
+                ! -> cf fstarpu_mpi_init
+                ! int starpu_mpi_initialize_extended(int *rank, int *world_size) STARPU_DEPRECATED;
+                ! -> cf fstarpu_mpi_init
+
+                ! int starpu_mpi_shutdown(void);
+                function fstarpu_mpi_shutdown () bind(C,name="starpu_mpi_shutdown")
+                        use iso_c_binding
+                        implicit none
+                        integer(c_int) :: fstarpu_mpi_shutdown
+                end function fstarpu_mpi_shutdown
+
+                ! struct starpu_task *starpu_mpi_task_build(MPI_Comm comm, struct starpu_codelet *codelet, ...);
+                ! int starpu_mpi_task_post_build(MPI_Comm comm, struct starpu_codelet *codelet, ...);
+                ! int starpu_mpi_task_insert(MPI_Comm comm, struct starpu_codelet *codelet, ...);
+                ! /* the function starpu_mpi_insert_task has the same semantics as starpu_mpi_task_insert, it is kept to avoid breaking old codes */
+                ! int starpu_mpi_insert_task(MPI_Comm comm, struct starpu_codelet *codelet, ...);
+                ! void starpu_mpi_get_data_on_node(MPI_Comm comm, starpu_data_handle_t data_handle, int node);
+                ! void starpu_mpi_get_data_on_node_detached(MPI_Comm comm, starpu_data_handle_t data_handle, int node, void (*callback)(void*), void *arg);
+                ! void starpu_mpi_redux_data(MPI_Comm comm, starpu_data_handle_t data_handle);
+                ! int starpu_mpi_scatter_detached(starpu_data_handle_t *data_handles, int count, int root, MPI_Comm comm, void (*scallback)(void *), void *sarg, void (*rcallback)(void *), void *rarg);
+                ! int starpu_mpi_gather_detached(starpu_data_handle_t *data_handles, int count, int root, MPI_Comm comm, void (*scallback)(void *), void *sarg, void (*rcallback)(void *), void *rarg);
+                ! int starpu_mpi_isend_detached_unlock_tag(starpu_data_handle_t data_handle, int dest, int mpi_tag, MPI_Comm comm, starpu_tag_t tag);
+                ! int starpu_mpi_irecv_detached_unlock_tag(starpu_data_handle_t data_handle, int source, int mpi_tag, MPI_Comm comm, starpu_tag_t tag);
+                ! int starpu_mpi_isend_array_detached_unlock_tag(unsigned array_size, starpu_data_handle_t *data_handle, int *dest, int *mpi_tag, MPI_Comm *comm, starpu_tag_t tag);
+                ! int starpu_mpi_irecv_array_detached_unlock_tag(unsigned array_size, starpu_data_handle_t *data_handle, int *source, int *mpi_tag, MPI_Comm *comm, starpu_tag_t tag);
+                ! void starpu_mpi_comm_amounts_retrieve(size_t *comm_amounts);
+                ! void starpu_mpi_cache_flush(MPI_Comm comm, starpu_data_handle_t data_handle);
+                ! void starpu_mpi_cache_flush_all_data(MPI_Comm comm);
+                ! int starpu_mpi_comm_size(MPI_Comm comm, int *size);
+                ! int starpu_mpi_comm_rank(MPI_Comm comm, int *rank);
+
+                ! int starpu_mpi_world_rank(void);
+                function fstarpu_mpi_world_rank() bind(C,name="starpu_mpi_world_rank")
+                        use iso_c_binding
+                        implicit none
+                        integer(c_int) :: fstarpu_mpi_world_rank
+                end function fstarpu_mpi_world_rank
+
+                ! int starpu_mpi_world_size(void);
+                function fstarpu_mpi_world_size() bind(C,name="starpu_mpi_world_size")
+                        use iso_c_binding
+                        implicit none
+                        integer(c_int) :: fstarpu_mpi_world_size
+                end function fstarpu_mpi_world_size
+
+                ! int starpu_mpi_get_communication_tag(void);
+                ! void starpu_mpi_set_communication_tag(int tag);
+                ! void starpu_mpi_data_register_comm(starpu_data_handle_t data_handle, int tag, int rank, MPI_Comm comm);
+                ! #define starpu_mpi_data_register(data_handle, tag, rank) starpu_mpi_data_register_comm(data_handle, tag, rank, MPI_COMM_WORLD)
+                ! void starpu_mpi_data_set_rank_comm(starpu_data_handle_t handle, int rank, MPI_Comm comm);
+                ! #define starpu_mpi_data_set_rank(handle, rank) starpu_mpi_data_set_rank_comm(handle, rank, MPI_COMM_WORLD)
+                ! void starpu_mpi_data_set_tag(starpu_data_handle_t handle, int tag);
+                ! #define starpu_data_set_rank starpu_mpi_data_set_rank
+                ! #define starpu_data_set_tag starpu_mpi_data_set_tag
+                ! int starpu_mpi_data_get_rank(starpu_data_handle_t handle);
+                ! int starpu_mpi_data_get_tag(starpu_data_handle_t handle);
+                ! #define starpu_data_get_rank starpu_mpi_data_get_rank
+                ! #define starpu_data_get_tag starpu_mpi_data_get_tag
+                ! #define STARPU_MPI_NODE_SELECTION_CURRENT_POLICY -1
+                ! #define STARPU_MPI_NODE_SELECTION_MOST_R_DATA    0
+                ! typedef int (*starpu_mpi_select_node_policy_func_t)(int me, int nb_nodes, struct starpu_data_descr *descr, int nb_data);
+                ! int starpu_mpi_node_selection_register_policy(starpu_mpi_select_node_policy_func_t policy_func);
+                ! int starpu_mpi_node_selection_unregister_policy(int policy);
+                ! int starpu_mpi_node_selection_get_current_policy();
+                ! int starpu_mpi_node_selection_set_current_policy(int policy);
+                ! int starpu_mpi_cache_is_enabled();
+                ! int starpu_mpi_cache_set(int enabled);
+                ! int starpu_mpi_wait_for_all(MPI_Comm comm);
+                ! int starpu_mpi_datatype_register(starpu_data_handle_t handle, starpu_mpi_datatype_allocate_func_t allocate_datatype_func, starpu_mpi_datatype_free_func_t free_datatype_func);
+                ! int starpu_mpi_datatype_unregister(starpu_data_handle_t handle);
+        end interface
+
+        contains
+                function fstarpu_mpi_init (initialize_mpi,mpi_comm) bind(C)
+                        use iso_c_binding
+                        implicit none
+                        integer(c_int) :: fstarpu_mpi_init
+                        integer(c_int), intent(in) :: initialize_mpi
+                        integer(c_int), optional, intent(in) :: mpi_comm
+                        type(c_ptr) :: argcv
+                        integer(c_int) :: fargc,i,farg_len
+                        character(len=1) :: farg_1
+                        character(len=:), allocatable :: farg
+                        integer(c_int) :: mpi_comm_present, mpi_comm_or_0
+                        integer(c_int) :: ret
+
+                        interface
+                                function fstarpu_mpi_argcv_alloc(argc, initialize_mpi, comm_present, comm) bind(C)
+                                        use iso_c_binding
+                                        implicit none
+                                        type(c_ptr) :: fstarpu_mpi_argcv_alloc
+                                        integer(c_int),value,intent(in) :: argc
+                                        integer(c_int),value,intent(in) :: initialize_mpi
+                                        integer(c_int),value,intent(in) :: comm_present
+                                        integer(c_int),value,intent(in) :: comm
+                                end function fstarpu_mpi_argcv_alloc
+
+                                subroutine fstarpu_mpi_argcv_set_arg(argcv, i, l, s) bind(C)
+                                        use iso_c_binding
+                                        implicit none
+                                        type(c_ptr),value,intent(in) :: argcv
+                                        integer(c_int),value,intent(in) :: i
+                                        integer(c_int),value,intent(in) :: l
+                                        character(c_char),intent(in) :: s
+                                end subroutine fstarpu_mpi_argcv_set_arg
+
+                                subroutine fstarpu_mpi_argcv_free(argcv) bind(C)
+                                        use iso_c_binding
+                                        implicit none
+                                        type(c_ptr),value,intent(in) :: argcv
+                                end subroutine fstarpu_mpi_argcv_free
+
+                                function fstarpu_mpi_init_c(argcv) bind(C)
+                                        use iso_c_binding
+                                        implicit none
+                                        integer(c_int) :: fstarpu_mpi_init_c
+                                        type(c_ptr),value,intent(in) :: argcv
+                                end function fstarpu_mpi_init_c
+                        end interface
+
+                        fargc = command_argument_count()
+                        write(*,*) "fargc",fargc
+                        if (present(mpi_comm)) then
+                                mpi_comm_present = 1
+                                mpi_comm_or_0 = mpi_comm
+                        else
+                                mpi_comm_present = 0
+                                mpi_comm_or_0 = 0
+                        end if
+                        write(*,*) "initialize_mpi",initialize_mpi
+                        write(*,*) "mpi_comm_present",mpi_comm_present
+                        argcv = fstarpu_mpi_argcv_alloc(fargc, initialize_mpi, mpi_comm_present, mpi_comm_or_0)
+                        do i=0,fargc-1
+                                call get_command_argument(i, farg_1, farg_len)
+                                allocate (character(len=farg_len) :: farg)
+                                call get_command_argument(i, farg)
+                                call fstarpu_mpi_argcv_set_arg(argcv, i, farg_len, farg)
+                                deallocate (farg)
+                        end do
+                        ret = fstarpu_mpi_init_c(argcv)
+                        call fstarpu_mpi_argcv_free(argcv)
+                        fstarpu_mpi_init = ret
+                end function fstarpu_mpi_init
+
+end module fstarpu_mpi_mod

+ 2 - 0
mpi/include/starpu_mpi.h

@@ -2,6 +2,7 @@
  *
  * Copyright (C) 2009-2012, 2014-2015  Université de Bordeaux
  * Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016  CNRS
+ * Copyright (C) 2016  Inria
  *
  * StarPU is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
@@ -77,6 +78,7 @@ void starpu_mpi_cache_flush_all_data(MPI_Comm comm);
 int starpu_mpi_comm_size(MPI_Comm comm, int *size);
 int starpu_mpi_comm_rank(MPI_Comm comm, int *rank);
 int starpu_mpi_world_rank(void);
+int starpu_mpi_world_size(void);
 
 int starpu_mpi_get_communication_tag(void);
 void starpu_mpi_set_communication_tag(int tag);

+ 56 - 0
mpi/src/starpu_mpi.c

@@ -2,6 +2,7 @@
  *
  * Copyright (C) 2009, 2010-2016  Université de Bordeaux
  * Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016  CNRS
+ * Copyright (C) 2016  Inria
  *
  * StarPU is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
@@ -1172,6 +1173,8 @@ struct _starpu_mpi_argc_argv
 	int *argc;
 	char ***argv;
 	MPI_Comm comm;
+	int fargc;	// Fortran argc
+	char **fargv;	// Fortran argv
 };
 
 static void _starpu_mpi_print_thread_level_support(int thread_level, char *msg)
@@ -1796,6 +1799,13 @@ int starpu_mpi_comm_rank(MPI_Comm comm, int *rank)
 #endif
 }
 
+int starpu_mpi_world_size(void)
+{
+	int size;
+	starpu_mpi_comm_size(MPI_COMM_WORLD, &size);
+	return size;
+}
+
 int starpu_mpi_world_rank(void)
 {
 	int rank;
@@ -1814,3 +1824,49 @@ int starpu_mpi_wait_for_all(MPI_Comm comm)
 	}
 	return 0;
 }
+
+/* Fortran related functions */
+struct _starpu_mpi_argc_argv *fstarpu_mpi_argcv_alloc(int argc, int initialize_mpi, int comm_present, MPI_Fint comm)
+{
+	struct _starpu_mpi_argc_argv *argcv = calloc(1,sizeof(*argcv));
+	argcv->initialize_mpi = initialize_mpi;
+	if (comm_present) {
+		argcv->comm = MPI_Comm_f2c(comm);
+	} else {
+		argcv->comm = MPI_COMM_WORLD;
+	}
+	argcv->fargc = argc;
+	argcv->argc = &argcv->fargc;
+	argcv->fargv = calloc(argc, sizeof(char *));
+	argcv->argv = &argcv->fargv;
+	return argcv;
+}
+
+void fstarpu_mpi_argcv_set_arg(struct _starpu_mpi_argc_argv *argcv, int i, int len, char *_s)
+{
+	STARPU_ASSERT(len >= 0);
+	STARPU_ASSERT(i >= 0 && i < argcv->fargc);
+	char *s = malloc(len+1);
+	memcpy(s, _s, len);
+	s[len] = '\0';
+	argcv->fargv[i] = s;
+}
+
+void fstarpu_mpi_argcv_free(struct _starpu_mpi_argc_argv *argcv)
+{
+	if (argcv->fargv != NULL)
+	{
+		int i;
+		for (i=0; i<argcv->fargc; i++)
+		{
+			free(argcv->fargv[i]);
+		}
+		free(argcv->fargv);
+	}
+	free(argcv);
+}
+
+int fstarpu_mpi_init_c(struct _starpu_mpi_argc_argv *argcv)
+{
+	return starpu_mpi_init_comm(argcv->argc, argcv->argv, argcv->initialize_mpi, argcv->comm);
+}