Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Alltoallv
authorgenaud <genaud@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Sat, 1 Aug 2009 08:19:02 +0000 (08:19 +0000)
committergenaud <genaud@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Sat, 1 Aug 2009 08:19:02 +0000 (08:19 +0000)
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@6539 48e7efb5-ca39-0410-a469-dd3cf9ba447f

ChangeLog
examples/smpi/Makefile.am
examples/smpi/alltoallv.c [new file with mode: 0644]
src/smpi/BUGS
src/smpi/smpi_coll.c
src/smpi/smpi_mpi.c
src/smpi/smpi_mpi_dt.c

index 0b5b80a..1ec9954 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -14,6 +14,7 @@ SimGrid (3.3.2-svn) unstable; urgency=low
                      Allreduce: Reduce then Bcast
                      Alltoall: "basic_linear" if data per proc < 3Kb, "otherwise pairwise". 
                                Not yet implemented: "Bruck" for data per proc < 200b and comm size > 12
+                     Alltoallv: flat tree, like ompi
                      Scatter: flat tree
   * Add support for optimized collectives (Bcast is now binomial by default)
   * Port smpirun and smpicc to OS X
index 7c4beba..8b11bdc 100644 (file)
 
 noinst_PROGRAMS = allreduce bcast bcbench compute compute2 compute3 first pingpong second sendrecv mvmul ring_c split scatter reduce 
 
+alltoall2: alltoall2.c
+       $(top_builddir)/src/smpi/smpicc $^ -o $@
+alltoall_basic: alltoall_basic.c
+       $(top_builddir)/src/smpi/smpicc $^ -o $@
+alltoallv: alltoallv.c
+       $(top_builddir)/src/smpi/smpicc $^ -o $@
 allreduce: allreduce.c
        $(top_builddir)/src/smpi/smpicc $^ -o $@
 bcast: bcast.c
