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

Last change on this file since 821 was 821, checked in by meunier, 8 years ago
  • Added several versions of rosenfeld: { SLOW, FAST } x { FEATURES, NO_FEATURES }
  • Added native linux compilation support
  • Added a script to check results natively
  • Started to refactor nrc code
File size: 13.6 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// QM : The cost of this function is horrible
129// but it is only for testing purpose
130// Renumbers object in a contiguous way, for an image which has already
131// been processed with several threads
132// --------------------------------------------------------------------
133static void renumber_image(uint32 ** E, int i0, int i1, int j0, int j1)
134// --------------------------------------------------------------------
135{
136    int size = 10;
137    int idx = 1; // next label to give, first invalid index in the equiv table
138    uint32 * equiv = malloc(sizeof(uint32) * size);
139    equiv[0] = 0; // unused
140    int found;
141
142    for (int i = i0; i <= i1; i++) {
143        for (int j = j0; j <= j1; j++) {
144            if (E[i][j] != 0) {
145                found = 0;
146                for (int k = 1; k < idx; k++) {
147                    if (equiv[k] == E[i][j]) {
148                        E[i][j] = k;
149                        found = 1;
150                        break;
151                    }
152                }
153                if (found == 0) {
154                    equiv[idx] = E[i][j];
155                    E[i][j] = idx;
156                    idx += 1;
157                    if (idx == size) {
158                        size = size * 2;
159                        equiv = realloc(equiv, sizeof(uint32) * size);
160                    }
161                }
162            }
163        }
164    }
165    free(equiv);
166}
167
168
169// ----------------------------
170void mca_test1(int num_threads)
171// ----------------------------
172{
173    int i0, i1, j0, j1;
174    int height, width;
175   
176    uint8 ** X0;
177    uint32 ** E;
178    MCA * mca;
179
180    pthread_barrier_init(&main_barrier, NULL, num_threads);
181
182    // -- Allocation --
183    init_forme_boulon1(&X0, &i0, &i1, &j0, &j1);
184   
185    height = i1 - i0 + 1;
186    width  = j1 - j0 + 1;
187   
188    E = ui32matrix(i0, i1, j0, j1);
189   
190    zero_ui32matrix(E, i0, i1, j0, j1);
191   
192    mca = MCA_pConstructor_Empty();
193   
194    // -- set param
195    MCA_Set_Size(mca, width, height);
196    MCA_Set_ImageX(mca, X0);
197    MCA_Set_ImageL(mca, E);
198    MCA_Set_NP(mca, num_threads);
199   
200    // -- MCA init
201    MCA_Initialize(mca);
202    MCA_Display_Parameters(mca);
203   
204    display_ui8matrix_positive(mca->X, i0, i1, j0, j1, 5, "X0");
205#if FEATURES
206    for (int i = 1; i < num_threads; i++) {
207        pthread_create(&thread_table[i], NULL, MCA_Label_Features_Rosenfeld, (void *) mca->mcas[i]);
208    }
209    MCA_Label_Features_Rosenfeld(mca->mcas[0]);
210#else
211    for (int i = 1; i < num_threads; i++) {
212        pthread_create(&thread_table[i], NULL, MCA_Label_Rosenfeld, (void *) mca->mcas[i]);
213    }
214    MCA_Label_Rosenfeld(mca->mcas[0]);
215#endif
216    for (int i = 1; i < num_threads; i++) {
217        pthread_join(thread_table[i], NULL);
218    }
219    display_ui32matrix_positive(mca->E, i0, i1, j0, j1, 5, "Efinal");
220
221   
222    // -- free --
223    printf("Finalize\n");
224    MCA_Finalize(mca);
225   
226    printf("Free_matrix\n");
227    free_ui8matrix (X0, i0, i1, j0, j1);
228    free_ui32matrix(E,  i0, i1, j0, j1);
229}
230
231
232
233// -----------------------------------------------------------
234void mca_test2(int num_threads, char * infile, char * outfile)
235// -----------------------------------------------------------
236{
237    int i0, i1, j0, j1;
238    int height, width;
239   
240    uint8 ** X;
241    uint8 ** E8;
242    uint32 ** E;
243    MCA * mca;
244
245    RGBQuad palette[256];
246
247    pthread_barrier_init(&main_barrier, NULL, num_threads);
248
249    Palette_18ColorsBW(palette);
250   
251    printf("Loading file %s... ", infile);
252    X = LoadPGM_ui8matrix(infile, &i0, &i1, &j0, &j1);
253    printf("done.\n");
254
255    printf("Allocating memory... ");
256    height = i1 - i0 + 1;
257    width  = j1 - j0 + 1;
258   
259    E8 = ui8matrix (i0, i1, j0, j1);
260    E  = ui32matrix(i0, i1, j0, j1);
261   
262    zero_ui8matrix(E8, i0, i1, j0, j1);
263    zero_ui32matrix(E, i0, i1, j0, j1);
264
265    // pre-traitements
266    binarisation_ui8matrix(X, i0, i1, j0, j1, 20, 1, X); // pour le traitement
267    printf("done.\n");
268
269    printf("Allocating and initializing MCA... \n");
270    mca = MCA_pConstructor_Empty();
271   
272    // -- set param
273    MCA_Set_Size(mca, width, height);
274    MCA_Set_ImageX(mca, X);
275    MCA_Set_ImageL(mca, E);
276    MCA_Set_NP(mca, num_threads);
277   
278    // -- MCA init
279    MCA_Initialize(mca);
280    MCA_Display_Parameters(mca);
281    printf("End of MCA allocation and initialization.\n");
282   
283    CLOCK_APP_CREATE;
284#if FEATURES
285    for (int i = 1; i < num_threads; i++) {
286        pthread_create(&thread_table[i], NULL, MCA_Label_Features_Rosenfeld, (void *) mca->mcas[i]);
287    }
288    MCA_Label_Features_Rosenfeld(mca->mcas[0]);
289#else
290    for (int i = 1; i < num_threads; i++) {
291        pthread_create(&thread_table[i], NULL, MCA_Label_Rosenfeld, (void *) mca->mcas[i]);
292    }
293    MCA_Label_Rosenfeld(mca->mcas[0]);
294#endif
295    for (int i = 1; i < num_threads; i++) {
296        pthread_join(thread_table[i], NULL);
297    }
298    CLOCK_APP_JOIN;
299
300    if (generate_output_image) {
301#if TARGET_OS != GIETVM
302        renumber_image(mca->E, i0, i1, j0, j1);
303#else
304        printf("Warning: the output image has not been renumbered, it cannot be used as a comparison with the reference\n");
305#endif
306        mod_ui32matrix_ui8matrix(mca->E, i0, i1, j0, j1, E8);
307        printf("Saving file %s for verification... ", outfile);
308        SaveBMP2_ui8matrix(E8, width, height, palette, outfile);
309        printf("done.\n");
310    }
311
312    MCA_Finalize(mca);
313    printf("Deallocating memory...");
314    free_ui8matrix (X,  i0, i1, j0, j1);
315    free_ui8matrix (E8, i0, i1, j0, j1);
316    free_ui32matrix(E,  i0, i1, j0, j1);
317    printf("done.\n");
318}
319
320
321// --------------------------------------------------------------
322int main_test_mca(int num_threads, char * infile, char * outfile)
323// --------------------------------------------------------------
324{
325    CLOCK_INIT(num_threads, 4); // 4 = Number of steps in body
326    CLOCK_APP_START;
327
328    mca_test2(num_threads, infile, outfile);
329
330    CLOCK_APP_END;
331    CLOCK_FINALIZE;
332    PRINT_CLOCK;
333    CLOCK_FREE;
334   
335    return 0;
336}
337
338
339#if TARGET_OS == GIETVM
340// ------------------------------------
341__attribute__((constructor)) int main()
342// ------------------------------------
343#else
344// -----------------------------
345int main(int argc, char ** argv)
346// -----------------------------
347#endif
348{
349    char * infile = DEFAULT_IN_FILENAME;
350    char * outfile = DEFAULT_OUT_FILENAME;
351
352    int ch;
353    int num_threads = DEFAULT_NTHREADS;
354
355    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: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 'h':
370            usage(argv[0]);
371            return 0;
372            break;
373        case 'd':
374#if !FEATURES
375            fprintf(stderr, "*** Error: Features display requires features computation\n");
376            return 1;
377#endif
378            display_features = 1;
379            break;
380        case 'g':
381            generate_output_image = 1;
382            break;
383        default:
384            usage(argv[0]);
385            return 1;
386            break;
387        }
388    }
389
390    // Check arguments
391    if (num_threads < 1) {
392        fprintf(stderr, "*** Error: The number of threads must at least be 1\n");
393        usage(argv[0]);
394        return -1;
395    }
396#endif
397
398#if TARGET_OS == GIETVM
399    {
400        unsigned int xsize, ysize, nprocs;
401        giet_procs_number(&xsize, &ysize, &nprocs);
402        num_threads = xsize * ysize * nprocs;
403    }
404#endif
405
406    if (num_threads > MAX_THREADS) {
407        printf("*** Error: The maximum number of threads is %d, i.e. less than the current number of threads.\n", MAX_THREADS);
408        printf("Please recompile with a bigger MAX_THREADS value.\n");
409        exit(1);
410    }
411
412    printf("Parameters:\n");
413    printf("- Number of threads: %d\n", num_threads);
414    printf("- Input file: %s\n", infile);
415    printf("- Output file: %s\n", outfile);
416#if FAST
417    printf("- Using decision trees (fast): yes\n");
418#elif SLOW
419    printf("- Using decision trees (fast): no\n");
420#endif
421#if FEATURES
422    printf("- Computing features: yes\n");
423#else
424    printf("- Computing features: no\n");
425#endif
426
427
428#if TARGET_OS == GIETVM
429    giet_tty_alloc(1);
430    printf("Initializing heaps... ");
431    for (int i = 0; i < X_SIZE; i++) {
432        for (int j = 0; j < X_SIZE; j++) {
433            heap_init(i, j);
434        }
435    }
436    printf("done.\n");
437#endif
438
439    pthread_mutex_init(&print_lock, PTHREAD_PROCESS_PRIVATE);
440    main_test_mca(num_threads, infile, outfile);
441
442    return 0;
443}
444
Note: See TracBrowser for help on using the repository browser.