source: soft/giet_vm/applications/rosenfeld/src-par/mca_main.c @ 822

Last change on this file since 822 was 822, checked in by meunier, 8 years ago

In rosenfeld:

  • Updated nrio0, nrio1, nrio2, nrio1f, nrio2f, nrio1x, nrbool1, nrbool2 and nralloc1 in the nrc2 lib in order to use macro-typed functions
  • Updated the simulation script to include performance evaluation with random images, and a script to generate graphs
  • Updated the clock.h to use 64-bit integers, which potentially breaks the printing on the giet
File size: 14.2 KB
Line 
1/* ------------------ */
2/* --- mca_main.c --- */
3/* ------------------ */
4
5/*
6 * Copyright (c) 2016 Lionel Lacassagne, LIP6, UPMC, CNRS
7 * Init  : 2016/03/03
8 */
9
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13#include <math.h>
14#include <malloc.h>
15
16#include "nrc_os_config.h"
17#include "config.h"
18#include "nrc.h"
19
20#if TARGET_OS == GIETVM
21    #include <user_lock.h>
22    #include <malloc.h>
23    #include <giet_config.h>
24    #include <user_barrier.h>
25#else
26    #include <unistd.h>
27#endif
28
29#include "util.h"
30#include "ecc_common.h"
31#include "ecc_features.h"
32#include "palette.h"
33#include "bmpNR.h"
34#include "mca_matrix_dist.h"
35#include "mca_rosenfeld.h"
36#include "clock.h"
37#include "str_ext.h"
38
39
40/* -- local -- */
41#include "mca.h"
42
43#define MAX_THREADS 256
44#define DEFAULT_NTHREADS 1
45#define DEFAULT_IN_FILENAME "/misc/cadastre.pgm"
46#define DEFAULT_OUT_FILENAME "out.bmp"
47
48pthread_t thread_table[MAX_THREADS];
49pthread_barrier_t main_barrier;
50int display_features = 0;
51int generate_output_image = 0;
52
53CLOCK_DEC;
54
55static void usage(char * name) {
56    printf("Usage: %s <options>\n", name);
57    printf("options:\n");
58    printf("  -i <input_file>  : Input file (default = %s)\n", DEFAULT_IN_FILENAME);
59    printf("  -o <output_file> : Output file (default = %s)\n", DEFAULT_OUT_FILENAME);
60    printf("  -nN              : N = number of threads (default = %d).\n", DEFAULT_NTHREADS);
61    printf("  -d               : Display features (default = false, requires features computation).\n");
62    printf("  -g               : Generate output image (default = false).\n");
63    printf("  -h               : Print out command line options.\n\n");
64}
65
66
67
68// --------------------------------------------------------------------------
69void init_forme_boulon1(uint8 *** X0, int * i0, int * i1, int * j0, int * j1)
70// --------------------------------------------------------------------------
71{
72    uint8 ** X;
73    int i =  0;
74    int h =  28;
75    int w =  30;
76   
77    X = ui8matrix(0, h - 1, 0, w - 1);
78    zero_ui8matrix(X, 0, h - 1, 0, w - 1);
79   
80    *X0 = X;
81    *i0 = 0;
82    *i1 = h - 1;
83    *j0 = 0;
84    *j1 = w - 1;
85   
86    //                                 0000000001111111111122222222223
87    //                                 0123456789012345678901234567890
88    set_ui8vector_str(X[i++], 0, w - 1, "                         111  "); // 00
89    set_ui8vector_str(X[i++], 0, w - 1, "                        11111 "); // 01
90    set_ui8vector_str(X[i++], 0, w - 1, "                      1111111 "); // 02
91    set_ui8vector_str(X[i++], 0, w - 1, "                     11111111 "); // 03
92    set_ui8vector_str(X[i++], 0, w - 1, "                    1111111111"); // 04
93    set_ui8vector_str(X[i++], 0, w - 1, "                   11111111111"); // 05
94    set_ui8vector_str(X[i++], 0, w - 1, "                 1111111111111"); // 06
95    set_ui8vector_str(X[i++], 0, w - 1, "               11111111111111 "); // 07
96    set_ui8vector_str(X[i++], 0, w - 1, "              11111111111111  "); // 08
97    set_ui8vector_str(X[i++], 0, w - 1, "             11111111111111   "); // 09
98    set_ui8vector_str(X[i++], 0, w - 1, "     11    11111111111111     "); // 10
99    set_ui8vector_str(X[i++], 0, w - 1, "    111   11111111111111      "); // 11
100    set_ui8vector_str(X[i++], 0, w - 1, "   11111111111111111111       "); // 12
101    set_ui8vector_str(X[i++], 0, w - 1, " 11111111111111111111         "); // 13
102    set_ui8vector_str(X[i++], 0, w - 1, "1111111111111111111           "); // 14
103    set_ui8vector_str(X[i++], 0, w - 1, " 11111111111111111            "); // 15
104    set_ui8vector_str(X[i++], 0, w - 1, " 1111111111111111             "); // 16
105    set_ui8vector_str(X[i++], 0, w - 1, " 111111111111111              "); // 17
106    set_ui8vector_str(X[i++], 0, w - 1, "  111111111111                "); // 18
107    set_ui8vector_str(X[i++], 0, w - 1, "  1111111111                  "); // 29
108    set_ui8vector_str(X[i++], 0, w - 1, "  1111111111                  "); // 20
109    set_ui8vector_str(X[i++], 0, w - 1, "   111111111                  "); // 21
110    set_ui8vector_str(X[i++], 0, w - 1, "   111111111                  "); // 22
111    set_ui8vector_str(X[i++], 0, w - 1, "    11111111                  "); // 23
112    set_ui8vector_str(X[i++], 0, w - 1, "    1111111                   "); // 24
113    set_ui8vector_str(X[i++], 0, w - 1, "     11111                    "); // 25
114    set_ui8vector_str(X[i++], 0, w - 1, "     111                      "); // 26
115    set_ui8vector_str(X[i++], 0, w - 1, "                              "); // 27
116   
117    //printf("[init_forme_boulon1]: h = %d i = %d\n", h, i);
118    if (i != h) {
119        MCA_Error("init_forme_boulon1 i != h");
120    }
121
122   
123    //display_ui8matrix_positive(X, 0, h-1, 0, w-1, 4, "forme_boulon1"); printf("");
124    //write_ui8matrix_positive(  X, 0, h-1, 0, w-1, 4, "forme_boulon1.txt");
125}
126
127
128// Renumbers object in a contiguous way, for an image which has already
129// been processed with several threads
130// ------------------------------------------------------------------
131static void renumber_image(MCA * mca, int i0, int i1, int j0, int j1)
132// ------------------------------------------------------------------
133{
134    int32_t na = 0;
135    uint32_t ** E = mca->E;
136    uint32_t ** D = mca->mcas[0]->D;
137
138    uint32_t shift = mca->alpha;
139    uint32_t mask = (1 << shift) - 1;
140   
141    for (int32_t p = 0; p < mca->np; p++) {
142        MCA * mca_par = mca->mcas[p];
143        uint32 * T = mca_par->T;
144        for (uint32_t e = mca_par->e0; e <= mca_par->ne; e++) {
145            if (T[e] != e) {
146                // FindRoot_Dist
147                uint32_t r = T[e];
148                uint32_t a = e;
149                do {
150                    uint32_t e1 = r >> shift;
151                    uint32_t e0 = r & mask;
152                    a = r;
153                    r = D[e1][e0];
154                } while (r < a);
155                T[e] = r;
156            }
157            else {
158                na += 1;
159                T[e] = na;
160            }
161        }
162    }
163
164    for (int32_t i = i0; i <= i1; i++) {
165        for (int32_t j = j0; j <= j1; j++) {
166            if (E[i][j] != 0) {
167                uint32_t e0 = E[i][j] & mask;
168                uint32_t e1 = E[i][j] >> shift;
169                E[i][j] = D[e1][e0];
170            }
171        }
172    }
173}
174
175
176// ----------------------------
177void mca_test1(int num_threads)
178// ----------------------------
179{
180    int i0, i1, j0, j1;
181    int height, width;
182   
183    uint8 ** X0;
184    uint32 ** E;
185    MCA * mca;
186
187    pthread_barrier_init(&main_barrier, NULL, num_threads);
188
189    // -- Allocation --
190    init_forme_boulon1(&X0, &i0, &i1, &j0, &j1);
191   
192    height = i1 - i0 + 1;
193    width  = j1 - j0 + 1;
194   
195    E = ui32matrix(i0, i1, j0, j1);
196   
197    zero_ui32matrix(E, i0, i1, j0, j1);
198   
199    mca = MCA_pConstructor_Empty();
200   
201    // -- set param
202    MCA_Set_Size(mca, width, height);
203    MCA_Set_ImageX(mca, X0);
204    MCA_Set_ImageL(mca, E);
205    MCA_Set_NP(mca, num_threads);
206   
207    // -- MCA init
208    MCA_Initialize(mca);
209    MCA_Display_Parameters(mca);
210   
211    display_ui8matrix_positive(mca->X, i0, i1, j0, j1, 5, "X0");
212    for (int i = 1; i < num_threads; i++) {
213        pthread_create(&thread_table[i], NULL, MCA_Label_Rosenfeld, (void *) mca->mcas[i]);
214    }
215   
216    MCA_Label_Rosenfeld(mca->mcas[0]);
217
218    for (int i = 1; i < num_threads; i++) {
219        pthread_join(thread_table[i], NULL);
220    }
221    display_ui32matrix_positive(mca->E, i0, i1, j0, j1, 5, "Efinal");
222
223   
224    // -- free --
225    MCA_VERBOSE1(printf("Finalize\n"));
226    MCA_Finalize(mca);
227   
228    MCA_VERBOSE1(printf("Free_matrix\n"));
229    free_ui8matrix (X0, i0, i1, j0, j1);
230    free_ui32matrix(E,  i0, i1, j0, j1);
231}
232
233
234
235// -----------------------------------------------------------
236void mca_test2(int num_threads, char * infile, char * outfile)
237// -----------------------------------------------------------
238{
239    int i0, i1, j0, j1;
240    int height, width;
241   
242    uint8 ** X;
243    uint8 ** E8;
244    uint32 ** E;
245    MCA * mca;
246
247    RGBQuad palette[256];
248
249    pthread_barrier_init(&main_barrier, NULL, num_threads);
250
251    Palette_18ColorsBW(palette);
252   
253    MCA_VERBOSE1(printf("Loading file %s... ", infile));
254    X = LoadPGM_ui8matrix(infile, &i0, &i1, &j0, &j1);
255    MCA_VERBOSE1(printf("done.\n"));
256
257    MCA_VERBOSE1(printf("Allocating memory... "));
258    height = i1 - i0 + 1;
259    width  = j1 - j0 + 1;
260   
261    E8 = ui8matrix (i0, i1, j0, j1);
262    E  = ui32matrix(i0, i1, j0, j1);
263   
264    zero_ui8matrix(E8, i0, i1, j0, j1);
265    zero_ui32matrix(E, i0, i1, j0, j1);
266
267    // pre-traitements
268    binarisation_ui8matrix(X, i0, i1, j0, j1, 20, 1, X); // pour le traitement
269    MCA_VERBOSE1(printf("done.\n"));
270
271    MCA_VERBOSE1(printf("Allocating and initializing MCA... \n"));
272    mca = MCA_pConstructor_Empty();
273   
274    // -- set param
275    MCA_Set_Size(mca, width, height);
276    MCA_Set_ImageX(mca, X);
277    MCA_Set_ImageL(mca, E);
278    MCA_Set_NP(mca, num_threads);
279   
280    // -- MCA init
281    MCA_Initialize(mca);
282    MCA_Display_Parameters(mca);
283    MCA_VERBOSE1(printf("End of MCA allocation and initialization.\n"));
284   
285    CLOCK_APP_CREATE;
286    for (int i = 1; i < num_threads; i++) {
287        pthread_create(&thread_table[i], NULL, MCA_Label_Rosenfeld, (void *) mca->mcas[i]);
288    }
289   
290    MCA_Label_Rosenfeld(mca->mcas[0]);
291
292    for (int i = 1; i < num_threads; i++) {
293        pthread_join(thread_table[i], NULL);
294    }
295    CLOCK_APP_JOIN;
296
297    if (generate_output_image) {
298#if TARGET_OS != GIETVM
299        renumber_image(mca, i0, i1, j0, j1);
300#else
301        printf("Warning: the output image has not been renumbered, it cannot be used as a comparison with the reference\n");
302#endif
303        mod_ui32matrix_ui8matrix(mca->E, i0, i1, j0, j1, E8);
304        MCA_VERBOSE1(printf("Saving file %s for verification... ", outfile));
305        SaveBMP2_ui8matrix(E8, width, height, palette, outfile);
306        MCA_VERBOSE1(printf("done.\n"));
307    }
308
309    MCA_Finalize(mca);
310    MCA_VERBOSE1(printf("Deallocating memory..."));
311    free_ui8matrix (X,  i0, i1, j0, j1);
312    free_ui8matrix (E8, i0, i1, j0, j1);
313    free_ui32matrix(E,  i0, i1, j0, j1);
314    MCA_VERBOSE1(printf("done.\n"));
315}
316
317
318// --------------------------------------------------------------
319int main_test_mca(int num_threads, char * infile, char * outfile)
320// --------------------------------------------------------------
321{
322    CLOCK_INIT(num_threads, 4); // 4 = Number of steps in body
323    CLOCK_APP_START;
324
325    mca_test2(num_threads, infile, outfile);
326
327    CLOCK_APP_END;
328    CLOCK_FINALIZE;
329    PRINT_CLOCK;
330    CLOCK_FREE;
331   
332    return 0;
333}
334
335
336#if TARGET_OS == GIETVM
337// ------------------------------------
338__attribute__((constructor)) int main()
339// ------------------------------------
340#else
341// -----------------------------
342int main(int argc, char ** argv)
343// -----------------------------
344#endif
345{
346    char * infile = DEFAULT_IN_FILENAME;
347    char * outfile = DEFAULT_OUT_FILENAME;
348
349    int ch;
350    int num_threads = DEFAULT_NTHREADS;
351
352    MCA_VERBOSE1(printf("*** Starting application Rosenfeld ***\n"));
353
354#if TARGET_OS != GIETVM // @QM I think the giet has some random (uninitialized) values for argc and argv
355    while ((ch = getopt(argc, argv, "i:o:n:hdg")) != EOF) {
356        switch (ch) {
357        case 'i':
358            infile = optarg;
359            break;
360        case 'o':
361            outfile = optarg;
362            break;
363        case 'n':
364            num_threads = atoi(optarg);
365            break;
366        case 'h':
367            usage(argv[0]);
368            return 0;
369            break;
370        case 'd':
371#if !FEATURES
372            fprintf(stderr, "*** Error: Features display requires features computation\n");
373            return 1;
374#endif
375            display_features = 1;
376            break;
377        case 'g':
378            generate_output_image = 1;
379            break;
380        default:
381            usage(argv[0]);
382            return 1;
383            break;
384        }
385    }
386
387    // Check arguments
388    if (num_threads < 1) {
389        fprintf(stderr, "*** Error: The number of threads must at least be 1\n");
390        usage(argv[0]);
391        return -1;
392    }
393#endif
394
395#if TARGET_OS == GIETVM
396    {
397        unsigned int xsize, ysize, nprocs;
398        giet_procs_number(&xsize, &ysize, &nprocs);
399        num_threads = xsize * ysize * nprocs;
400    }
401#endif
402
403    if (num_threads > MAX_THREADS) {
404        printf("*** Error: The maximum number of threads is %d, i.e. less than the current number of threads.\n", MAX_THREADS);
405        printf("Please recompile with a bigger MAX_THREADS value.\n");
406        exit(1);
407    }
408
409    MCA_VERBOSE1(printf("Parameters:\n"));
410    MCA_VERBOSE1(printf("- Number of threads: %d\n", num_threads));
411    MCA_VERBOSE1(printf("- Input file: %s\n", infile));
412    MCA_VERBOSE1(printf("- Output file: %s\n", outfile));
413#if FAST
414    MCA_VERBOSE1(printf("- Using decision trees (fast): yes\n"));
415#elif SLOW
416    MCA_VERBOSE1(printf("- Using decision trees (fast): no\n"));
417#endif
418#if FEATURES
419    MCA_VERBOSE1(printf("- Computing features: yes\n"));
420#else
421    MCA_VERBOSE1(printf("- Computing features: no\n"));
422#endif
423#if PARMERGE
424    MCA_VERBOSE1(printf("- Parallel Merge: yes\n"));
425#else
426    MCA_VERBOSE1(printf("- Parallel Merge: no\n"));
427#endif
428#if ARSP
429    MCA_VERBOSE1(printf("- Optimization ARemSP: yes\n"));
430#else
431    MCA_VERBOSE1(printf("- Optimization ARemSP: no\n"));
432#endif
433#if PYR_BARRIERS
434    MCA_VERBOSE1(printf("- Pyramidal Barriers: yes\n"));
435#else
436    MCA_VERBOSE1(printf("- Pyramidal Barriers: no\n"));
437#endif
438
439
440#if TARGET_OS == GIETVM
441    giet_tty_alloc(1);
442    MCA_VERBOSE1(printf("Initializing heaps... "));
443    for (int i = 0; i < X_SIZE; i++) {
444        for (int j = 0; j < X_SIZE; j++) {
445            heap_init(i, j);
446        }
447    }
448    MCA_VERBOSE1(printf("done.\n"));
449#endif
450
451    pthread_mutex_init(&print_lock, PTHREAD_PROCESS_PRIVATE);
452    main_test_mca(num_threads, infile, outfile);
453
454    return 0;
455}
456
457// Local Variables:
458// tab-width: 4
459// c-basic-offset: 4
460// c-file-offsets:((innamespace . 0)(inline-open . 0))
461// indent-tabs-mode: nil
462// End:
463
464// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
465
Note: See TracBrowser for help on using the repository browser.