diff --git a/examples/smpi/alltoallv.c b/examples/smpi/alltoallv.c
new file mode 100644 (file)
index 0000000..73b6d24
--- /dev/null
@@ -0,0 +1,171 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+ #include <string.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+/*
+   This program tests MPI_Alltoallv by having processor i send different
+   amounts of data to each processor.
+
+   Because there are separate send and receive types to alltoallv,
+   there need to be tests to rearrange data on the fly.  Not done yet.
+
+   The first test sends i items to processor i from all processors.
+
+   Currently, the test uses only MPI_INT; this is adequate for testing systems
+   that use point-to-point operations
+ */
+
+
+/* example values:
+ * For 3 processes:
+ * <0> sbuf: (#9):   [0][1][2][3][4][5][6][7][8]
+   <0> scount: (#3): [0][1][2]
+   <0> rcount: (#3): [0][0][0]
+   <0> sdisp: (#3):  [0][1][3]
+   <0> rdisp: (#3):  [0][0][0]
+
+   <1> sbuf: (#9):   [100][101][102][103][104][105][106][107][108]
+   <1> scount: (#3): [0][1][2]
+   <1> rcount: (#3): [1][1][1]
+   <1> sdisp: (#3):  [0][1][3]
+   <1> rdisp: (#3):  [0][1][2]
+
+   <2> sbuf: (#9):   [200][201][202][203][204][205][206][207][208]
+   <2> scount: (#3): [0][1][2]
+   <2> rcount: (#3): [2][2][2]
+   <2> sdisp: (#3):  [0][1][3]
+   <2> rdisp: (#3):  [0][2][4]
+
+   after MPI_Alltoallv :
+   <0> rbuf: (#9):   [0][-1][-2][-3][-4][-5][-6][-7][-8]
+   <1> rbuf: (#9):   [1][101][201][-3][-4][-5][-6][-7][-8]
+   <2> rbuf: (#9):   [3][4][103][104][203][204][-6][-7][-8]
+*/
+
+
+void print_buffer_int(void *buf, int len, char *msg, int rank)
+{
+  int tmp, *v;
+  printf("**<%d> %s (#%d): ", rank, msg,len);
+  for (tmp = 0; tmp < len; tmp++) {
+    v = buf;
+    printf("[%d]", v[tmp]);
+  }
+  printf("\n");
+  free(msg);
+}
+
+
+int main( int argc, char **argv )
+{
+
+        MPI_Comm comm;
+        int      *sbuf, *rbuf, *erbuf;
+        int      rank, size;
+        int      *sendcounts, *recvcounts, *rdispls, *sdispls;
+        int      i, j, *p, err;
+
+        MPI_Init( &argc, &argv );
+        err = 0;
+
+        comm = MPI_COMM_WORLD;
+
+        /* Create the buffer */
+        MPI_Comm_size( comm, &size );
+        MPI_Comm_rank( comm, &rank );
+        sbuf = (int *)malloc( size * size * sizeof(int) );
+        rbuf = (int *)malloc( size * size * sizeof(int) );
+        erbuf = (int *)malloc( size * size * sizeof(int) ); // expected
+        if (!sbuf || !rbuf) {
+                fprintf( stderr, "Could not allocated buffers!\n" );
+                MPI_Abort( comm, 1 );
+        }
+
+        /* Load up the buffers */
+        for (i=0; i<size*size; i++) {
+                sbuf[i] = i + 100*rank;
+                rbuf[i] = -i;
+                erbuf[i]= -i;
+        }
+
+        /* Create and load the arguments to alltoallv */
+        sendcounts = (int *)malloc( size * sizeof(int) );
+        recvcounts = (int *)malloc( size * sizeof(int) );
+        rdispls    = (int *)malloc( size * sizeof(int) );
+        sdispls    = (int *)malloc( size * sizeof(int) );
+        if (!sendcounts || !recvcounts || !rdispls || !sdispls) {
+                fprintf( stderr, "Could not allocate arg items!\n" );
+                MPI_Abort( comm, 1 );
+        }
+        for (i=0; i<size; i++) {
+                sendcounts[i] = i;
+                recvcounts[i] = rank;
+                rdispls[i]    = i * rank;
+                sdispls[i]    = (i * (i+1))/2;
+        }
+
+        /* debug */
+        /* 
+        print_buffer_int( sbuf, size*size, strdup("sbuf:"),rank);
+        print_buffer_int( sendcounts, size, strdup("scount:"),rank);
+        print_buffer_int( recvcounts, size, strdup("rcount:"),rank);
+        print_buffer_int( sdispls, size, strdup("sdisp:"),rank);
+        print_buffer_int( rdispls, size, strdup("rdisp:"),rank);
+        */
+
+
+        /* debug : erbuf */
+        /* debug
+        for (i=0; i<size; i++) {
+                for (j=0; j<rank; j++) {
+                        *(erbuf+j+ rdispls[i]) = i * 100 + (rank*(rank+1))/2 + j; 
+                }
+        }
+        */
+
+
+        //print_buffer_int( erbuf, size*size, strdup("erbuf:"),rank);
+
+        MPI_Alltoallv( sbuf, sendcounts, sdispls, MPI_INT,
+                        rbuf, recvcounts, rdispls, MPI_INT, comm );
+
+        // debug: print_buffer_int( rbuf, size*size, strdup("rbuf:"),rank);
+
+        
+        /* Check rbuf */
+        for (i=0; i<size; i++) {
+                p = rbuf + rdispls[i];
+                for (j=0; j<rank; j++) {
+                        if (p[j] != i * 100 + (rank*(rank+1))/2 + j) {
+                                fprintf( stderr, "** Error: <%d> got %d expected %d for %dth\n",
+                                                rank, p[j],(i*(i+1))/2 + j, j );
+                                err++;
+                        }
+                }
+        }
+
+        /* Summary */
+        if ( err > 0) {
+                      printf("<%d> Alltoallv test: failure (%d errors).\n",rank,err);
+        }
+        if ( 0==rank ) {
+                printf("* Alltoallv TEST COMPLETE.\n");
+        }
+        free( sdispls );
+        free( rdispls );
+        free( recvcounts );
+        free( sendcounts );
+        free( rbuf );
+        free( sbuf );
+            
+        MPI_Barrier( MPI_COMM_WORLD);
+        MPI_Finalize();
+        return 0;
+}
index b6b24e8..a72f313 100644 (file)
@@ -1,36 +1,31 @@
 
