Index: /soft/giet_vm/applications/classif/classif.ld
===================================================================
--- /soft/giet_vm/applications/classif/classif.ld	(revision 472)
+++ /soft/giet_vm/applications/classif/classif.ld	(revision 473)
@@ -1,27 +1,8 @@
 /****************************************************************************
-* Definition of the base address for all virtual segments
+* Definition of the base address for code and data vsegs
 *****************************************************************************/
 
 seg_code_base        = 0x10000000;
-
-seg_data_0_0_base    = 0x20000000;
-seg_data_0_1_base    = 0x20010000;
-seg_data_0_2_base    = 0x20020000;
-seg_data_0_3_base    = 0x20030000;
-
-seg_data_1_0_base    = 0x20040000;
-seg_data_1_1_base    = 0x20050000;
-seg_data_1_2_base    = 0x20060000;
-seg_data_1_3_base    = 0x20070000;
-
-seg_data_2_0_base    = 0x20080000;
-seg_data_2_1_base    = 0x20090000;
-seg_data_2_2_base    = 0x200A0000;
-seg_data_2_3_base    = 0x200B0000;
-
-seg_data_3_0_base    = 0x200C0000;
-seg_data_3_1_base    = 0x200D0000;
-seg_data_3_2_base    = 0x200E0000;
-seg_data_3_3_base    = 0x200F0000;
+seg_data_base        = 0x20000000;
 
 /***************************************************************************
@@ -37,6 +18,6 @@
     }
 
-    . = seg_data_0_0_base;
-    seg_data_0_0 : 
+    . = seg_data_base;
+    seg_data : 
     {
         *(.ctors)
@@ -51,83 +32,4 @@
         *(.sbss)
         *(.scommon)
-        *(.data_0_0)
-    }
-    . = seg_data_0_1_base;
-    seg_data_0_1 : 
-    {
-        *(.data_0_1)
-    }
-    . = seg_data_0_2_base;
-    seg_data_0_2 : 
-    {
-        *(.data_0_2)
-    }
-    . = seg_data_0_3_base;
-    seg_data_0_3 : 
-    {
-        *(.data_0_3)
-    }
-
-    . = seg_data_1_0_base;
-    seg_data_1_0 : 
-    {
-        *(.data_1_0)
-    }
-    . = seg_data_1_1_base;
-    seg_data_1_1 : 
-    {
-        *(.data_1_1)
-    }
-    . = seg_data_1_2_base;
-    seg_data_1_2 : 
-    {
-        *(.data_1_2)
-    }
-    . = seg_data_1_3_base;
-    seg_data_1_3 : 
-    {
-        *(.data_1_3)
-    }
-
-    . = seg_data_2_0_base;
-    seg_data_2_0 : 
-    {
-        *(.data_2_0)
-    }
-    . = seg_data_2_1_base;
-    seg_data_2_1 : 
-    {
-        *(.data_2_1)
-    }
-    . = seg_data_2_2_base;
-    seg_data_2_2 : 
-    {
-        *(.data_2_2)
-    }
-    . = seg_data_2_3_base;
-    seg_data_2_3 : 
-    {
-        *(.data_2_3)
-    }
-
-    . = seg_data_3_0_base;
-    seg_data_3_0 : 
-    {
-        *(.data_3_0)
-    }
-    . = seg_data_3_1_base;
-    seg_data_3_1 : 
-    {
-        *(.data_3_1)
-    }
-    . = seg_data_3_2_base;
-    seg_data_3_2 : 
-    {
-        *(.data_3_2)
-    }
-    . = seg_data_3_3_base;
-    seg_data_3_3 : 
-    {
-        *(.data_3_3)
     }
 }
Index: /soft/giet_vm/applications/classif/classif.py
===================================================================
--- /soft/giet_vm/applications/classif/classif.py	(revision 472)
+++ /soft/giet_vm/applications/classif/classif.py	(revision 473)
@@ -15,5 +15,6 @@
 #  The mapping of virtual segments on the clusters is the following:
 #    - The code vsegs are replicated on all clusters.
-#    - There is one shared data vseg per cluster.
+#    - There is one shared data vseg in cluster[0][0]
+#    - There is one heap vseg per cluster.
 #    - The stacks vsegs are distibuted on all clusters.
 #  This mapping uses 5 platform parameters, (obtained from the "mapping" argument)
@@ -37,5 +38,4 @@
     y_width   = mapping.y_width
 
-    assert (x_size <= 4) and (y_size <= 4)
     assert (nprocs >= 2)
 
@@ -45,5 +45,8 @@
     
     data_base  = 0x20000000
-    data_size  = 0x00010000     # 64 Kbytes (per cluster)
+    data_size  = 0x00010000     # 64 Kbytes 
+
+    heap_base  = 0x30000000
+    heap_size  = 0x00008000     # 32 Kbytes (per cluster)      
 
     stack_base = 0x40000000 
@@ -51,14 +54,19 @@
 
     # create vspace
-    vspace = mapping.addVspace( name = 'classif', startname = 'classif_data_0_0' )
+    vspace = mapping.addVspace( name = 'classif', startname = 'classif_data' )
     
-    # data_x_y vsegs : shared / one per cluster 
+    # data vseg : shared / cluster[0][0]
+    mapping.addVseg( vspace, 'classif_data', data_base , data_size, 
+                     'C_WU', vtype = 'ELF', x = 0, y = 0, pseg = 'RAM', 
+                     binpath = 'build/classif/classif.elf',
+                     local = False )
+
+    # heap_x_y vsegs : shared / one per cluster 
     for x in xrange (x_size):
         for y in xrange (y_size):
-            base = data_base + ( (4*x + y) * data_size )
+            base = heap_base + ( (4*x + y) * heap_size )
 
-            mapping.addVseg( vspace, 'classif_data_%d_%d' %(x,y), base , data_size, 
-                             'C_WU', vtype = 'ELF', x = x, y = y, pseg = 'RAM', 
-                             binpath = 'build/classif/classif.elf',
+            mapping.addVseg( vspace, 'classif_heap_%d_%d' %(x,y), base , heap_size, 
+                             'C_WU', vtype = 'HEAP', x = x, y = y, pseg = 'RAM', 
                              local = False )
 
@@ -94,8 +102,10 @@
                 else :                                      # task analyse
                     task_index = 1
-                    task_name  = 'analyse_%d_%d_%d' % (x,y,p
-)
+                    task_name  = 'analyse_%d_%d_%d' % (x,y,p)
+
                 mapping.addTask( vspace, task_name, trdid, x, y, p,
-                                 'classif_stack_%d_%d_%d' % (x,y,p), '' , task_index )
+                                 'classif_stack_%d_%d_%d' % (x,y,p), 
+                                 'classif_heap_%d_%d' % (x,y),
+                                 task_index )
 
     # extend mapping name
Index: /soft/giet_vm/applications/classif/main.c
===================================================================
--- /soft/giet_vm/applications/classif/main.c	(revision 472)
+++ /soft/giet_vm/applications/classif/main.c	(revision 473)
@@ -17,11 +17,19 @@
 // as global variables distributed in (up to) 16 clusters. 
 //
-// WARNING: the platform cannot contain more than 16 clusters: (X_SIZE < 4) && (Y_SIZE < 4)
-//
-// 1) The "load" task transfer one container from the kernel chbuf associated to the
-//    NIC_RX channel, to a private buffer. Then it copies this bufferer to the local MWMR fifo.
+// Initialisation is done in two steps by the "load" tasks:
+// - Task "load" in cluster[0][0] initialises NIC & CMA channel, and initialises 
+//   the barrier between all "load" tasks. Other "load" tasks are waiting on the
+//   global_sync synchronisation variable.
+// - In each cluster[x][y], the load" task allocates the MWMR fifo descriptor & the data
+//   buffer in the local heap, and store the pointers on a global array of pointers. 
+//   The "analyse" tasks are waiting on the sync[x][y] variables.
+//     
+// When initialisation is completed, all "load and "analyse" tasks loop on containers:
+// 1) The "load" task transfer containers from the kernel chbuf associated to the
+//    NIC_RX channel (in cluster[0][0]), to the local MWMR fifo (in cluster[x][y]),
+//    after an in termediate copy in a private stack buffer. 
 //    Each "load" task loads CONTAINERS_MAX containers before exit, and the
 //    task in cluster[0,0] displays the results stored in global counters filled
-//    by the "analyse" tasks.
+//    by the "analyse" tasks when all "load" tasks reach the barrier.
 //
 // 2) The "analyse" task transfer one container from the local MWMR fifo to a private
@@ -47,105 +55,25 @@
 #define CONTAINERS_MAX   10
 
-///////////  distributed data /////////////////////////////////////////////////////////////
-// - fifo_x_y is the local MWMR fifo descriptor
-// - data_x_y is the local MWMR fifo data buffer
-// - sync_x_y is the local variable signaling MWMR fifo initialisation
-///////////  distributed data /////////////////////////////////////////////////////////////
-
-#if ( (X_SIZE > 0) && (Y_SIZE > 0) )
-__attribute__((section (".data_0_0")))  mwmr_channel_t fifo_0_0;
-__attribute__((section (".data_0_0")))  unsigned int   data_0_0[NB_PROCS_MAX<<10];
-__attribute__((section (".data_0_0")))  unsigned int   sync_0_0 = 0;
-#endif
-#if ( (X_SIZE > 0) && (Y_SIZE > 1) )
-__attribute__((section (".data_0_1")))  mwmr_channel_t fifo_0_1;
-__attribute__((section (".data_0_1")))  unsigned int   data_0_1[NB_PROCS_MAX<<10];
-__attribute__((section (".data_0_1")))  unsigned int   sync_0_1 = 0;
-#endif
-#if ( (X_SIZE > 0) && (Y_SIZE > 2) )
-__attribute__((section (".data_0_2")))  mwmr_channel_t fifo_0_2;
-__attribute__((section (".data_0_2")))  unsigned int   data_0_2[NB_PROCS_MAX<<10];
-__attribute__((section (".data_0_2")))  unsigned int   sync_0_2 = 0;
-#endif
-#if ( (X_SIZE > 0) && (Y_SIZE > 3) )
-__attribute__((section (".data_0_3")))  mwmr_channel_t fifo_0_3;
-__attribute__((section (".data_0_3")))  unsigned int   data_0_3[NB_PROCS_MAX<<10];
-__attribute__((section (".data_0_3")))  unsigned int   sync_0_3 = 0;
-#endif
-#if ( (X_SIZE > 1) && (Y_SIZE > 0) )
-__attribute__((section (".data_1_0")))  mwmr_channel_t fifo_1_0;
-__attribute__((section (".data_1_0")))  unsigned int   data_1_0[NB_PROCS_MAX<<10];
-__attribute__((section (".data_1_0")))  unsigned int   sync_1_0 = 0;
-#endif
-#if ( (X_SIZE > 1) && (Y_SIZE > 1) )
-__attribute__((section (".data_1_1")))  mwmr_channel_t fifo_1_1;
-__attribute__((section (".data_1_1")))  unsigned int   data_1_1[NB_PROCS_MAX<<10];
-__attribute__((section (".data_1_1")))  unsigned int   sync_1_1 = 0;
-#endif
-#if ( (X_SIZE > 1) && (Y_SIZE > 2) )
-__attribute__((section (".data_1_2")))  mwmr_channel_t fifo_1_2;
-__attribute__((section (".data_1_2")))  unsigned int   data_1_2[NB_PROCS_MAX<<10];
-__attribute__((section (".data_1_2")))  unsigned int   sync_1_2 = 0;
-#endif
-#if ( (X_SIZE > 1) && (Y_SIZE > 3) )
-__attribute__((section (".data_1_3")))  mwmr_channel_t fifo_1_3;
-__attribute__((section (".data_1_3")))  unsigned int   data_1_3[NB_PROCS_MAX<<10];
-__attribute__((section (".data_1_3")))  unsigned int   sync_1_3 = 0;
-#endif
-#if ( (X_SIZE > 2) && (Y_SIZE > 0) )
-__attribute__((section (".data_2_0")))  mwmr_channel_t fifo_2_0;
-__attribute__((section (".data_2_0")))  unsigned int   data_2_0[NB_PROCS_MAX<<10];
-__attribute__((section (".data_2_0")))  unsigned int   sync_2_0 = 0;
-#endif
-#if ( (X_SIZE > 2) && (Y_SIZE > 1) )
-__attribute__((section (".data_2_1")))  mwmr_channel_t fifo_2_1;
-__attribute__((section (".data_2_1")))  unsigned int   data_2_1[NB_PROCS_MAX<<10];
-__attribute__((section (".data_2_1")))  unsigned int   sync_2_1 = 0;
-#endif
-#if ( (X_SIZE > 2) && (Y_SIZE > 2) )
-__attribute__((section (".data_2_2")))  mwmr_channel_t fifo_2_2;
-__attribute__((section (".data_2_2")))  unsigned int   data_2_2[NB_PROCS_MAX<<10];
-__attribute__((section (".data_2_2")))  unsigned int   sync_2_2 = 0;
-#endif
-#if ( (X_SIZE > 2) && (Y_SIZE > 3) )
-__attribute__((section (".data_2_3")))  mwmr_channel_t fifo_2_3;
-__attribute__((section (".data_2_3")))  unsigned int   data_2_3[NB_PROCS_MAX<<10];
-__attribute__((section (".data_2_3")))  unsigned int   sync_2_3 = 0;
-#endif
-#if ( (X_SIZE > 3) && (Y_SIZE > 0) )
-__attribute__((section (".data_3_0")))  mwmr_channel_t fifo_3_0;
-__attribute__((section (".data_3_0")))  unsigned int   data_3_0[NB_PROCS_MAX<<10];
-__attribute__((section (".data_3_0")))  unsigned int   sync_3_0 = 0;
-#endif
-#if ( (X_SIZE > 3) && (Y_SIZE > 1) )
-__attribute__((section (".data_3_1")))  mwmr_channel_t fifo_3_1;
-__attribute__((section (".data_3_1")))  unsigned int   data_3_1[NB_PROCS_MAX<<10];
-__attribute__((section (".data_3_1")))  unsigned int   sync_3_1 = 0;
-#endif
-#if ( (X_SIZE > 3) && (Y_SIZE > 2) )
-__attribute__((section (".data_3_2")))  mwmr_channel_t fifo_3_2;
-__attribute__((section (".data_3_2")))  unsigned int   data_3_2[NB_PROCS_MAX<<10];
-__attribute__((section (".data_3_2")))  unsigned int   sync_3_2 = 0;
-#endif
-#if ( (X_SIZE > 3) && (Y_SIZE > 3) )
-__attribute__((section (".data_3_3")))  mwmr_channel_t fifo_3_3;
-__attribute__((section (".data_3_3")))  unsigned int   data_3_3[NB_PROCS_MAX<<10];
-__attribute__((section (".data_3_3")))  unsigned int   sync_3_3 = 0;
-#endif
-
-/////////// shared variables in cluster[0,0] //////////////////////////
-
-__attribute__((section (".data_0_0")))  unsigned int count[16];
-
-__attribute__((section (".data_0_0")))  giet_barrier_t barrier;
-
-__attribute__((section (".data_0_0")))  unsigned int global_init_ok = 0;
-
-__attribute__((section (".data_0_0")))  unsigned int nic_channel;
-
-
-/////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////
+//    Global variables
+// The communication channels are distributed in the clusters, 
+// but the pointers arrays are global variables in cluster[0][0]
+///////////////////////////////////////////////////////////////////////////////////////////
+
+mwmr_channel_t*  mwmr[X_SIZE][Y_SIZE];        // distributed MWMR fifos pointers
+
+unsigned int     local_sync[X_SIZE][Y_SIZE];  // distributed synchros "load" / "analyse"
+
+unsigned int     global_sync = 0;             // global synchro between "load" tasks
+
+unsigned int     count[16];                   // instrumentation counters
+
+giet_barrier_t   barrier;                     // barrier between "load" (instrumentation)
+
+unsigned int     nic_channel;                 // allocated NIC channel index
+
+///////////////////////////////////////////////////////////////////////////////////////////
 __attribute__ ((constructor)) void load()
-/////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////
 {
     // get processor identifiers
@@ -158,18 +86,33 @@
     if (Y_SIZE > 4 )  giet_exit("The Y_SIZE parameter cannot be larger than 4\n");
 
-    // local buffer to store one container
+    // local buffer to store one container in private stack
     unsigned int  temp[1024];
 
-    // get pointer on local MWMR fifo descriptor and data buffer
-    unsigned int    offset = ((x * 4) + y) * 0x10000;
-    mwmr_channel_t* fifo = (mwmr_channel_t*)(((unsigned int)&fifo_0_0) + offset);
-    unsigned int*   data = (unsigned int*)  (((unsigned int)data_0_0)  + offset);
-    unsigned int*   sync = (unsigned int*)  (((unsigned int)&sync_0_0) + offset);
-
+// giet_shr_printf("\n@@@ P[%d,%d,%d] enters load task at cycle %d\n", 
+//                 x, y, l, giet_proctime() );
+
+    // allocates data buffer for MWMR fifo in local heap
+    unsigned int*  data = malloc( NB_PROCS_MAX<<12 );
+
+//giet_shr_printf("\n@@@ P[%d,%d,%d] completes data malloc at cycle %d "
+//                "/ &data = %x\n", x, y, l, giet_proctime(), (unsigned int)data );
+
+    // allocates MWMR fifo descriptor in local heap
+    mwmr_channel_t*  fifo = malloc( sizeof(mwmr_channel_t) );
+
+//giet_shr_printf("\n@@@ P[%d,%d,%d] completes mwmr malloc at cycle %d "
+//                "/ &mwmr = %x\n", x, y, l, giet_proctime(), (unsigned int)mwmr );
+
+    // makes copy of pointer in global array for "analyse" tasks
+    mwmr[x][y] = fifo;
+
+    // display status for cluster[X_SIZE-1][Y_SIZE-1]
     if ( (x==X_SIZE-1) && (y==Y_SIZE-1) )
     giet_shr_printf("\n*** Task load starts on P[%d,%d,%d] at cycle %d\n"
-                    "      &fifo = %x / &data = %x / &sync = %x\n",
-                    x, y, l, giet_proctime(), 
-                    (unsigned int)fifo, (unsigned int)data, (unsigned int)sync ); 
+                    "      &fifo  = %x / &data  = %x / &sync  = %x\n"
+                    "      x_size = %d / y_size = %d / nprocs = %d\n",
+                    x , y , l , giet_proctime() , 
+                    (unsigned int)fifo , (unsigned int)data, (unsigned int)(&local_sync[x][y]) ,
+                    X_SIZE, Y_SIZE, NB_PROCS_MAX ); 
 
     // Task load on cluster[0,0] makes global initialisation:
@@ -188,9 +131,12 @@
         barrier_init( &barrier, X_SIZE * Y_SIZE );
 
-        global_init_ok = 1;
+        // clear NIC RX channels stats
+        giet_nic_rx_clear(); 
+
+        global_sync = 1;
     }
     else
     {
-        while ( global_init_ok == 0 ) asm volatile ("nop");
+        while ( global_sync == 0 ) asm volatile ("nop");
     }    
 
@@ -198,6 +144,6 @@
     mwmr_init( fifo , data , 1024 , NB_PROCS_MAX );
 
-    // signal MWMR fifo initialisation completion
-    *sync = 1;
+    // signal MWMR fifo initialisation completion to analyse tasks
+    local_sync[x][y] = 1;
 
     // main loop (on containers)
@@ -226,7 +172,9 @@
     barrier_wait( &barrier );
 
-    // Task load in cluster[0,0] displays counters and stops NIC / CMA transfer
+    // Task load in cluster[0,0] stops NIC and displays results 
     if ( (x==0) && (y==0) )
     {
+        giet_nic_rx_stop();
+
         giet_shr_printf("\n@@@@ Clasification Results @@@\n"
                         " - TYPE 0 : %d packets\n"
@@ -246,10 +194,8 @@
                         " - TYPE E : %d packets\n"
                         " - TYPE F : %d packets\n",
-            count[0x0], count[0x1], count[0x2], count[0x3],
-            count[0x4], count[0x5], count[0x6], count[0x7],
-            count[0x8], count[0x9], count[0xA], count[0xB],
-            count[0xC], count[0xD], count[0xE], count[0xF] );
-
-        giet_nic_rx_stop();
+                        count[0x0], count[0x1], count[0x2], count[0x3],
+                        count[0x4], count[0x5], count[0x6], count[0x7],
+                        count[0x8], count[0x9], count[0xA], count[0xB],
+                        count[0xC], count[0xD], count[0xE], count[0xF] );
 
         giet_nic_rx_stats();
@@ -277,19 +223,18 @@
     unsigned int  temp[1024];
 
+    // wait MWMR channel initialisation (done by task load)
+    while ( local_sync[x][y] == 0 ) asm volatile ("nop");
+
     // get pointer on MWMR channel descriptor 
-    unsigned int    offset = ((x * 4) + y) * 0x10000;
-    mwmr_channel_t* fifo = (mwmr_channel_t*)(((unsigned int)&fifo_0_0) + offset);
-    unsigned int*   sync = (unsigned int*)  (((unsigned int)&sync_0_0) + offset);
-
+    mwmr_channel_t* fifo = mwmr[x][y];
+
+    // display status for cluster[X_SIZE-1][Y_SIZE-1]
     if ( (x==X_SIZE-1) && (y==Y_SIZE-1) )
     giet_shr_printf("\n*** Task analyse starts on P[%d,%d,%d] at cycle %d\n"
                     "       &fifo = %x / &sync = %x\n",
                     x, y, l, giet_proctime(), 
-                    (unsigned int)fifo, (unsigned int)sync );
+                    (unsigned int)fifo, (unsigned int)(&local_sync[x][y]) );
     
-    // wait MWMR channel initialisation (done by task load)
-    while ( *sync == 0 ) asm volatile ("nop");
-
-    // infinite loop (on containers)
+    // main loop (on containers)
     unsigned int nwords;     // number of words in container
     unsigned int npackets;   // number of packets in container
