Ignore:
Timestamp:
May 6, 2016, 3:06:29 PM (8 years ago)
Author:
meunier
Message:
  • 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:
1 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/applications/rosenfeld/src-par/mca_main.c

    r805 r821  
    11/* ------------------ */
    2 /* --- mca.c --- */
     2/* --- mca_main.c --- */
    33/* ------------------ */
    44
     
    1212#include <string.h>
    1313#include <math.h>
    14 
    15 #include <user_lock.h>
    16 
    17 #ifdef CLI
     14#include <malloc.h>
     15
    1816#include "nrc_os_config.h"
     17#include "config.h"
    1918#include "nrc.h"
    20 #endif
    21 
     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
    2228
    2329#include "util.h"
    2430#include "ecc_common.h"
    2531#include "ecc_features.h"
    26 
    2732#include "palette.h"
    2833#include "bmpNR.h"
    29 
     34#include "mca_matrix_dist.h"
     35#include "mca_rosenfeld.h"
     36#include "clock.h"
    3037#include "str_ext.h"
     38
    3139
    3240/* -- local -- */
    3341#include "mca.h"
    34 #include "mca_test.h"
    35 
    36 
     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
    37344// -----------------------------
    38 __attribute__((constructor)) void main()
     345int main(int argc, char ** argv)
    39346// -----------------------------
    40 {
     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
    41428#if TARGET_OS == GIETVM
    42429    giet_tty_alloc(1);
    43     heap_init(0, 0);
    44 #endif
    45     lock_init(&print_lock);
    46     main_test_mca();
    47 
    48     exit(0);
    49 }
    50 
     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 TracChangeset for help on using the changeset viewer.