-
+___________________________________________________________________________________________
 * if the program has a different main() prototype than
    int main( int argc, char *argv[] )
   then the compilation smpicc fails : conflicting types for ‘smpi_simulated_main’
   since smpicc substitutes smpi_simulated_main for the user main() declaration.
    
-
-* MPI_Barrier()
-  Tue Jun 30 11:49:07 UTC 2009 - genaud
-
-  several calls to MPI_Barrier() result in:
-  
-genaud@boa:~/Documents/svn/simgrid/simgrid/trunk/src/smpi$ ./smpirun -np 2 -platform g1.xml -hostfile hostfile ./barrier
-[0.000000] [simix_kernel/INFO] Oops ! Deadlock or code not perfectly clean.
-[0.000000] [simix_kernel/INFO] 6 processes are still running, waiting for something.
-[0.000000] [simix_kernel/INFO] Legend of the following listing: "<process> on <host>: <status>."
-[0.000000] [simix_kernel/INFO] smpi_simulated_main on grelon-1.nancy.grid5000.fr:  Blocked on condition 0xdead; Waiting for the following actions: 'sleep'(0xdead) 'sleep'(0xdead).
-[0.000000] [simix_kernel/INFO] smpi_simulated_main on grelon-2.nancy.grid5000.fr:  Blocked on condition 0xdead; Waiting for the following actions: 'sleep'(0xdead) 'sleep'(0xdead).
-[0.000000] [simix_kernel/INFO] smpi_sender on grelon-1.nancy.grid5000.fr: [SUSPENDED]  Blocked on condition 0xdead; Waiting for the following actions: 'dummy'(0xdead).
-[0.000000] [simix_kernel/INFO] smpi_receiver on grelon-1.nancy.grid5000.fr: [SUSPENDED]  Blocked on condition 0xdead; Waiting for the following actions: 'dummy'(0xdead).
-[0.000000] [simix_kernel/INFO] smpi_sender on grelon-2.nancy.grid5000.fr: [SUSPENDED]  Blocked on condition 0xdead; Waiting for the following actions: 'dummy'(0xdead).
-[0.000000] [simix_kernel/INFO] smpi_receiver on grelon-2.nancy.grid5000.fr: [SUSPENDED]  Blocked on condition 0xdead; Waiting for the following actions: 'dummy'(0xdead).
-[0.000000] [simix_kernel/INFO] Return a Warning.
-** SimGrid: UNCAUGHT EXCEPTION received on (0): category: unknown_err; value: 0
-** Cannot destroy conditional since someone is still using it
-** Thrown by () in this process
-[0.000000] xbt/ex.c:117: [xbt_ex/CRITICAL] Cannot destroy conditional since someone is still using it
-
-**   In SIMIX_cond_destroy() at /home/genaud/Documents/svn/simgrid/simgrid/trunk/src/simix/smx_synchro.c:302
-**   In smpi_global_destroy() at /home/genaud/Documents/svn/simgrid/simgrid/trunk/src/smpi/smpi_global.c:239
-**   In smpi_run_simulation() at /home/genaud/Documents/svn/simgrid/simgrid/trunk/src/smpi/smpi_global.c:333
-./smpirun: line 176: 18880 Abandon                 ${EXEC} ${SIMOPTS} ${PLATFORMTMP} ${APPLICATIONTMP}
-
-
-
+___________________________________________________________________________________________
+* MPI_Alltoallv()
+  samedi 1 août 2009, 10:12:08 (UTC+0200) - genaud
+
+  pass the test 'alltoallv.c' (from mpich2) for many number of processors but shows a segfault 
+  after TEST COMPLETE.
+
+  Program received signal SIGSEGV, Segmentation fault.
+  SIMIX_mutex_lock (mutex=0x657475) at simix/smx_synchro.c:49
+  49    if (mutex->refcount) {
+  (gdb) bt
+  #0  SIMIX_mutex_lock (mutex=0x657475) at simix/smx_synchro.c:49
+  #1  0xb7fc0cb0 in SIMIX_cond_wait (cond=0x9f5eba0, mutex=0x9f5eb78) at simix/smx_synchro.c:196
+  #2  0xb7f473a0 in smpi_sender (argc=0, argv=0x0) at smpi/smpi_sender.c:85
+  #3  0xb7fb8f71 in smx_ctx_sysv_wrapper () at simix/smx_context_sysv.c:247
+  #4  0xb7e032bb in makecontext () from /lib/tls/i686/cmov/libc.so.6
+  #5  0x00000000 in ?? ()
+  (gdb) quit
+
+
+  as soon as to -np > 8 using the plaform/hosts : 
+  ./smpirun -np 9 -platform ../../examples/msg/small_platform.xml -hostfile ../../examples/smpi/hostfile ./alltoallv
+
+___________________________________________________________________________________________
index 43738f1..4221710 100644 (file)
@@ -684,10 +684,9 @@ int smpi_coll_basic_alltoallv(void *sbuf, int *scounts, int *sdisps, MPI_Datatyp
 
         err = smpi_mpi_type_get_extent(sdtype, &lb, &sndextent);
         err = smpi_mpi_type_get_extent(rdtype, &lb, &rcvextent);
-        DEBUG3("<%d> sizeof(sndttype)=%d,sizeof(rcvtype)=%d",rank,sndextent,rcvextent);
 
         psnd = (char *)sbuf;
-        print_buffer_int(psnd,size*size,xbt_strdup("sbuff"),rank);
+        //print_buffer_int(psnd,size*size,xbt_strdup("sbuff"),rank);
 
         /* copy the local sbuf to rbuf when it's me */
         psnd = ((char *) sbuf) + (sdisps[rank] * sndextent);
@@ -695,7 +694,6 @@ int smpi_coll_basic_alltoallv(void *sbuf, int *scounts, int *sdisps, MPI_Datatyp
 
         if (0 != scounts[rank]) {
                 err = copy_dt( psnd, scounts[rank], sdtype, prcv, rcounts[rank], rdtype );
-                print_buffer_int(psnd,scounts[rank],strdup("copy_dt"),rank);
                 if (MPI_SUCCESS != err) {
                         return err;
                 }
@@ -739,8 +737,8 @@ int smpi_coll_basic_alltoallv(void *sbuf, int *scounts, int *sdisps, MPI_Datatyp
                 }
                 psnd = ((char *) sbuf) + (sdisps[i] * sndextent);
 
-                fprintf(stderr,"<%d> send %d elems to <%d>\n",rank,scounts[i],i);
-                print_buffer_int(psnd,scounts[i],xbt_strdup("sbuff part"),rank);
+                //fprintf(stderr,"<%d> send %d elems to <%d>\n",rank,scounts[i],i);
+                //print_buffer_int(psnd,scounts[i],xbt_strdup("sbuff part"),rank);
                 err = smpi_create_request (psnd, scounts[i], sdtype,
                                 rank, i,
                                 system_alltoallv_tag, 
@@ -760,7 +758,8 @@ int smpi_coll_basic_alltoallv(void *sbuf, int *scounts, int *sdisps, MPI_Datatyp
                 DEBUG3("<%d> issued irecv request reqs[%d]=%p",rank,i,reqs[i]);
                 smpi_mpi_irecv( reqs[i] );
         }
-        for ( i=rreq; i<sreq; i++ ) {
+                DEBUG3("<%d> for (i=%d;i<%d)",rank,rreq,sreq);
+        for ( i=rreq; i< rreq+sreq; i++ ) {
                 DEBUG3("<%d> issued isend request reqs[%d]=%p",rank,i,reqs[i]);
                 smpi_mpi_isend( reqs[i] );
         }
index 53799a0..22f9ae5 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id$tag */
+/* $Id$tag */
 
 /* smpi_mpi.c -- 
  *
index a196e36..783bb86 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id$tag */
+/* $Id$tag */
 
 /* smpi_mpi_dt.c -- MPI primitives to handle datatypes                        */