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

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