verilog-to-routing / vtr-verilog-to-routing

Verilog to Routing -- Open Source CAD Flow for FPGA Research
https://verilogtorouting.org
Other
996 stars 385 forks source link

Integer overflow in RRG allocation for large designs #113

Closed EliasVansteenkiste closed 8 years ago

EliasVansteenkiste commented 8 years ago

Symptom: On a machine with 512gb work memory, VPR fails when trying to place sparcT1_chip2, bitcoin_miner, LU230, gsm_switch designs from the Titan benchmark suite with the following error message:

Error 1:
Type: Unknown
File: SRC/route/rr_graph2.c
Line: 2124
Message: Error:  Unable to malloc memory.  Aborting.

Cause: I looked into it and an integer overflow happens in the function alloc_sblock_pattern_lookup for the variable items.

short ******alloc_sblock_pattern_lookup(
        INP int L_nx, INP int L_ny, INP int max_chan_width) {

    /* loading up the sblock connection pattern matrix. It's a huge matrix because
     * for nonquantized W, it's impossible to make simple permutations to figure out
     * where muxes are and how to connect to them such that their sizes are balanced */

    /* Do chunked allocations to make freeing easier, speed up malloc and free, and
     * reduce some of the memory overhead. Could use fewer malloc's but this way
     * avoids all considerations of pointer sizes and allignment. */

    /* Alloc each list of pointers in one go. items is a running product that increases
     * with each new dimension of the matrix. */
    int items = 1;
    items *= (L_nx + 1);
    short ******i_list = (short ******) my_malloc(sizeof(short *****) * items);
    items *= (L_ny + 1);
    short *****j_list = (short *****) my_malloc(sizeof(short ****) * items);
    items *= (4);
    short ****from_side_list = (short ****) my_malloc(sizeof(short ***) * items);
    items *= (4);
    short ***to_side_list = (short ***) my_malloc(sizeof(short **) * items);
    items *= (max_chan_width);
    short **from_track_list = (short **) my_malloc(sizeof(short *) * items);
    items *= (4);
    short *from_track_types = (short *) my_malloc(sizeof(short) * items);

Let's say we have an architecture which has 500x500 blocks, a channel width of 300. In that case, items will have a value of 4.8 billion, which is slightly higher than the max value of a 32-bit integer, which is 4,294,967,295.

Solution: Change the type of items to unsigned long.

kmurray commented 8 years ago

Thanks for the report Elias.

Fixed in f2a02617642671707fc1669aff6847f4caa1c47c.