source: soft/giet_vm/applications/sort/main.c @ 502

Last change on this file since 502 was 502, checked in by alain, 9 years ago

1) Introduce distributed barriers in the multi-threads applications
(classif) transpose, convol, sort, gameoflife)

2) Introducing support for architectures containing empty clusters
in the mapping of these multi-threaded applications.

3) Removing the "command line arguments" in the sort application
(replaced by the giet_procs_number() system call.

  • Property svn:executable set to *
File size: 7.0 KB
Line 
1///////////////////////////////////////////////////////////////////////////////
2// File   :  main.c
3// Date   :  November 2013
4// Author :  Cesar Fuguet Tortolero <cesar.fuguet-tortolero@lip6.fr>
5//
6// Description :
7//
8//      Sort application using the GIET-VM OS. This application uses the
9//      barrier routines to apply a sort algorithm in several stages.
10//
11//      Constraints :
12//
13//      - It supports up to 1024 processors and the number of processors
14//        must be a power of 2.
15//
16//      _ The array of values to be sorted (ARRAY_LENGTH) must be power of 2
17//        larger than the number of processors.
18//
19//      - This application must be executed on a cache coherent architecture.
20//
21///////////////////////////////////////////////////////////////////////////////
22
23#include "stdio.h"
24#include "mapping_info.h"
25#include "hard_config.h"
26#include "user_barrier.h"
27
28#define ARRAY_LENGTH    4096
29#define IPT             (ARRAY_LENGTH / threads) // ITEMS PER THREAD
30
31////////////////////////////////////////////////////////////////////////////////
32// Processors other than 0 display algorithm state if VERBOSE non zero
33
34#define VERBOSE         1
35
36////////////////////////////////////////////////////////////////////////////////
37// Define printf according to verbosity option and number of available TTY
38
39#if (VERBOSE == 1)
40#   define printf(...)     giet_shr_printf(__VA_ARGS__)
41#else     
42#   define printf(...)
43#endif
44
45#define task0_printf(...) if(thread_id == 0) giet_shr_printf(__VA_ARGS__)
46
47int array0[ARRAY_LENGTH];
48int array1[ARRAY_LENGTH];
49
50volatile int init_ok = 0;
51
52void bubbleSort(
53        int * array,
54        unsigned int length,
55        unsigned int init_pos);
56
57void merge(
58        int * array,
59        int * result,
60        int length,
61        int init_pos_a,
62        int init_pos_b,
63        int init_pos_result);
64
65///////////////////////////////////////////////////////
66// This application supports at most 1024 processors
67// Number of barriers = log2(threads)
68
69giet_barrier_t barrier[10];
70
71//////////////////////////////////////////
72__attribute__ ((constructor)) void sort()
73{
74    int thread_id = giet_thread_id();
75    int * src_array = NULL;
76    int * dst_array = NULL;
77    int i;
78   
79    unsigned int time_start = giet_proctime();
80    unsigned int time_end;   
81
82    // compute number of threads (one thread per proc)
83    unsigned int x_size;
84    unsigned int y_size;
85    unsigned int nprocs;
86    unsigned int threads;
87    giet_procs_number( &x_size , &y_size , &nprocs );
88    threads = x_size * y_size * nprocs;
89
90    if ( (threads != 1)   && (threads != 2)   && (threads != 4)   && 
91         (threads != 8)   && (threads != 16 ) && (threads != 32)  && 
92         (threads != 64)  && (threads != 128) && (threads != 256) && 
93         (threads != 512) && (threads != 1024) )
94    {
95        task0_printf("[SORT ERROR] Number of processors must be power of 2\n"
96                     "  x_size = %d / y_size = %d / nprocs = %d\n",
97                     x_size , y_size , nprocs );
98        giet_exit("error");
99    }
100
101    task0_printf("\n[ Thread 0 ] Starting sort application with %d threads "
102                 "at cycle %d\n", threads, time_start);
103
104    ///////////////////////////
105    // Barriers Initialization
106
107    if (thread_id == 0)
108    {
109        for (i = 0; i < __builtin_ctz( threads ); i++)
110        {
111            barrier_init(&barrier[i], threads >> i);
112        }
113
114        init_ok = 1;
115    }
116    else
117    {
118        while(!init_ok);
119    }
120
121    ////////////////////////
122    // Array Initialization
123
124    for (i = IPT * thread_id; i < IPT * (thread_id + 1); i++)
125    {
126        array0[i] = giet_rand();
127    }
128
129    ///////////////////////////////////
130    // Parallel sort of array elements
131
132    printf("[ Thread %d ] Stage 0: Sorting...\n\r", thread_id);
133
134    bubbleSort(array0, IPT, IPT * thread_id);
135
136    printf("[ Thread %d ] Finishing Stage 0\n\r", thread_id);
137
138    for (i = 0; i < __builtin_ctz( threads ); i++)
139    {
140        barrier_wait(&barrier[i]);
141
142        if((thread_id % (2 << i)) != 0)
143        {
144            printf("[ Thread %d ] Quit\n\r", thread_id );
145            giet_exit("Completed");
146        }
147
148        printf("[ Thread %d ] Stage %d: Sorting...\n\r", thread_id, i+1);
149
150        if((i % 2) == 0)
151        {
152            src_array = &array0[0];
153            dst_array = &array1[0];
154        }
155        else
156        {
157            src_array = &array1[0];
158            dst_array = &array0[0];
159        }
160
161        merge(src_array, dst_array
162                , IPT << i
163                , IPT * thread_id
164                , IPT * (thread_id + (1 << i))
165                , IPT * thread_id
166                );
167
168        printf("[ Thread %d ] Finishing Stage %d\n\r", thread_id, i + 1);
169    }
170
171    int success;
172    int failure_index;
173
174    //////////////////////////////
175    // Verify the resulting array
176   
177    if(thread_id != 0)
178    {
179        giet_exit("error: only thread 0 should get here");
180    }
181
182    success = 1;
183    for(i=0; i<(ARRAY_LENGTH-1); i++)
184    {
185        if(dst_array[i] > dst_array[i+1])
186        {
187
188            success = 0;
189            failure_index = i;
190            break;
191        }
192    }
193
194    time_end = giet_proctime();
195
196    printf("[ Thread 0 ] Finishing sort application at cycle %d\n"
197           "[ Thread 0 ] Time elapsed = %d\n",
198            time_end, (time_end - time_start) );
199
200    if (success)
201    {
202        giet_exit("!!! Success !!!");
203    }
204    else
205    {
206        printf("[ Thread 0 ] Failure!! Incorrect element: %d\n\r", 
207               failure_index);
208        for(i=0; i<ARRAY_LENGTH; i++)
209        {
210            printf("array[%d] = %d\n", i, dst_array[i]);
211        }
212        giet_exit("!!!  Failure !!!");
213    }
214
215    giet_exit("Completed");
216}
217
218////////////////////////////////////
219void bubbleSort( int *        array,
220                 unsigned int length,
221                 unsigned int init_pos )
222{
223    int i;
224    int j;
225    int aux;
226
227    for(i = 0; i < length; i++)
228    {
229        for(j = init_pos; j < (init_pos + length - i - 1); j++)
230        {
231            if(array[j] > array[j + 1])
232            {
233                aux          = array[j + 1];
234                array[j + 1] = array[j];
235                array[j]     = aux;
236            }
237        }
238    }
239}
240
241/////////////
242void merge(
243        int * array,
244        int * result,
245        int length,
246        int init_pos_a,
247        int init_pos_b,
248        int init_pos_result)
249{
250    int i;
251    int j;
252    int k;
253
254    i = 0;
255    j = 0;
256    k = init_pos_result;
257
258    while((i < length) || (j < length))
259    {
260        if((i < length) && (j < length))
261        {
262            if(array[init_pos_a + i] < array[init_pos_b + j])
263            {
264                result[k++] = array[init_pos_a + i];
265                i++;
266            }
267            else
268            {
269                result[k++] = array[init_pos_b + j];
270                j++;
271            }
272        }
273        else if(i < length)
274        {
275            result[k++] = array[init_pos_a + i];
276            i++;
277        }
278        else
279        {
280            result[k++] = array[init_pos_b + j];
281            j++;
282        }
283    }
284}
285
286/* vim: tabstop=4 : shiftwidth=4 : expandtab
287*/
Note: See TracBrowser for help on using the repository browser.