├── README.md ├── doc ├── make_build.out ├── make_clean.out └── make_test.out ├── input ├── biomed ├── hp1 ├── hp9 ├── industry2 └── industry3 └── src ├── Makefile ├── fms ├── Makefile ├── ad_fms.c ├── ad_lib_fms.c ├── ad_lib_fms.h ├── utest.awk └── utest.sh ├── pfm ├── Makefile ├── ad_lib_pfm.c ├── ad_lib_pfm.h ├── ad_pfm.c ├── utest.awk └── utest.sh ├── plm ├── Makefile ├── ad_lib_plm.c ├── ad_lib_plm.h ├── ad_plm.c ├── utest.awk └── utest.sh ├── sa ├── Makefile ├── ad_lib_sa.c ├── ad_lib_sa.h ├── ad_rsa.c ├── ad_sa1.c ├── ad_sa2.c ├── utest.awk └── utest.sh └── share ├── Makefile ├── ad_bucketio.c ├── ad_bucketio.h ├── ad_defs.h ├── ad_fileio.c ├── ad_fileio.h ├── ad_lib.c ├── ad_lib.h ├── ad_partition.c ├── ad_partition.h ├── ad_print.c ├── ad_print.h ├── ad_random.c ├── ad_random.h ├── ad_readinput.c └── ad_readinput.h /README.md: -------------------------------------------------------------------------------- 1 | # hypergraph-partitioning-algorithms 2 | ================================== 3 | 4 | This package contains the multi-way hypergraph partitioning 5 | algorithms: FMS (Fiduccia-Mattheyses-Sanchis), PLM (Partitioning by 6 | Locked Moves), PFM (Partitioning by Free Moves), SA (Simulated 7 | Annealing - 2 versions), and RSA (Simulated Annealing with ratio cut 8 | model - 2-way partitioning only), as detailed in [DaAy97]. 9 | 10 | ## THE HYPERGRAPH PARTITIONING PROBLEM 11 | 12 | The hypergraph partitioning problem is defined as follows: Given an 13 | input hypergraph, partition it into a given number of almost 14 | equal-sized parts in such a way that the cutsize, i.e., the sum of the 15 | net weights whose end cells are in different parts, is minimized. This 16 | problem has many variations as well as has important applications in 17 | many areas. Unfortunately, the problem is NP-hard so the algorithms in 18 | this package are heuristics (but they work very very well). 19 | 20 | If you do not know what a hypergraph is, remember this: In a graph, 21 | you have vertices and edges, where every edge connects two vertices; 22 | in a hypergraph, you have vertices and hyperedges, where every 23 | hyperedge connects two or more vertices. Since hypergraphs can model 24 | electronic circuits well, a hypergraph is often said to have cells and 25 | nets instead of vertices and hyperedges. In a circuit cell where a net 26 | is connected is called a pin. You may see the cell, net, and pin 27 | terminology in my code. 28 | 29 | ## A SHORT HISTORY ON THESE ALGORITHMS 30 | 31 | The basis for these algorithms go back to the Kernighan-Lin (KL) 32 | algorithm for hypergraph partitioning. The KL algorithm produces very 33 | good partitions but it is slow. The Fiduccia-Mattheyses (FM) algorithm 34 | is not only a faster version of the KL algorithm but it also 35 | generalizes the KL algorithm to run on hypergraphs. Sanchis 36 | generalized the FM algorithm from 2-way partitioning to multi-way 37 | partitioning. 38 | 39 | All these KL-based algorithms work in multiple passes over the number 40 | of vertices; in each pass, these algorithms find the best destination 41 | part for a cell and lock this cell from moving again in the rest of 42 | the current pass. Realizing the limitations of this "locking" 43 | mechanism, I devised ways to relax this mechanism, resulting in the 44 | Partitioning by Locked Moves (PLM) algorithm and the Partitioning by 45 | Free Moves (PFM) algorithm. The PLM algorithm still uses locking but 46 | it goes through multiple phases of locking and unlocking within a pass 47 | over the input hypergraph. The PFM algorithm does not use locking at 48 | all; it uses a way to penalize the moves to march towards a local 49 | minimum. For more details, please refer to [DaAy97]. 50 | 51 | ## MORE INTRODUCTION 52 | 53 | I originally developed this package in C during my MSc study (around 54 | 1991-1993). Before putting this package on github, I converted my code 55 | to ANSI C (c99) and cleaned it quite a bit. 56 | 57 | In my code, you may notice some biologically inspired names such as 58 | 'population', 'chromosome', 'allele', etc. These names actually come 59 | from genetic algorithms. During my MSc years, my eventual goal was to 60 | implement graph and hypergraph partitioning using genetic algorithms 61 | on a hypercube connected parallel computer (from Intel). Once I 62 | discovered the limitations of the locking mechanism, I changed my 63 | research direction towards what would become PLM and PFM. By the way, 64 | I did still work on genetic algorithms but in a different setting 65 | (applying genetic algorithms to synthesize unsupervised learning 66 | algorithms). 67 | 68 | This package is available on an "as is" basis. I do not say or imply 69 | that it will be useful for whatever you want to do with it. It may 70 | also contain bugs, and I assume no responsibility for any potential 71 | problems associated with its use. You can use this package free of 72 | charge in academic research and teaching. For any commercial use, 73 | contact Ali Dasdan at ali_dasdan@yahoo.com. See the COPYRIGHT section 74 | below. 75 | 76 | ## DIRECTORY STRUCTURE 77 | 78 | At the top level, you see two directories: 'src' and 'input'. 'src' 79 | contains all the source files and 'input' contains the input 80 | hypergraphs used for testing the executables. Under 'src', there is 81 | one directory, called 'share', for the shared source files as well as 82 | one directory for each algorithm: 'fms', 'plm', 'pfm', and 'sa'. Note 83 | that there will be three executables under the 'sa' directory, one for 84 | each version of simulated annealing. 85 | 86 | ## HOW TO BUILD 87 | 88 | Under 'src', type 'make' (or 'gmake') to build each executable under 89 | its own directory. The executables are all have .x extension: 90 | ad_fms.x, ad_plm.x, ad_pfm.x, ad_sa1.x, ad_sa2.x, and ad_rsa.x. 91 | 92 | The output you expect to see with 'make' is shown in 93 | 'doc/make_build.out'. 94 | 95 | ## HOW TO RUN 96 | 97 | Go to the respective directory for an algorithm and type the name of 98 | one of the executables in your command line to get the usage 99 | information. At minimum, each executable requires the input hypergraph 100 | and the number of parts to partition the hypergraph. PLM and PFM 101 | require additional parameters to create different versions of them, 102 | which trade off runtime for partition quality. 103 | 104 | For example, a run of FMS (in 'ad_fms.x') to partition the input 105 | hypergraph 'p9' into two parts will produce this output: 106 | 107 | ``` 108 | > ad_fms.x input/hp9 2 123456 109 | SEED = 123456 fname = input/p9 110 | pass_no = 7 Final cutsize = 85 Check cutsize = 85 111 | ``` 112 | 113 | This output shows that FMS took 7 passes over the cells of the input 114 | hypergraph 'hp9' when started with a seed of 123456. Note that 115 | specifying a seed will make the results repeatable. FMS found a 116 | cutsize of 85, which is correct as FMS and the other programs will 117 | check every cutsize they report for correctness. That is, each of the 118 | executables are self validating. 119 | 120 | __NOTE__: When you run this program for a large number of parts (i.e., 121 | the 2nd argument on the command line), you may get a seg fault. The 122 | reason seems to be the allocation of the 2D array 'partb' on the 123 | stack. When I find time (hopefully soon), I will remove this weakness 124 | by allocating partb dynamically on the heap. 125 | 126 | ## HOW TO TEST 127 | 128 | Under 'src', type 'make test' to test each executable on the input 129 | hypergraphs under the 'input' directory. The result will be a 'pass' 130 | or a 'fail'. 131 | 132 | The output you expect to see with 'make test' is shown in 133 | 'doc/make_test.out'. 134 | 135 | ## HOW TO CLEAN 136 | 137 | Under 'src', type 'make clean' to clean all temporary files including 138 | the object files and the executables. 139 | 140 | The output you expect to see with 'make clean' is shown in 141 | 'doc/make_clean.out'. 142 | 143 | ## INPUT FILE FORMAT 144 | 145 | The input file format is explained below using a very simple hypergraph. 146 | 147 | ``` 148 | > cat input/hp1 149 | 6 150 | 7 151 | 14 152 | 1 2 0 1 153 | 1 2 1 2 154 | 1 2 2 0 155 | 1 2 3 4 156 | 1 2 4 5 157 | 1 2 5 3 158 | 1 2 0 3 159 | 1 160 | 1 161 | 1 162 | 1 163 | 1 164 | 1 165 | ``` 166 | 167 | The first three lines give the number of cells, the number of nets, 168 | and the number of pins (or endpoints), respectively. Thus, 'p1' has 6 169 | vertices, 7 edges, and 14 pins. 170 | 171 | The following 7 lines describe the nets, one net per line. The first 172 | number is the net weight; the second number is the number of pins on 173 | this net (always equal to 2 for graphs)); the third number is the 174 | source cell; and the fourth number is the target cell. For example, 175 | the first net from cell 0 to cell 1 has a weight of 1. 176 | 177 | The last 6 lines describe the cell weights. 178 | 179 | ## REFERENCE 180 | 181 | Please cite this reference if you use my programs in your research 182 | work. 183 | 184 | ``` 185 | @article{DaAy97, 186 | author = {Ali Dasdan and C. Aykanat}, 187 | title = {Two Novel Circuit Partitioning Algorithms Using Relaxed Locking}, 188 | journal = {IEEE Transactions on Computer-Aided Design of Integrated Circuits and Systems (TCAD)}, 189 | volume = {16}, 190 | number = {2}, 191 | year = {1997}, 192 | pages = {169-178}, 193 | url = {http://yoksis.bilkent.edu.tr/doi_getpdf/articles/10.1109-43.573831.pdf}, 194 | } 195 | ``` 196 | 197 | ## COPYRIGHT 198 | 199 | COPYRIGHT C 1991 - Ali Dasdan 200 | 201 | Permission to use for non-commercial purposes is granted provided that 202 | proper acknowledgments are given. For a commercial licence, contact 203 | Ali Dasdan at ali_dasdan@yahoo.com. 204 | 205 | This software is provided on an "as is" basis, without warranties or 206 | conditions of any kind, either express or implied including, without 207 | limitation, any warranties or conditions of title, non-infringement, 208 | merchantability or fitness for a particular purpose. 209 | 210 | ## END OF FILE 211 | 212 | -------------------------------------------------------------------------------- /doc/make_build.out: -------------------------------------------------------------------------------- 1 | make -C share all 2 | gcc -O3 -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow -c -o ad_bucketio.o ad_bucketio.c 3 | gcc -O3 -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow -c -o ad_fileio.o ad_fileio.c 4 | gcc -O3 -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow -c -o ad_lib.o ad_lib.c 5 | gcc -O3 -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow -c -o ad_partition.o ad_partition.c 6 | gcc -O3 -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow -c -o ad_print.o ad_print.c 7 | gcc -O3 -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow -c -o ad_random.o ad_random.c 8 | gcc -O3 -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow -c -o ad_readinput.o ad_readinput.c 9 | make -C fms all 10 | gcc -O3 -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow -I../share -c -o ad_lib_fms.o ad_lib_fms.c 11 | gcc -O3 -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow -I../share -o ad_fms.x ad_fms.c ../share/ad_bucketio.o ../share/ad_fileio.o ../share/ad_lib.o ../share/ad_partition.o ../share/ad_print.o ../share/ad_random.o ../share/ad_readinput.o ad_lib_fms.o 12 | make -C plm all 13 | gcc -O3 -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow -I../share -c -o ad_lib_plm.o ad_lib_plm.c 14 | gcc -O3 -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow -I../share -o ad_plm.x ad_plm.c ../share/ad_bucketio.o ../share/ad_fileio.o ../share/ad_lib.o ../share/ad_partition.o ../share/ad_print.o ../share/ad_random.o ../share/ad_readinput.o ad_lib_plm.o 15 | make -C pfm all 16 | gcc -O3 -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow -I../share -c -o ad_lib_pfm.o ad_lib_pfm.c -lm 17 | gcc -O3 -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow -I../share -o ad_pfm.x ad_pfm.c ../share/ad_bucketio.o ../share/ad_fileio.o ../share/ad_lib.o ../share/ad_partition.o ../share/ad_print.o ../share/ad_random.o ../share/ad_readinput.o ad_lib_pfm.o -lm 18 | make -C sa all 19 | gcc -O3 -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow -I../share -c -o ad_lib_sa.o ad_lib_sa.c -lm 20 | gcc -O3 -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow -I../share -o ad_sa1.x ad_sa1.c ../share/ad_bucketio.o ../share/ad_fileio.o ../share/ad_lib.o ../share/ad_partition.o ../share/ad_print.o ../share/ad_random.o ../share/ad_readinput.o ad_lib_sa.o -lm 21 | gcc -O3 -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow -I../share -o ad_sa2.x ad_sa2.c ../share/ad_bucketio.o ../share/ad_fileio.o ../share/ad_lib.o ../share/ad_partition.o ../share/ad_print.o ../share/ad_random.o ../share/ad_readinput.o ad_lib_sa.o -lm 22 | gcc -O3 -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow -I../share -o ad_rsa.x ad_rsa.c ../share/ad_bucketio.o ../share/ad_fileio.o ../share/ad_lib.o ../share/ad_partition.o ../share/ad_print.o ../share/ad_random.o ../share/ad_readinput.o ad_lib_sa.o -lm 23 | -------------------------------------------------------------------------------- /doc/make_clean.out: -------------------------------------------------------------------------------- 1 | make -C share clean 2 | rm -f *.o *~ core *.x 3 | make -C fms clean 4 | rm -f *.o *~ core *.x 5 | make -C plm clean 6 | rm -f *.o *~ core *.x 7 | make -C pfm clean 8 | rm -f *.o *~ core *.x 9 | make -C sa clean 10 | rm -f *.o *~ core *.x 11 | -------------------------------------------------------------------------------- /doc/make_test.out: -------------------------------------------------------------------------------- 1 | make -C fms test 2 | ./utest.sh 3 | Passed: program=ad_fms p1 2: cutsize=1 target=1 4 | Passed: program=ad_fms p9 2: cutsize=85 target=85 5 | Passed: program=ad_fms p9 3: cutsize=201 target=201 6 | make -C plm test 7 | ./utest.sh 8 | Passed: program=ad_plm p1 2 1 1: cutsize=1 target=1 9 | Passed: program=ad_plm p1 2 2 1: cutsize=1 target=1 10 | Passed: program=ad_plm p1 2 1 2: cutsize=1 target=1 11 | Passed: program=ad_plm p9 2 1 1: cutsize=26 target=26 12 | Passed: program=ad_plm p9 3 1 1: cutsize=157 target=157 13 | Passed: program=ad_plm p9 2 2 1: cutsize=35 target=35 14 | Passed: program=ad_plm p9 3 2 1: cutsize=163 target=163 15 | Passed: program=ad_plm p9 2 1 2: cutsize=27 target=27 16 | Passed: program=ad_plm p9 3 1 2: cutsize=175 target=175 17 | make -C pfm test 18 | ./utest.sh 19 | Passed: program=ad_pfm p1 2 1 1: cutsize=1 target=1 20 | Passed: program=ad_pfm p1 2 2 1: cutsize=1 target=1 21 | Passed: program=ad_pfm p1 2 3 1: cutsize=1 target=1 22 | Passed: program=ad_pfm p9 2 1 1: cutsize=75 target=75 23 | Passed: program=ad_pfm p9 3 1 1: cutsize=69 target=69 24 | Passed: program=ad_pfm p9 2 2 1: cutsize=53 target=53 25 | Passed: program=ad_pfm p9 3 2 1: cutsize=75 target=75 26 | Passed: program=ad_pfm p9 2 3 2: cutsize=32 target=32 27 | Passed: program=ad_pfm p9 3 3 2: cutsize=58 target=58 28 | make -C sa test 29 | ./utest.sh 30 | Passed: program=ad_sa1 p1 2: cutsize=1 target=1 31 | Passed: program=ad_sa2 p1 2: cutsize=1 target=1 32 | Passed: program=ad_rsa p1 2: cutsize=1 target=1 33 | Passed: program=ad_sa1 p9 2: cutsize=40 target=40 34 | Passed: program=ad_sa1 p9 3: cutsize=56 target=56 35 | Passed: program=ad_sa2 p9 2: cutsize=70 target=70 36 | Passed: program=ad_sa2 p9 3: cutsize=119 target=119 37 | Passed: program=ad_rsa p9 2: cutsize=35 target=35 38 | -------------------------------------------------------------------------------- /input/hp1: -------------------------------------------------------------------------------- 1 | 6 2 | 7 3 | 14 4 | 1 2 0 1 5 | 1 2 1 2 6 | 1 2 2 0 7 | 1 2 3 4 8 | 1 2 4 5 9 | 1 2 5 3 10 | 1 2 0 3 11 | 1 12 | 1 13 | 1 14 | 1 15 | 1 16 | 1 17 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | make -C share all 3 | make -C fms all 4 | make -C plm all 5 | make -C pfm all 6 | make -C sa all 7 | 8 | test: 9 | make -C fms test 10 | make -C plm test 11 | make -C pfm test 12 | make -C sa test 13 | 14 | clean: 15 | make -C share clean 16 | make -C fms clean 17 | make -C plm clean 18 | make -C pfm clean 19 | make -C sa clean 20 | 21 | -------------------------------------------------------------------------------- /src/fms/Makefile: -------------------------------------------------------------------------------- 1 | CC0 = gcc 2 | CC = $(CC0) 3 | LD = $(CC0) 4 | FLAGS1 = -O3 5 | FLAGS2 = -lm 6 | FLAGS3 = -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow 7 | DIR_H = ../share 8 | FLAGS = $(FLAGS1) $(FLAGS3) -I$(DIR_H) 9 | 10 | DEPS_SHARE = $(DIR_H)/ad_bucketio.h \ 11 | $(DIR_H)/ad_fileio.h \ 12 | $(DIR_H)/ad_lib.h \ 13 | $(DIR_H)/ad_partition.h \ 14 | $(DIR_H)/ad_print.h \ 15 | $(DIR_H)/ad_random.h \ 16 | $(DIR_H)/ad_readinput.h 17 | 18 | DEPS_FMS = ad_lib_fms.h $(DIR_H)/ad_defs.h $(DEPS_SHARE) 19 | OBJS = $(patsubst %.h,%.o,$(DEPS_SHARE)) 20 | OBJS_FMS = $(OBJS) ad_lib_fms.o 21 | 22 | all: ad_fms 23 | 24 | ad_lib_fms.o: ad_lib_fms.c ad_lib_fms.h $(DIR_H)/ad_lib.h $(DIR_H)/ad_bucketio.h $(DIR_H)/ad_defs.h 25 | $(CC) $(FLAGS) -c -o $@ $< 26 | 27 | ad_fms: ad_fms.c $(DEPS_FMS) $(OBJS_FMS) 28 | $(CC) $(FLAGS) -o $@.x $< $(OBJS_FMS) 29 | 30 | # Testing: 31 | test: 32 | ./utest.sh 33 | 34 | # Cleaning: 35 | clean c cl cle clea: 36 | rm -f *.o *~ core *.x 37 | cleano: 38 | rm -f *.o *~ core 39 | 40 | # End of file 41 | -------------------------------------------------------------------------------- /src/fms/ad_fms.c: -------------------------------------------------------------------------------- 1 | 2 | /* COPYRIGHT C 1991- Ali Dasdan */ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "ad_defs.h" 9 | #include "ad_random.h" 10 | #include "ad_fileio.h" 11 | #include "ad_readinput.h" 12 | #include "ad_partition.h" 13 | #include "ad_print.h" 14 | #include "ad_bucketio.h" 15 | #include "ad_lib.h" 16 | #include "ad_lib_fms.h" 17 | 18 | /* FOR SANCHIS' VERSION OF MULTI-WAY PARTITIONING */ 19 | /* Also mentioned as the SN algorithm */ 20 | /* Direct multi-way partitioning. 21 | Locking is used. 22 | Cells are moved wrt their gains 23 | */ 24 | 25 | int main(int argc, char *argv[]) 26 | { 27 | /* definitions */ 28 | int nocells; /* number of cells */ 29 | int nonets; /* number of nets */ 30 | int nopins; /* number of pins */ 31 | int noparts; /* number of partitions */ 32 | int totcellsize; /* total cell weight of the partition */ 33 | int totnetsize; /* total net weight of the partition */ 34 | int cutsize; /* cutsize of the partition */ 35 | int max_gain; /* max gain of a cell */ 36 | int max_cdeg; /* max density of a cell */ 37 | int max_ndeg; /* max density of a net */ 38 | int max_cweight; /* max cell weight */ 39 | int max_nweight; /* max net weight */ 40 | int bucketsize; /* max size of a bucket array */ 41 | int msize; /* index to mcells */ 42 | 43 | if (argc < 3) { 44 | printf("\nUsage: %s InputFileName NoParts [Seed]\n", argv[0]); 45 | exit(1); 46 | } /* if */ 47 | 48 | char fname[STR_SIZE]; 49 | sprintf(fname, "%s", argv[1]); 50 | 51 | noparts = atoi(argv[2]); 52 | 53 | long seed; 54 | if (argc > 3) { 55 | seed = (long) atoi(argv[3]); 56 | } else { 57 | seed = -1; 58 | } 59 | seed = randomize((long) seed); 60 | printf("SEED = %ld fname = %s\n", seed, fname); 61 | 62 | read_hgraph_size(fname, &nocells, &nonets, &nopins); 63 | 64 | /* alloc memory for all data structures */ 65 | cells_t *cells = (cells_t *) calloc(nocells, sizeof(cells_t)); 66 | assert(cells != NULL); 67 | cells_info_t *cells_info = (cells_info_t *) calloc(nocells, sizeof(cells_info_t)); 68 | assert(cells_info != NULL); 69 | for (int i = 0; i < nocells; i++) { 70 | cells_info[i].mgain = (int *) calloc(noparts, sizeof(int)); 71 | assert(cells_info[i].mgain != NULL); 72 | cells_info[i].partb_ptr = (bnode_ptr_t *) calloc(noparts - 1, sizeof(bnode_ptr_t)); 73 | assert(cells_info[i].partb_ptr != NULL); 74 | cells_info[i].partb_gain_inx = (int *) calloc(noparts - 1, sizeof(int)); 75 | assert(cells_info[i].partb_gain_inx != NULL); 76 | } 77 | 78 | nets_t *nets = (nets_t *) calloc(nonets, sizeof(nets_t)); 79 | assert(nets != NULL); 80 | nets_info_t *nets_info = (nets_info_t *) calloc(nonets, sizeof(nets_info_t)); 81 | assert(nets_info != NULL); 82 | for (int i = 0; i < nonets; i++) { 83 | nets[i].npartdeg = (int *) calloc(noparts, sizeof(int)); 84 | assert(nets[i].npartdeg != NULL); 85 | nets_info[i].npartdeg = (int *) calloc(noparts, sizeof(int)); 86 | assert(nets_info[i].npartdeg != NULL); 87 | } 88 | 89 | /* cells of nets */ 90 | corn_t *cnets = (corn_t *) calloc(nopins, sizeof(corn_t)); 91 | assert(cnets != NULL); 92 | /* nets of cells */ 93 | corn_t *ncells = (corn_t *) calloc(nopins, sizeof(corn_t)); 94 | assert(ncells != NULL); 95 | 96 | /* partition buckets */ 97 | partb_t partb[noparts][noparts - 1]; 98 | parts_info_t parts_info[noparts]; 99 | 100 | /* population (w/ one individual!) */ 101 | ind_t pop[MAX_POP]; 102 | for (int i = 0; i < MAX_POP; i++) { 103 | pop[i].chrom = (allele *) calloc(nocells, sizeof(allele)); 104 | assert(pop[i].chrom != NULL); 105 | pop[i].parts = (parts_t *) calloc(noparts, sizeof(parts_t)); 106 | assert(pop[i].parts != NULL); 107 | } 108 | 109 | /* selected cell */ 110 | selected_cell_t scell[1]; 111 | 112 | /* moved cells */ 113 | mcells_t *mcells = (mcells_t *) calloc(nocells, sizeof(mcells_t)); 114 | assert(mcells != NULL); 115 | 116 | read_hgraph(fname, nocells, nonets, nopins, noparts, 117 | &totcellsize, &totnetsize, &max_cdeg, &max_ndeg, 118 | &max_cweight, &max_nweight, 119 | cells, nets, cnets, ncells); 120 | 121 | max_gain = max_cdeg * max_nweight; 122 | bucketsize = 2 * max_gain + 1; 123 | 124 | /* alloc memory (statically if possible) */ 125 | for (int i = 0; i < noparts; i++) { 126 | for (int j = 0; j < noparts - 1; ++j) { 127 | partb[i][j].bnode_ptr = (bnode_ptr_t *) calloc(bucketsize, sizeof(bnode_ptr_t)); 128 | } 129 | } 130 | 131 | float off_ratio = (float) 0.1; 132 | create_partition(nocells, noparts, totcellsize, max_cweight, &off_ratio, 133 | cells, nets, cnets, &pop[0]); 134 | 135 | #ifdef DEBUG 136 | printf("off=%f\n", off_ratio); 137 | printf("Initial : Part_no min_size curr_size max_size\n"); 138 | for (int i = 0; i < noparts; i++) { 139 | printf("II %d %d %d %d\n", i, pop[0].parts[i].pmin_size, 140 | pop[0].parts[i].pcurr_size, pop[0]. parts[i].pmax_size); 141 | } 142 | #endif 143 | 144 | init_buckets(noparts, bucketsize, partb); 145 | cutsize = find_cut_size(nonets, noparts, totnetsize, nets, &pop[0]); 146 | 147 | #ifdef DEBUG 148 | printf("Totalsize = %d Initial cutsize = %d\n", totnetsize, cutsize); 149 | #endif 150 | 151 | int gain_sum; 152 | int no_iter = 0; 153 | int glob_inx = 0; 154 | do { 155 | 156 | copy_partition(noparts, parts_info, &pop[0]); 157 | 158 | copy_nets_info(nonets, noparts, nets, nets_info); 159 | 160 | compute_gains(nocells, noparts, cells, nets, cnets, 161 | cells_info, pop[0].chrom); 162 | 163 | create_buckets(nocells, noparts, max_gain, pop[0].chrom, 164 | partb, cells_info); 165 | 166 | msize = 0; 167 | 168 | int nlocked = 0; 169 | do { 170 | int move_possible = select_cell(noparts, scell, parts_info, cells, 171 | partb, cells_info); 172 | 173 | delete_partb_nodes_of_cell(noparts, scell[0].mov_cell_no, 174 | scell[0].from_part, partb, cells_info); 175 | 176 | /* lock cell */ 177 | cells_info[scell[0].mov_cell_no].locked = True; 178 | if (move_possible == True) { 179 | move_cell(mcells, msize, scell); 180 | msize++; 181 | update_gains(noparts, max_gain, scell, 182 | cells, nets, cnets, ncells, nets_info, 183 | partb, cells_info, pop[0].chrom); 184 | } /* if */ 185 | nlocked++; 186 | 187 | } while (nlocked < nocells); 188 | 189 | int max_mcells_inx; 190 | gain_sum = find_move_set(mcells, msize, &max_mcells_inx); 191 | 192 | #ifdef DEBUG 193 | printf("gain_sum=%d max_mcells_inx=%d msize = %d\n", 194 | gain_sum, max_mcells_inx, msize); 195 | #endif 196 | 197 | if (gain_sum > 0) { 198 | int cut_gain = move_cells(False, nocells, msize, mcells, max_mcells_inx, 199 | cutsize, &glob_inx, &pop[0], cells, nets, cnets); 200 | cutsize -= cut_gain; 201 | } /* if */ 202 | no_iter++; 203 | 204 | #ifdef DEBUG 205 | printf("pass_no = %d Final cutsize = %d Check cutsize = %d\n", 206 | no_iter, cutsize, find_cut_size(nonets, noparts, totnetsize, nets, &pop[0])); 207 | #endif 208 | 209 | } while ((gain_sum > 0) && (cutsize > 0) && (no_iter < NO_ITERATIONS)); 210 | 211 | printf("pass_no = %d Final cutsize = %d Check cutsize = %d\n", no_iter, 212 | cutsize, find_cut_size(nonets, noparts, totnetsize, nets, &pop[0])); 213 | 214 | free_nodes(noparts, bucketsize, partb); 215 | 216 | #ifdef DEBUG 217 | printf("Final : Part_no min_size curr_size max_size\n"); 218 | for (int i = 0; i < noparts; i++) { 219 | printf("FF %d %d %d %d\n", i, pop[0].parts[i].pmin_size, 220 | pop[0].parts[i].pcurr_size, pop[0].parts[i].pmax_size); 221 | } 222 | #endif 223 | 224 | /* free memory for all data structures */ 225 | free(cells); 226 | for (int i = 0; i < nocells; i++) { 227 | free(cells_info[i].mgain); 228 | free(cells_info[i].partb_ptr); 229 | free(cells_info[i].partb_gain_inx); 230 | } 231 | free(cells_info); 232 | 233 | for (int i = 0; i < nonets; i++) { 234 | free(nets[i].npartdeg); 235 | free(nets_info[i].npartdeg); 236 | } 237 | free(nets); 238 | free(nets_info); 239 | 240 | free(cnets); 241 | free(ncells); 242 | 243 | for (int i = 0; i < noparts; i++) { 244 | for (int j = 0; j < noparts - 1; ++j) { 245 | free(partb[i][j].bnode_ptr); 246 | } 247 | } 248 | 249 | for (int i = 0; i < MAX_POP; i++) { 250 | free(pop[i].chrom); 251 | free(pop[i].parts); 252 | } 253 | 254 | free(mcells); 255 | 256 | return (0); 257 | } /* main-fms */ 258 | 259 | /* EOF */ 260 | -------------------------------------------------------------------------------- /src/fms/ad_lib_fms.c: -------------------------------------------------------------------------------- 1 | 2 | /* COPYRIGHT C 1991- Ali Dasdan */ 3 | 4 | #include "ad_defs.h" 5 | #include "ad_bucketio.h" 6 | #include "ad_lib.h" 7 | #include "ad_lib_fms.h" 8 | 9 | /* map a given mov_gain into index to a bucket array */ 10 | int map_gain(int mov_gain, int max_gain) 11 | { 12 | return (mov_gain + max_gain); 13 | } /* map_gain */ 14 | 15 | /* fill all bucket arrays */ 16 | void create_buckets(int nocells, 17 | int noparts, 18 | int max_gain, 19 | allele chrom[], 20 | partb_t partb[][noparts - 1], 21 | cells_info_t cells_info[]) 22 | { 23 | /* read cell gains from cells_info and insert them into buckets */ 24 | for (int cell_no = 0; cell_no < nocells; cell_no++) { 25 | 26 | int part_no = chrom[cell_no]; 27 | 28 | /* for each possible move direction */ 29 | for (int mov_part_no = 0; mov_part_no < noparts; mov_part_no++) { 30 | if (mov_part_no != part_no) { 31 | 32 | int mov_gain = calculate_gain(cell_no, part_no, mov_part_no, cells_info); 33 | 34 | /* find mapped_after calculating gain & max */ 35 | int mapped_part_no = map_part_no(mov_part_no, part_no); 36 | int gain_inx = map_gain(mov_gain, max_gain); 37 | 38 | /* create a partb node */ 39 | create_partb_node(noparts, cell_no, part_no, mapped_part_no, 40 | gain_inx, partb, cells_info); 41 | 42 | } /* if mapped_part_no not equal part_no */ 43 | } /* for mapped_part_no */ 44 | } /* for part_no */ 45 | } /* create_buckets */ 46 | 47 | /* select a cell to move */ 48 | int select_cell(int noparts, 49 | selected_cell_t scell[], 50 | parts_info_t parts_info[], 51 | cells_t cells[], 52 | partb_t partb[][noparts - 1], 53 | cells_info_t cells_info[]) 54 | { 55 | /* 56 | add to the 1st "if" && (parts_info[from].pmax_cells > 0) 57 | */ 58 | int move_possible = True; 59 | int max_mov_value = -1; 60 | for (int from = 0; from < noparts; from++) { 61 | int fpcurr_size = parts_info[from].pcurr_size; 62 | int fpmin_size = parts_info[from].pmin_size; 63 | if (fpcurr_size > fpmin_size) { 64 | for (int to = 0; to < noparts; to++) { 65 | int tpmax_size = parts_info[to].pmax_size; 66 | int tpcurr_size = parts_info[to].pcurr_size; 67 | if ((from != to) && (tpcurr_size < tpmax_size)) { 68 | int dest_part = map_part_no(to, from); 69 | int max_inx = partb[from][dest_part].max_inx; 70 | if (max_inx > 0) { 71 | int cell_no = partb[from][dest_part].bnode_ptr[max_inx]->cell_no; 72 | if ((max_mov_value < max_inx) && 73 | (fpcurr_size >= (fpmin_size + cells[cell_no].cweight)) && 74 | ((tpcurr_size + cells[cell_no].cweight) <= tpmax_size)) { 75 | max_mov_value = max_inx; 76 | scell[0].mov_cell_no = cell_no; 77 | scell[0].from_part = from; 78 | scell[0].to_part = to; 79 | } /* if many conditions */ 80 | } /* if */ 81 | } /* if */ 82 | } /* for to */ 83 | } /* if curr > min */ 84 | } /* for from */ 85 | 86 | if (max_mov_value != -1) { 87 | 88 | scell[0].mov_gain = calculate_gain(scell[0].mov_cell_no, 89 | scell[0].from_part, 90 | scell[0].to_part, 91 | cells_info); 92 | parts_info[scell[0].from_part].pmax_cells--; 93 | parts_info[scell[0].to_part].pmax_cells++; 94 | parts_info[scell[0].from_part].pcurr_size -= 95 | cells[scell[0].mov_cell_no].cweight; 96 | parts_info[scell[0].to_part].pcurr_size += 97 | cells[scell[0].mov_cell_no].cweight; 98 | 99 | } else { 100 | 101 | move_possible = False; 102 | max_mov_value = -1; 103 | for (int from = 0; from < noparts; from++) { 104 | // int fpcurr_size = parts_info[from].pcurr_size; 105 | // int fpmin_size = parts_info[from].pmin_size; 106 | for (int to = 0; to < noparts; to++) { 107 | // int tpmax_size = parts_info[to].pmax_size; 108 | // int tpcurr_size = parts_info[to].pcurr_size; 109 | if (from != to) { 110 | int dest_part = map_part_no(to, from); 111 | int max_inx = partb[from][dest_part].max_inx; 112 | if (max_inx > 0) { 113 | int cell_no = partb[from][dest_part].bnode_ptr[max_inx]->cell_no; 114 | if (max_mov_value < max_inx) { 115 | max_mov_value = max_inx; 116 | scell[0].mov_cell_no = cell_no; 117 | scell[0].from_part = from; 118 | } /* if many conditions */ 119 | } /* if */ 120 | } /* if */ 121 | } /* for to */ 122 | } /* for from */ 123 | 124 | } /* else */ 125 | 126 | return move_possible; 127 | } /* select_cell */ 128 | 129 | /* move selected cell, and save the move in a file */ 130 | void move_cell(mcells_t mcells[], 131 | int msize, 132 | selected_cell_t scell[]) 133 | { 134 | mcells[msize].cell_no = scell[0].mov_cell_no; 135 | mcells[msize].from = scell[0].from_part; 136 | mcells[msize].to = scell[0].to_part; 137 | mcells[msize].mgain = scell[0].mov_gain; 138 | } /* move_cell */ 139 | 140 | /* update gains after a move */ 141 | void update_gains(int noparts, 142 | int max_gain, 143 | selected_cell_t scell[], 144 | cells_t cells[], 145 | nets_t nets[], 146 | corn_t cnets[], 147 | corn_t ncells[], 148 | nets_info_t nets_info[], 149 | partb_t partb[][noparts - 1], 150 | cells_info_t cells_info[], 151 | allele tchrom[]) 152 | { 153 | int net_ptr = cells[scell[0].mov_cell_no].netlist; 154 | int mov_cell_no = scell[0].mov_cell_no; 155 | int from_part = scell[0].from_part; 156 | int to_part = scell[0].to_part; 157 | 158 | /* for each neighor net */ 159 | for (int i = 0; i < cells[mov_cell_no].cno_nets; i++) { 160 | 161 | int net_no = cnets[net_ptr + i].corn_no; 162 | int net_weight = nets[net_no].nweight; 163 | int cell_ptr = nets[net_no].celllist; 164 | 165 | /* do operations before the move */ 166 | if (nets_info[net_no].npartdeg[from_part] == nets[net_no].nno_cells) { 167 | 168 | update1(False, noparts, max_gain, from_part, mov_cell_no, 169 | cell_ptr, net_no, net_weight, 170 | nets, ncells, partb, cells_info, tchrom); 171 | 172 | } else if (nets_info[net_no].npartdeg[from_part] == (nets[net_no].nno_cells - 1)) { 173 | 174 | update2(False, noparts, max_gain, from_part, mov_cell_no, 175 | cell_ptr, net_no, net_weight, 176 | nets, ncells, partb, cells_info, tchrom); 177 | 178 | } 179 | 180 | /* update net info */ 181 | nets_info[net_no].npartdeg[from_part]--; 182 | nets_info[net_no].npartdeg[to_part]++; 183 | 184 | /* do operations after the move */ 185 | if (nets_info[net_no].npartdeg[to_part] == nets[net_no].nno_cells) { 186 | 187 | update1(True, noparts, max_gain, to_part, mov_cell_no, 188 | cell_ptr, net_no, net_weight, 189 | nets, ncells, partb, cells_info, tchrom); 190 | 191 | } else if (nets_info[net_no].npartdeg[to_part] == (nets[net_no].nno_cells - 1)) { 192 | 193 | update2(True, noparts, max_gain, to_part, mov_cell_no, 194 | cell_ptr, net_no, net_weight, 195 | nets, ncells, partb, cells_info, tchrom); 196 | 197 | } /* else */ 198 | 199 | } /* for i */ 200 | } /* update_gains */ 201 | 202 | /* update gain of a cell */ 203 | void update1(int flag, 204 | int noparts, 205 | int max_gain, 206 | int dest_part, 207 | int mov_cell_no, 208 | int cell_ptr, 209 | int net_no, 210 | int net_weight, 211 | nets_t nets[], 212 | corn_t ncells[], 213 | partb_t partb[][noparts - 1], 214 | cells_info_t cells_info[], 215 | allele tchrom[]) 216 | { 217 | int i = 0; 218 | while (i < nets[net_no].nno_cells) { 219 | 220 | int other_cell = ncells[cell_ptr + i].corn_no; 221 | int other_part_no = tchrom[other_cell]; 222 | if ((other_cell != mov_cell_no) && (cells_info[other_cell].locked == False)) { 223 | 224 | if (flag == False) { 225 | cells_info[other_cell].mgain[dest_part] -= net_weight; 226 | } else { 227 | cells_info[other_cell].mgain[dest_part] += net_weight; 228 | } 229 | 230 | /* since internal gains change, update all gains */ 231 | delete_partb_nodes_of_cell(noparts, other_cell, other_part_no, 232 | partb, cells_info); 233 | create_partb_nodes_of_cell(noparts, max_gain, 234 | other_cell, other_part_no, 235 | partb, cells_info); 236 | } /* if */ 237 | 238 | i++; 239 | } /* while */ 240 | } /* update1 */ 241 | 242 | /* update gain of a cell */ 243 | void update2(int flag, 244 | int noparts, 245 | int max_gain, 246 | int dest_part, 247 | int mov_cell_no, 248 | int cell_ptr, 249 | int net_no, 250 | int net_weight, 251 | nets_t nets[], 252 | corn_t ncells[], 253 | partb_t partb[][noparts - 1], 254 | cells_info_t cells_info[], 255 | allele tchrom[]) 256 | { 257 | int other_cell, other_part_no; 258 | 259 | int found = False; 260 | int i = 0; 261 | while ((i < nets[net_no].nno_cells) && (!found)) { 262 | 263 | other_cell = ncells[cell_ptr + i].corn_no; 264 | other_part_no = tchrom[other_cell]; 265 | if ((other_cell != mov_cell_no) && 266 | (cells_info[other_cell].locked == False) && 267 | (other_part_no != dest_part)) { 268 | found = True; 269 | } /* if */ 270 | 271 | i++; 272 | } /* while */ 273 | 274 | if (!found) return; 275 | 276 | if (flag == False) { 277 | cells_info[other_cell].mgain[dest_part] -= net_weight; 278 | } else { 279 | cells_info[other_cell].mgain[dest_part] += net_weight; 280 | } 281 | 282 | int mov_gain = calculate_gain(other_cell, other_part_no, 283 | dest_part, cells_info); 284 | int gain_inx = map_gain(mov_gain, max_gain); 285 | int mapped_part_no = map_part_no(dest_part, other_part_no); 286 | bnode_ptr_t tnode_ptr = delete_partb_node(False, mapped_part_no, 287 | &partb[other_part_no][mapped_part_no], 288 | &cells_info[other_cell]); 289 | insert_partb_node(tnode_ptr, mapped_part_no, gain_inx, 290 | &partb[other_part_no][mapped_part_no], 291 | &cells_info[other_cell]); 292 | } /* update2 */ 293 | 294 | void create_partb_nodes_of_cell(int noparts, 295 | int max_gain, 296 | int cell_no, 297 | int part_no, 298 | partb_t partb[][noparts - 1], 299 | cells_info_t cells_info[]) 300 | { 301 | if (cell_no == -1) { 302 | return; 303 | } 304 | 305 | /* for each possible move direction */ 306 | for (int mov_part_no = 0; mov_part_no < noparts; mov_part_no++) { 307 | 308 | if (mov_part_no != part_no) { /* part-no is home_part of cell_no */ 309 | 310 | int mov_gain = calculate_gain(cell_no, part_no, mov_part_no, cells_info); 311 | 312 | /* find mapped_after calculating gain & max */ 313 | int mapped_part_no = map_part_no(mov_part_no, part_no); 314 | int gain_inx = map_gain(mov_gain, max_gain); 315 | 316 | /* create a partb node */ 317 | create_partb_node(noparts, cell_no, part_no, mapped_part_no, 318 | gain_inx, partb, cells_info); 319 | 320 | } /* if mapped_part_no not equal part_no */ 321 | } /* for mapped_part_no */ 322 | } /* create_partb_nodes_of_cell */ 323 | 324 | /* EOF */ 325 | -------------------------------------------------------------------------------- /src/fms/ad_lib_fms.h: -------------------------------------------------------------------------------- 1 | #ifndef AD_LIB_FMS_INCLUDED 2 | #define AD_LIB_FMS_INCLUDED 3 | 4 | /* COPYRIGHT C 1991- Ali Dasdan */ 5 | 6 | /* map a given mov_gain into index to a bucket array */ 7 | int map_gain(int mov_gain, int max_gain); 8 | 9 | /* fill all bucket arrays */ 10 | void create_buckets(int nocells, 11 | int noparts, 12 | int max_gain, 13 | allele chrom[], 14 | partb_t partb[][noparts - 1], 15 | cells_info_t cells_info[]); 16 | 17 | /* select a cell to move */ 18 | int select_cell(int noparts, 19 | selected_cell_t scell[], 20 | parts_info_t parts_info[], 21 | cells_t cells[], 22 | partb_t partb[][noparts - 1], 23 | cells_info_t cells_info[]); 24 | 25 | /* move selected cell, and save the move in a file */ 26 | void move_cell(mcells_t mcells[], 27 | int msize, 28 | selected_cell_t scell[]); 29 | 30 | /* update gains after a move */ 31 | void update_gains(int noparts, 32 | int max_gain, 33 | selected_cell_t scell[], 34 | cells_t cells[], 35 | nets_t nets[], 36 | corn_t cnets[], 37 | corn_t ncells[], 38 | nets_info_t nets_info[], 39 | partb_t partb[][noparts - 1], 40 | cells_info_t cells_info[], 41 | allele tchrom[]); 42 | 43 | /* update gain of a cell */ 44 | void update1(int flag, 45 | int noparts, 46 | int max_gain, 47 | int dest_part, 48 | int mov_cell_no, 49 | int cell_ptr, 50 | int net_no, 51 | int net_weight, 52 | nets_t nets[], 53 | corn_t ncells[], 54 | partb_t partb[][noparts - 1], 55 | cells_info_t cells_info[], 56 | allele tchrom[]); 57 | 58 | /* update gain of a cell */ 59 | void update2(int flag, 60 | int noparts, 61 | int max_gain, 62 | int dest_part, 63 | int mov_cell_no, 64 | int cell_ptr, 65 | int net_no, 66 | int net_weight, 67 | nets_t nets[], 68 | corn_t ncells[], 69 | partb_t partb[][noparts - 1], 70 | cells_info_t cells_info[], 71 | allele tchrom[]); 72 | 73 | void create_partb_nodes_of_cell(int noparts, 74 | int max_gain, 75 | int cell_no, 76 | int part_no, 77 | partb_t partb[][noparts - 1], 78 | cells_info_t cells_info[]); 79 | 80 | #endif 81 | 82 | -------------------------------------------------------------------------------- /src/fms/utest.awk: -------------------------------------------------------------------------------- 1 | # Awk program called in utest.sh 2 | { 3 | # c = current cutsize 4 | # l = target cutsize 5 | c = $7 6 | s = "program=" p ": cutsize=" c " target=" t 7 | if (c == t) { 8 | print "Passed:", s; 9 | } else { 10 | print "Failed:", s; 11 | } 12 | } 13 | 14 | # EOF 15 | -------------------------------------------------------------------------------- /src/fms/utest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # testing each executable using input/hp1 4 | 5 | ./ad_fms.x ../../input/hp1 2 123456 | grep Final | awk -v p="ad_fms p1 2" -v t=1 -f utest.awk 6 | 7 | # testing each executable using input/hp9 8 | 9 | ./ad_fms.x ../../input/hp9 2 123456 | grep Final | awk -v p="ad_fms p9 2" -v t=85 -f utest.awk 10 | ./ad_fms.x ../../input/hp9 3 123456 | grep Final | awk -v p="ad_fms p9 3" -v t=201 -f utest.awk 11 | 12 | # EOF 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/pfm/Makefile: -------------------------------------------------------------------------------- 1 | CC0 = gcc 2 | CC = $(CC0) 3 | LD = $(CC0) 4 | FLAGS1 = -O3 5 | FLAGS2 = -lm 6 | FLAGS3 = -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow 7 | DIR_H = ../share 8 | FLAGS = $(FLAGS1) $(FLAGS3) -I$(DIR_H) 9 | 10 | DEPS_SHARE = $(DIR_H)/ad_bucketio.h \ 11 | $(DIR_H)/ad_fileio.h \ 12 | $(DIR_H)/ad_lib.h \ 13 | $(DIR_H)/ad_partition.h \ 14 | $(DIR_H)/ad_print.h \ 15 | $(DIR_H)/ad_random.h \ 16 | $(DIR_H)/ad_readinput.h 17 | 18 | DEPS_PFM = ad_lib_pfm.h $(DIR_H)/ad_defs.h $(DEPS_SHARE) 19 | OBJS = $(patsubst %.h,%.o,$(DEPS_SHARE)) 20 | OBJS_PFM = $(OBJS) ad_lib_pfm.o 21 | 22 | all: ad_pfm 23 | 24 | ad_lib_pfm.o: ad_lib_pfm.c ad_lib_pfm.h $(DIR_H)/ad_lib.h $(DIR_H)/ad_bucketio.h $(DIR_H)/ad_defs.h 25 | $(CC) $(FLAGS) -c -o $@ $< $(FLAGS2) 26 | 27 | ad_pfm: ad_pfm.c $(DEPS_PFM) $(OBJS_PFM) 28 | $(CC) $(FLAGS) -o $@.x $< $(OBJS_PFM) $(FLAGS2) 29 | 30 | # Testing: 31 | test: 32 | ./utest.sh 33 | 34 | # Cleaning: 35 | clean c cl cle clea: 36 | rm -f *.o *~ core *.x 37 | cleano: 38 | rm -f *.o *~ core 39 | 40 | # End of file 41 | -------------------------------------------------------------------------------- /src/pfm/ad_lib_pfm.c: -------------------------------------------------------------------------------- 1 | 2 | /* COPYRIGHT C 1991- Ali Dasdan */ 3 | 4 | #include 5 | #include 6 | #include 7 | #include "ad_defs.h" 8 | #include "ad_bucketio.h" 9 | #include "ad_lib.h" 10 | #include "ad_lib_pfm.h" 11 | 12 | /* 13 | ALSO TRY THESE: 14 | mov_value = ((float) (mov_gain + max_gain)) / 15 | ((float) mcount * 2.0 * max_gain); 16 | 17 | mov_value = ((float) (mov_gain + max_gain)) / 18 | ((float) log((double) (mcount + 3.0)) * 2.0 * max_gain); 19 | */ 20 | 21 | /* map a given mov_gain into index to a bucket array */ 22 | int map_gain(int bucketsize, 23 | int mov_gain, 24 | int mov_count, 25 | int max_gain, 26 | eval_t eval[]) 27 | { 28 | int mcount = mov_count; 29 | if (mcount == 0) { 30 | mcount = 1; 31 | } 32 | float mov_value = ((float) (bucketsize) / 33 | (1.0 + (float) sqrt ((double) (mcount)) * 34 | (float) eval[max_gain - mov_gain].val)); 35 | return ((int) mov_value); 36 | } /* map_gain */ 37 | 38 | /* fill all bucket arrays */ 39 | void create_buckets(int bucketsize, 40 | int nocells, 41 | int noparts, 42 | int max_gain, 43 | eval_t eval[], 44 | allele chrom[], 45 | partb_t partb[][noparts - 1], 46 | cells_info_t cells_info[]) 47 | { 48 | /* read cell gains from cells_info and insert them into buckets */ 49 | for (int cell_no = 0; cell_no < nocells; cell_no++) { 50 | 51 | int part_no = chrom[cell_no]; 52 | 53 | /* for each possible move direction */ 54 | for (int mov_part_no = 0; mov_part_no < noparts; mov_part_no++) { 55 | if (mov_part_no != part_no) { 56 | 57 | int mov_gain = calculate_gain(cell_no, part_no, mov_part_no, cells_info); 58 | 59 | /* find mapped_after calculating gain & max */ 60 | int mapped_part_no = map_part_no(mov_part_no, part_no); 61 | int gain_inx = map_gain(bucketsize, mov_gain, cells_info[cell_no].mcount, 62 | max_gain, eval); 63 | 64 | /* create a partb node */ 65 | create_partb_node(noparts, cell_no, part_no, mapped_part_no, 66 | gain_inx, partb, cells_info); 67 | 68 | } /* if mapped_part_no not equal part_no */ 69 | } /* for mapped_part_no */ 70 | } /* for part_no */ 71 | } /* create_buckets */ 72 | 73 | /* select a cell to move */ 74 | void select_cell(int noparts, 75 | selected_cell_t scell[], 76 | parts_info_t parts_info[], 77 | cells_t cells[], 78 | partb_t partb[][noparts - 1], 79 | cells_info_t cells_info[]) 80 | { 81 | int max_mov_value = -1; 82 | scell[0].mov_cell_no = -1; 83 | for (int from = 0; from < noparts; from++) { 84 | int fpcurr_size = parts_info[from].pcurr_size; 85 | int fpmin_size = parts_info[from].pmin_size; 86 | if (fpcurr_size > fpmin_size) { 87 | for (int to = 0; to < noparts; to++) { 88 | int tpmax_size = parts_info[to].pmax_size; 89 | int tpcurr_size = parts_info[to].pcurr_size; 90 | if ((from != to) && (tpcurr_size < tpmax_size)) { 91 | int dest_part = map_part_no(to, from); 92 | int max_inx = partb[from][dest_part].max_inx; 93 | if (max_inx < 0) { 94 | printf("Error: max_inx cannot be negative.\n"); 95 | exit(1); 96 | } /* if */ 97 | int cell_no = partb[from][dest_part].bnode_ptr[max_inx]->cell_no; 98 | if ((max_mov_value < max_inx) && 99 | (fpcurr_size >= (fpmin_size + cells[cell_no].cweight)) && 100 | ((tpcurr_size + cells[cell_no].cweight) <= tpmax_size)) { 101 | max_mov_value = max_inx; 102 | scell[0].mov_cell_no = cell_no; 103 | scell[0].from_part = from; 104 | scell[0].to_part = to; 105 | } /* if many conditions */ 106 | } /* if */ 107 | } /* for to */ 108 | } /* if curr > min */ 109 | } /* for from */ 110 | 111 | if (scell[0].mov_cell_no == -1) { 112 | printf("Error: Cannot find a node to move.\n"); 113 | exit(1); 114 | } /* if */ 115 | 116 | scell[0].mov_gain = calculate_gain(scell[0].mov_cell_no, 117 | scell[0].from_part, 118 | scell[0].to_part, 119 | cells_info); 120 | parts_info[scell[0].from_part].pmax_cells--; 121 | parts_info[scell[0].to_part].pmax_cells++; 122 | parts_info[scell[0].from_part].pcurr_size -= 123 | cells[scell[0].mov_cell_no].cweight; 124 | parts_info[scell[0].to_part].pcurr_size += 125 | cells[scell[0].mov_cell_no].cweight; 126 | } /* select_cell */ 127 | 128 | /* move selected cell, and save the move in a file */ 129 | void move_cell(mcells_t mcells[], 130 | int msize, 131 | selected_cell_t scell[], 132 | allele tchrom[], 133 | cells_info_t cells_info[]) 134 | { 135 | tchrom[scell[0].mov_cell_no] = scell[0].to_part; 136 | cells_info[scell[0].mov_cell_no].mcount++; 137 | mcells[msize].cell_no = scell[0].mov_cell_no; 138 | mcells[msize].from = scell[0].from_part; 139 | mcells[msize].to = scell[0].to_part; 140 | mcells[msize].mgain = scell[0].mov_gain; 141 | } /* move_cell */ 142 | 143 | /* update gains after a move */ 144 | void update_gains(int bucketsize, 145 | int noparts, 146 | int max_gain, 147 | eval_t eval[], 148 | selected_cell_t scell[], 149 | cells_t cells[], 150 | nets_t nets[], 151 | corn_t cnets[], 152 | corn_t ncells[], 153 | nets_info_t nets_info[], 154 | partb_t partb[][noparts - 1], 155 | cells_info_t cells_info[], 156 | allele tchrom[]) 157 | { 158 | int net_ptr = cells[scell[0].mov_cell_no].netlist; 159 | int mov_cell_no = scell[0].mov_cell_no; 160 | int from_part = scell[0].from_part; 161 | int to_part = scell[0].to_part; 162 | 163 | /* for each neighor net */ 164 | for (int i = 0; i < cells[mov_cell_no].cno_nets; i++) { 165 | 166 | int net_no = cnets[net_ptr + i].corn_no; 167 | int net_weight = nets[net_no].nweight; 168 | int cell_ptr = nets[net_no].celllist; 169 | 170 | /* do operations before the move */ 171 | if (nets_info[net_no].npartdeg[from_part] == nets[net_no].nno_cells) { 172 | 173 | update1(False, bucketsize, noparts, max_gain, from_part, mov_cell_no, 174 | cell_ptr, net_no, net_weight, 175 | eval, nets, ncells, partb, cells_info, tchrom); 176 | 177 | } else if (nets_info[net_no].npartdeg[from_part] == (nets[net_no].nno_cells - 1)) { 178 | 179 | update2(False, bucketsize, noparts, max_gain, from_part, mov_cell_no, 180 | cell_ptr, net_no, net_weight, 181 | eval, nets, ncells, partb, cells_info, tchrom); 182 | 183 | } /* else */ 184 | 185 | /* update net info */ 186 | nets_info[net_no].npartdeg[from_part]--; 187 | nets_info[net_no].npartdeg[to_part]++; 188 | 189 | /* do operations after the move */ 190 | if (nets_info[net_no].npartdeg[to_part] == nets[net_no].nno_cells) { 191 | 192 | update1(True, bucketsize, noparts, max_gain, to_part, mov_cell_no, 193 | cell_ptr, net_no, net_weight, 194 | eval, nets, ncells, partb, cells_info, tchrom); 195 | 196 | } else if (nets_info[net_no].npartdeg[to_part] == (nets[net_no].nno_cells - 1)) { 197 | 198 | update2(True, bucketsize, noparts, max_gain, to_part, mov_cell_no, 199 | cell_ptr, net_no, net_weight, 200 | eval, nets, ncells, partb, cells_info, tchrom); 201 | 202 | } /* else */ 203 | 204 | } /* for i */ 205 | } /* update_gains */ 206 | 207 | /* update gain of a cell */ 208 | void update1(int flag, 209 | int bucketsize, 210 | int noparts, 211 | int max_gain, 212 | int dest_part, 213 | int mov_cell_no, 214 | int cell_ptr, 215 | int net_no, 216 | int net_weight, 217 | eval_t eval[], 218 | nets_t nets[], 219 | corn_t ncells[], 220 | partb_t partb[][noparts - 1], 221 | cells_info_t cells_info[], 222 | allele tchrom[]) 223 | { 224 | int i = 0; 225 | while (i < nets[net_no].nno_cells) { 226 | 227 | int other_cell = ncells[cell_ptr + i].corn_no; 228 | int other_part_no = tchrom[other_cell]; 229 | if (other_cell != mov_cell_no) { 230 | 231 | if (flag == False) { 232 | cells_info[other_cell].mgain[dest_part] -= net_weight; 233 | } else { 234 | cells_info[other_cell].mgain[dest_part] += net_weight; 235 | } 236 | 237 | /* since internal gains change, update all gains */ 238 | delete_partb_nodes_of_cell(noparts, other_cell, other_part_no, 239 | partb, cells_info); 240 | create_partb_nodes_of_cell(bucketsize, noparts, max_gain, 241 | other_cell, other_part_no, 242 | eval, partb, cells_info); 243 | } /* if */ 244 | 245 | i++; 246 | } /* while */ 247 | } /* update1 */ 248 | 249 | /* update gain of a cell */ 250 | void update2(int flag, 251 | int bucketsize, 252 | int noparts, 253 | int max_gain, 254 | int dest_part, 255 | int mov_cell_no, 256 | int cell_ptr, 257 | int net_no, 258 | int net_weight, 259 | eval_t eval[], 260 | nets_t nets[], 261 | corn_t ncells[], 262 | partb_t partb[][noparts - 1], 263 | cells_info_t cells_info[], 264 | allele tchrom[]) 265 | { 266 | int other_cell, other_part_no; 267 | 268 | int found = False; 269 | int i = 0; 270 | while ((i < nets[net_no].nno_cells) && (!found)) { 271 | 272 | other_cell = ncells[cell_ptr + i].corn_no; 273 | other_part_no = tchrom[other_cell]; 274 | if ((other_cell != mov_cell_no) && 275 | (other_part_no != dest_part)) { 276 | found = True; 277 | } /* if */ 278 | 279 | i++; 280 | } /* while */ 281 | 282 | if (!found) return; 283 | 284 | if (flag == False) { 285 | cells_info[other_cell].mgain[dest_part] -= net_weight; 286 | } else { 287 | cells_info[other_cell].mgain[dest_part] += net_weight; 288 | } 289 | 290 | int mov_gain = calculate_gain(other_cell, other_part_no, 291 | dest_part, cells_info); 292 | int gain_inx = map_gain(bucketsize, mov_gain, cells_info[other_cell].mcount, 293 | max_gain, eval); 294 | int mapped_part_no = map_part_no(dest_part, other_part_no); 295 | bnode_ptr_t tnode_ptr = delete_partb_node(False, mapped_part_no, 296 | &partb[other_part_no][mapped_part_no], 297 | &cells_info[other_cell]); 298 | insert_partb_node(tnode_ptr, mapped_part_no, gain_inx, 299 | &partb[other_part_no][mapped_part_no], 300 | &cells_info[other_cell]); 301 | } /* update2 */ 302 | 303 | /* fill eval array */ 304 | void fill_eval(int max_gain, 305 | float K, 306 | eval_t eval[]) 307 | { 308 | for (int i = 0; i <= (2 * max_gain); i++) 309 | eval[i].val = (float) exp((double) (-K * (max_gain - i))); 310 | } /* fill_eval */ 311 | 312 | void create_partb_nodes_of_cell(int bucketsize, 313 | int noparts, 314 | int max_gain, 315 | int cell_no, 316 | int part_no, 317 | eval_t eval[], 318 | partb_t partb[][noparts - 1], 319 | cells_info_t cells_info[]) 320 | { 321 | if (cell_no == -1) { 322 | return; 323 | } 324 | 325 | /* for each possible move direction */ 326 | for (int mov_part_no = 0; mov_part_no < noparts; mov_part_no++) { 327 | 328 | if (mov_part_no != part_no) { /* part_no is home_part of cell_no */ 329 | 330 | int mov_gain = calculate_gain(cell_no, part_no, mov_part_no, cells_info); 331 | 332 | /* find mapped_after calculating gain & max */ 333 | int mapped_part_no = map_part_no(mov_part_no, part_no); 334 | int gain_inx = map_gain(bucketsize, mov_gain, cells_info[cell_no].mcount, 335 | max_gain, eval); 336 | 337 | /* create a partb node */ 338 | create_partb_node(noparts, cell_no, part_no, mapped_part_no, 339 | gain_inx, partb, cells_info); 340 | 341 | } /* if mapped_part_no not equal part_no */ 342 | 343 | } /* for mapped_part_no */ 344 | } /* create_partb_nodes_of_cell */ 345 | 346 | /* calculate K and scale factor */ 347 | void calculate_scale(int nocells, 348 | int noparts, 349 | int max_gain, 350 | float *K) 351 | { 352 | double ratio = log((double) ((1.0 - EPSILON) / EPSILON)); 353 | *K = (1.0 / max_gain) * (float) ratio; 354 | double scale = (double) pow(ratio, (double) 1.0 / max_gain); 355 | scale = (scale + 1.0 + ratio * noparts * sqrt((double) nocells)) / (scale - 1.0); 356 | scale = (double) pow(ratio, (double) 1.0 / max_gain); 357 | scale = (scale + 1.0 + ratio * noparts) / (scale - 1.0); 358 | } /* calculate_scale */ 359 | 360 | /* EOF */ 361 | -------------------------------------------------------------------------------- /src/pfm/ad_lib_pfm.h: -------------------------------------------------------------------------------- 1 | #ifndef AD_LIB_PFM_INCLUDED 2 | #define AD_LIB_PFM_INCLUDED 3 | 4 | /* COPYRIGHT C 1991- Ali Dasdan */ 5 | 6 | /* map a given mov_gain into index to a bucket array */ 7 | int map_gain(int bucketsize, 8 | int mov_gain, 9 | int mov_count, 10 | int max_gain, 11 | eval_t eval[]); 12 | 13 | /* fill all bucket arrays */ 14 | void create_buckets(int bucketsize, 15 | int nocells, 16 | int noparts, 17 | int max_gain, 18 | eval_t eval[], 19 | allele chrom[], 20 | partb_t partb[][noparts - 1], 21 | cells_info_t cells_info[]); 22 | 23 | /* select a cell to move */ 24 | void select_cell(int noparts, 25 | selected_cell_t scell[], 26 | parts_info_t parts_info[], 27 | cells_t cells[], 28 | partb_t partb[][noparts - 1], 29 | cells_info_t cells_info[]); 30 | 31 | /* move selected cell, and save the move in a file */ 32 | void move_cell(mcells_t mcells[], 33 | int msize, 34 | selected_cell_t scell[], 35 | allele tchrom[], 36 | cells_info_t cells_info[]); 37 | 38 | /* update gains after a move */ 39 | void update_gains(int bucketsize, 40 | int noparts, 41 | int max_gain, 42 | eval_t eval[], 43 | selected_cell_t scell[], 44 | cells_t cells[], 45 | nets_t nets[], 46 | corn_t cnets[], 47 | corn_t ncells[], 48 | nets_info_t nets_info[], 49 | partb_t partb[][noparts - 1], 50 | cells_info_t cells_info[], 51 | allele tchrom[]); 52 | 53 | /* update gain of a cell */ 54 | void update1(int flag, 55 | int bucketsize, 56 | int noparts, 57 | int max_gain, 58 | int dest_part, 59 | int mov_cell_no, 60 | int cell_ptr, 61 | int net_no, 62 | int net_weight, 63 | eval_t eval[], 64 | nets_t nets[], 65 | corn_t ncells[], 66 | partb_t partb[][noparts - 1], 67 | cells_info_t cells_info[], 68 | allele tchrom[]); 69 | 70 | /* update gain of a cell */ 71 | void update2(int flag, 72 | int bucketsize, 73 | int noparts, 74 | int max_gain, 75 | int dest_part, 76 | int mov_cell_no, 77 | int cell_ptr, 78 | int net_no, 79 | int net_weight, 80 | eval_t eval[], 81 | nets_t nets[], 82 | corn_t ncells[], 83 | partb_t partb[][noparts - 1], 84 | cells_info_t cells_info[], 85 | allele tchrom[]); 86 | 87 | /* fill eval array */ 88 | void fill_eval(int max_gain, 89 | float K, 90 | eval_t eval[]); 91 | 92 | void create_partb_nodes_of_cell(int bucketsize, 93 | int noparts, 94 | int max_gain, 95 | int cell_no, 96 | int part_no, 97 | eval_t eval[], 98 | partb_t partb[][noparts - 1], 99 | cells_info_t cells_info[]); 100 | 101 | /* calculate K and scale factor */ 102 | void calculate_scale(int nocells, 103 | int noparts, 104 | int max_gain, 105 | float *K); 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /src/pfm/ad_pfm.c: -------------------------------------------------------------------------------- 1 | 2 | /* COPYRIGHT C 1991- Ali Dasdan */ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "ad_defs.h" 11 | #include "ad_random.h" 12 | #include "ad_fileio.h" 13 | #include "ad_readinput.h" 14 | #include "ad_partition.h" 15 | #include "ad_print.h" 16 | #include "ad_bucketio.h" 17 | #include "ad_lib.h" 18 | #include "ad_lib_pfm.h" 19 | 20 | /* PARTITIONING BY FREE MOVES */ 21 | 22 | int main(int argc, char *argv[]) 23 | { 24 | /* definitions */ 25 | int nocells; /* number of cells */ 26 | int nonets; /* number of nets */ 27 | int nopins; /* number of pins */ 28 | int noparts; /* number of partitions */ 29 | int totcellsize; /* total cell weight of the partition */ 30 | int totnetsize; /* total net weight of the partition */ 31 | int cutsize; /* cutsize of the partition */ 32 | int max_gain; /* max gain of a cell */ 33 | int max_cdeg; /* max density of a cell */ 34 | int max_ndeg; /* max density of a net */ 35 | int max_cweight; /* max cell weight */ 36 | int max_nweight; /* max net weight */ 37 | 38 | if (argc < 5) { 39 | printf("\nUsage: %s InputFileName NoParts Version BucketSizeFactor [Seed]\n", argv[0]); 40 | exit(1); 41 | } /* if */ 42 | 43 | char fname[STR_SIZE]; 44 | sprintf(fname, "%s", argv[1]); 45 | 46 | noparts = atoi(argv[2]); 47 | int version = atoi(argv[3]); 48 | 49 | int bucketsize_factor = atoi(argv[4]); 50 | 51 | long seed; 52 | if (argc > 5) { 53 | seed = (long) atoi(argv[5]); 54 | } else { 55 | seed = (long) -1; 56 | } 57 | seed = randomize((long) seed); 58 | printf("SEED = %ld fname = %s\n", seed, fname); 59 | 60 | read_hgraph_size(fname, &nocells, &nonets, &nopins); 61 | 62 | /* determine max_noiter based on pfm version */ 63 | /* pfm1: size=max_cells; 64 | pfm2: size=max_cells * max_parts; 65 | pfm3: size=max_cells * max_parts^2 */ 66 | int max_noiter = nocells; 67 | switch (version) { 68 | case 1 : break; 69 | case 2 : max_noiter *= noparts; break; 70 | case 3 : max_noiter *= noparts * noparts; break; 71 | default : break; 72 | } 73 | 74 | /* alloc memory for all data structures */ 75 | cells_t *cells = (cells_t *) calloc(nocells, sizeof(cells_t)); 76 | assert(cells != NULL); 77 | cells_info_t *cells_info = (cells_info_t *) calloc(nocells, sizeof(cells_info_t)); 78 | assert(cells_info != NULL); 79 | for (int i = 0; i < nocells; i++) { 80 | cells_info[i].mgain = (int *) calloc(noparts, sizeof(int)); 81 | assert(cells_info[i].mgain != NULL); 82 | cells_info[i].partb_ptr = (bnode_ptr_t *) calloc(noparts - 1, sizeof(bnode_ptr_t)); 83 | assert(cells_info[i].partb_ptr != NULL); 84 | cells_info[i].partb_gain_inx = (int *) calloc(noparts - 1, sizeof(int)); 85 | assert(cells_info[i].partb_gain_inx != NULL); 86 | } 87 | 88 | nets_t *nets = (nets_t *) calloc(nonets, sizeof(nets_t)); 89 | assert(nets != NULL); 90 | nets_info_t *nets_info = (nets_info_t *) calloc(nonets, sizeof(nets_info_t)); 91 | assert(nets_info != NULL); 92 | for (int i = 0; i < nonets; i++) { 93 | nets[i].npartdeg = (int *) calloc(noparts, sizeof(int)); 94 | assert(nets[i].npartdeg != NULL); 95 | nets_info[i].npartdeg = (int *) calloc(noparts, sizeof(int)); 96 | assert(nets_info[i].npartdeg != NULL); 97 | } 98 | 99 | /* cells of nets */ 100 | corn_t *cnets = (corn_t *) calloc(nopins, sizeof(corn_t)); 101 | assert(cnets != NULL); 102 | /* nets of cells */ 103 | corn_t *ncells = (corn_t *) calloc(nopins, sizeof(corn_t)); 104 | assert(ncells != NULL); 105 | 106 | /* partition buckets */ 107 | partb_t partb[noparts][noparts - 1]; 108 | parts_info_t parts_info[noparts]; 109 | 110 | /* population (w/ one individual!) */ 111 | ind_t pop[MAX_POP]; 112 | for (int i = 0; i < MAX_POP; i++) { 113 | pop[i].chrom = (allele *) calloc(nocells, sizeof(allele)); 114 | assert(pop[i].chrom != NULL); 115 | pop[i].parts = (parts_t *) calloc(noparts, sizeof(parts_t)); 116 | assert(pop[i].parts != NULL); 117 | } 118 | 119 | /* selected cell */ 120 | selected_cell_t scell[1]; 121 | selected_cell_t prev_scell[1]; 122 | 123 | /* moved cells */ 124 | mcells_t *mcells = (mcells_t *) calloc(max_noiter, sizeof(mcells_t)); 125 | assert(mcells != NULL); 126 | 127 | /* temp chrom */ 128 | allele *tchrom = (allele *) calloc(nocells, sizeof(allele)); 129 | assert(tchrom != NULL); 130 | 131 | /* in read_graph, change tnoparts -> noparts & delete the line (D) */ 132 | read_hgraph(fname, nocells, nonets, nopins, noparts, 133 | &totcellsize, &totnetsize, &max_cdeg, &max_ndeg, 134 | &max_cweight, &max_nweight, 135 | cells, nets, cnets, ncells); 136 | 137 | float off_ratio = (float) 0.1; /* alpha in initial partitioning */ 138 | create_partition(nocells, noparts, totcellsize, max_cweight, &off_ratio, 139 | cells, nets, cnets, &pop[0]); 140 | 141 | #ifdef DEBUG 142 | printf("Initial : Part_no min_size curr_size max_size\n"); 143 | for (int i = 0; i < noparts; i++) { 144 | printf("II %d %d %d %d\n", i, pop[0].parts[i].pmin_size, 145 | pop[0].parts[i].pcurr_size, pop[0].parts[i].pmax_size); 146 | } 147 | #endif 148 | 149 | /* bucketsize has impact on cutsize and runtime */ 150 | float K; 151 | max_gain = max_cdeg * max_nweight; 152 | int bucketsize = 2 * max_gain + 1; 153 | if (bucketsize_factor > 0) { 154 | bucketsize *= bucketsize_factor; 155 | } 156 | 157 | /* cache to speed up math heavy function evals */ 158 | eval_t *eval = (eval_t *) calloc(2 * max_gain + 1, sizeof(eval_t)); 159 | calculate_scale(nocells, noparts, max_gain, &K); 160 | fill_eval(max_gain, K, eval); 161 | 162 | /* alloc memory (statically if possible) */ 163 | for (int i = 0; i < noparts; i++) { 164 | for (int j = 0; j < noparts - 1; ++j) { 165 | partb[i][j].bnode_ptr = (bnode_ptr_t *) calloc(bucketsize, sizeof(bnode_ptr_t)); 166 | } 167 | } 168 | 169 | init_buckets(noparts, bucketsize, partb); 170 | cutsize = find_cut_size(nonets, noparts, totnetsize, nets, &pop[0]); 171 | 172 | #ifdef DEBUG 173 | printf("BB bucketsize=%d\n", bucketsize); 174 | printf("Totalsize = %d Initial cutsize = %d\n", totnetsize, cutsize); 175 | #endif 176 | 177 | int gain_sum; 178 | int glob_inx = 0; 179 | int pass_no = 0; 180 | do { 181 | 182 | copy_partition(noparts, parts_info, &pop[0]); 183 | 184 | copy_nets_info(nonets, noparts, nets, nets_info); 185 | 186 | for (int i = 0; i < nocells; i++) { 187 | tchrom[i] = pop[0].chrom[i]; 188 | } 189 | 190 | compute_gains(nocells, noparts, cells, nets, cnets, 191 | cells_info, pop[0].chrom); 192 | 193 | create_buckets(bucketsize, nocells, noparts, max_gain, eval, pop[0].chrom, 194 | partb, cells_info); 195 | 196 | prev_scell[0].mov_cell_no = -1; 197 | 198 | int msize = 0; /* index to mcells */ 199 | int mov_count = 0; /* count of total moves */ 200 | while (mov_count < max_noiter) { 201 | 202 | select_cell(noparts, scell, parts_info, cells, partb, cells_info); 203 | 204 | move_cell(mcells, msize, scell, tchrom, cells_info); 205 | 206 | msize++; 207 | 208 | /* insert previous cell */ 209 | create_partb_nodes_of_cell(bucketsize, noparts, max_gain, 210 | prev_scell[0].mov_cell_no, 211 | prev_scell[0].to_part, 212 | eval, partb, cells_info); 213 | 214 | update_gains(bucketsize, noparts, max_gain, eval, scell, 215 | cells, nets, cnets, ncells, nets_info, 216 | partb, cells_info, tchrom); 217 | 218 | /* currently moved cell becomes previous cell */ 219 | bcopy((void *) scell, (void *) prev_scell, sizeof(scell[0])); 220 | 221 | /* delete current cell */ 222 | delete_partb_nodes_of_cell(noparts, scell[0].mov_cell_no, 223 | scell[0].from_part, partb, cells_info); 224 | 225 | mov_count++; 226 | } /* while */ 227 | 228 | int max_mcells_inx; 229 | gain_sum = find_move_set(mcells, msize, &max_mcells_inx); 230 | 231 | #ifdef DEBUG 232 | printf("gain_sum=%d max_mcells_inx=%d msize = %d\n", 233 | gain_sum, max_mcells_inx, msize); 234 | #endif 235 | 236 | if (gain_sum > 0) { 237 | int cut_gain = move_cells(False, nocells, msize, mcells, max_mcells_inx, 238 | cutsize, &glob_inx, &pop[0], cells, nets, cnets); 239 | cutsize -= cut_gain; 240 | } /* if */ 241 | pass_no++; 242 | 243 | #ifdef DEBUG 244 | printf("pass_no = %d Final cutsize = %d Check cutsize = %d\n", 245 | pass_no, cutsize, 246 | find_cut_size (nonets, noparts, totnetsize, nets, &pop[0])); 247 | #endif 248 | 249 | free_nodes(noparts, bucketsize, partb); 250 | 251 | } while ((gain_sum > 0) && (cutsize > 0)); /* while pass_no */ 252 | /* or (pass_no < noparts) */ 253 | 254 | printf("pass_no = %d Final cutsize = %d Check cutsize = %d\n", pass_no, 255 | cutsize, find_cut_size(nonets, noparts, totnetsize, nets, &pop[0])); 256 | 257 | #ifdef DEBUG 258 | printf("Final : Part_no min_size curr_size max_size\n"); 259 | for (int i = 0; i < noparts; i++) { 260 | printf("FF %d %d %d %d\n", i, pop[0].parts[i].pmin_size, 261 | pop[0].parts[i].pcurr_size, pop[0].parts[i].pmax_size); 262 | } 263 | #endif 264 | 265 | /* free memory for all data structures */ 266 | free(cells); 267 | for (int i = 0; i < nocells; i++) { 268 | free(cells_info[i].mgain); 269 | free(cells_info[i].partb_ptr); 270 | free(cells_info[i].partb_gain_inx); 271 | } 272 | free(cells_info); 273 | 274 | for (int i = 0; i < nonets; i++) { 275 | free(nets[i].npartdeg); 276 | free(nets_info[i].npartdeg); 277 | } 278 | free(nets); 279 | free(nets_info); 280 | 281 | free(cnets); 282 | free(ncells); 283 | 284 | for (int i = 0; i < noparts; i++) { 285 | for (int j = 0; j < noparts - 1; ++j) { 286 | free(partb[i][j].bnode_ptr); 287 | } 288 | } 289 | 290 | for (int i = 0; i < MAX_POP; i++) { 291 | free(pop[i].chrom); 292 | free(pop[i].parts); 293 | } 294 | 295 | free(mcells); 296 | 297 | free(tchrom); 298 | 299 | free(eval); 300 | 301 | return (0); 302 | } /* main_pfm */ 303 | 304 | /* EOF */ 305 | -------------------------------------------------------------------------------- /src/pfm/utest.awk: -------------------------------------------------------------------------------- 1 | # Awk program called in utest.sh 2 | { 3 | # c = current cutsize 4 | # l = target cutsize 5 | c = $7 6 | s = "program=" p ": cutsize=" c " target=" t 7 | if (c == t) { 8 | print "Passed:", s; 9 | } else { 10 | print "Failed:", s; 11 | } 12 | } 13 | 14 | # EOF 15 | -------------------------------------------------------------------------------- /src/pfm/utest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # testing each executable using input/hp1 4 | 5 | ./ad_pfm.x ../../input/hp1 2 1 1 123456 | grep Final | awk -v p="ad_pfm p1 2 1 1" -v t=1 -f utest.awk 6 | ./ad_pfm.x ../../input/hp1 2 2 1 123456 | grep Final | awk -v p="ad_pfm p1 2 2 1" -v t=1 -f utest.awk 7 | ./ad_pfm.x ../../input/hp1 2 3 1 123456 | grep Final | awk -v p="ad_pfm p1 2 3 1" -v t=1 -f utest.awk 8 | 9 | # testing each executable using input/hp9 10 | 11 | ./ad_pfm.x ../../input/hp9 2 1 1 123456 | grep Final | awk -v p="ad_pfm p9 2 1 1" -v t=75 -f utest.awk 12 | ./ad_pfm.x ../../input/hp9 3 1 1 123456 | grep Final | awk -v p="ad_pfm p9 3 1 1" -v t=69 -f utest.awk 13 | ./ad_pfm.x ../../input/hp9 2 2 1 123456 | grep Final | awk -v p="ad_pfm p9 2 2 1" -v t=53 -f utest.awk 14 | ./ad_pfm.x ../../input/hp9 3 2 1 123456 | grep Final | awk -v p="ad_pfm p9 3 2 1" -v t=75 -f utest.awk 15 | ./ad_pfm.x ../../input/hp9 2 3 2 123456 | grep Final | awk -v p="ad_pfm p9 2 3 2" -v t=32 -f utest.awk 16 | ./ad_pfm.x ../../input/hp9 3 3 2 123456 | grep Final | awk -v p="ad_pfm p9 3 3 2" -v t=58 -f utest.awk 17 | 18 | # EOF 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/plm/Makefile: -------------------------------------------------------------------------------- 1 | CC0 = gcc 2 | CC = $(CC0) 3 | LD = $(CC0) 4 | FLAGS1 = -O3 5 | FLAGS2 = -lm 6 | FLAGS3 = -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow 7 | DIR_H = ../share 8 | FLAGS = $(FLAGS1) $(FLAGS3) -I$(DIR_H) 9 | 10 | DEPS_SHARE = $(DIR_H)/ad_bucketio.h \ 11 | $(DIR_H)/ad_fileio.h \ 12 | $(DIR_H)/ad_lib.h \ 13 | $(DIR_H)/ad_partition.h \ 14 | $(DIR_H)/ad_print.h \ 15 | $(DIR_H)/ad_random.h \ 16 | $(DIR_H)/ad_readinput.h 17 | 18 | DEPS_PLM = ad_lib_plm.h $(DIR_H)/ad_defs.h $(DEPS_SHARE) 19 | OBJS = $(patsubst %.h,%.o,$(DEPS_SHARE)) 20 | OBJS_PLM = $(OBJS) ad_lib_plm.o 21 | 22 | all: ad_plm 23 | 24 | ad_lib_plm.o: ad_lib_plm.c ad_lib_plm.h $(DIR_H)/ad_lib.h $(DIR_H)/ad_bucketio.h $(DIR_H)/ad_defs.h 25 | $(CC) $(FLAGS) -c -o $@ $< 26 | 27 | ad_plm: ad_plm.c $(DEPS_PLM) $(OBJS_PLM) 28 | $(CC) $(FLAGS) -o $@.x $< $(OBJS_PLM) 29 | 30 | # Testing: 31 | test: 32 | ./utest.sh 33 | 34 | # Cleaning: 35 | clean c cl cle clea: 36 | rm -f *.o *~ core *.x 37 | cleano: 38 | rm -f *.o *~ core 39 | 40 | # End of file 41 | -------------------------------------------------------------------------------- /src/plm/ad_lib_plm.c: -------------------------------------------------------------------------------- 1 | 2 | /* COPYRIGHT C 1991- Ali Dasdan */ 3 | 4 | #include 5 | #include 6 | #include "ad_defs.h" 7 | #include "ad_bucketio.h" 8 | #include "ad_lib.h" 9 | #include "ad_lib_plm.h" 10 | 11 | /* map a given mov_gain into index to a bucket array */ 12 | int map_gain(int mov_gain, int max_gain) 13 | { 14 | return (mov_gain + max_gain); 15 | } /* map_gain */ 16 | 17 | /* fill all bucket arrays */ 18 | void create_buckets(int nocells, 19 | int noparts, 20 | int max_gain, 21 | allele chrom[], 22 | partb_t partb[][noparts - 1], 23 | cells_info_t cells_info[]) 24 | { 25 | /* read cell gains from cells_info and insert them into buckets */ 26 | for (int cell_no = 0; cell_no < nocells; cell_no++) { 27 | 28 | int part_no = chrom[cell_no]; 29 | 30 | /* for each possible move direction */ 31 | for (int mov_part_no = 0; mov_part_no < noparts; mov_part_no++) { 32 | if (mov_part_no != part_no) { 33 | 34 | int mov_gain = calculate_gain(cell_no, part_no, mov_part_no, cells_info); 35 | 36 | /* find mapped_after calculating gain & max */ 37 | int mapped_part_no = map_part_no(mov_part_no, part_no); 38 | int gain_inx = map_gain(mov_gain, max_gain); 39 | 40 | /* create a partb node */ 41 | create_partb_node(noparts, cell_no, part_no, mapped_part_no, 42 | gain_inx, partb, cells_info); 43 | 44 | } /* if mapped_part_no not equal part_no */ 45 | } /* for mapped_part_no */ 46 | } /* for part_no */ 47 | } /* create_buckets */ 48 | 49 | /* select a cell to move */ 50 | int select_cell(int noparts, 51 | selected_cell_t scell[], 52 | parts_info_t parts_info[], 53 | cells_t cells[], 54 | partb_t partb[][noparts - 1], 55 | cells_info_t cells_info[]) 56 | { 57 | /* 58 | add to the 1st "if" && (parts_info[from].pmax_cells > 0) 59 | */ 60 | int move_possible = True; 61 | int max_mov_value = -1; 62 | for (int from = 0; from < noparts; from++) { 63 | int fpcurr_size = parts_info[from].pcurr_size; 64 | int fpmin_size = parts_info[from].pmin_size; 65 | if (fpcurr_size > fpmin_size) { 66 | for (int to = 0; to < noparts; to++) { 67 | int tpmax_size = parts_info[to].pmax_size; 68 | int tpcurr_size = parts_info[to].pcurr_size; 69 | if ((from != to) && (tpcurr_size < tpmax_size)) { 70 | int dest_part = map_part_no(to, from); 71 | int max_inx = partb[from][dest_part].max_inx; 72 | if (max_inx < 0) { 73 | printf("Error: max_inx cannot be negative.\n"); 74 | exit(1); 75 | } 76 | int cell_no = partb[from][dest_part].bnode_ptr[max_inx]->cell_no; 77 | if ((max_mov_value < max_inx) && 78 | (fpcurr_size >= (fpmin_size + cells[cell_no].cweight)) && 79 | ((tpcurr_size + cells[cell_no].cweight) <= tpmax_size)) { 80 | max_mov_value = max_inx; 81 | scell[0].mov_cell_no = cell_no; 82 | scell[0].from_part = from; 83 | scell[0].to_part = to; 84 | } /* if many conditions */ 85 | } /* if */ 86 | } /* for to */ 87 | } /* if curr > min */ 88 | } /* for from */ 89 | 90 | if (max_mov_value != -1) { 91 | 92 | scell[0].mov_gain = calculate_gain(scell[0].mov_cell_no, 93 | scell[0].from_part, 94 | scell[0].to_part, 95 | cells_info); 96 | parts_info[scell[0].from_part].pmax_cells--; 97 | parts_info[scell[0].to_part].pmax_cells++; 98 | parts_info[scell[0].from_part].pcurr_size -= 99 | cells[scell[0].mov_cell_no].cweight; 100 | parts_info[scell[0].to_part].pcurr_size += 101 | cells[scell[0].mov_cell_no].cweight; 102 | 103 | } else { 104 | 105 | move_possible = False; 106 | max_mov_value = -1; 107 | for (int from = 0; from < noparts; from++) { 108 | // int fpcurr_size = parts_info[from].pcurr_size; 109 | // int fpmin_size = parts_info[from].pmin_size; 110 | for (int to = 0; to < noparts; to++) { 111 | // int tpmax_size = parts_info[to].pmax_size; 112 | // int tpcurr_size = parts_info[to].pcurr_size; 113 | if (from != to) { 114 | int dest_part = map_part_no(to, from); 115 | int max_inx = partb[from][dest_part].max_inx; 116 | if (max_inx > 0) { 117 | int cell_no = partb[from][dest_part].bnode_ptr[max_inx]->cell_no; 118 | if (max_mov_value < max_inx) { 119 | max_mov_value = max_inx; 120 | scell[0].mov_cell_no = cell_no; 121 | scell[0].from_part = from; 122 | } /* if many conditions */ 123 | } /* if */ 124 | } /* if */ 125 | } /* for to */ 126 | } /* for from */ 127 | 128 | } /* else */ 129 | 130 | return move_possible; 131 | } /* select_cell */ 132 | 133 | /* move selected cell, and save the move in a file */ 134 | void move_cell(mcells_t mcells[], 135 | int msize, 136 | selected_cell_t scell[], 137 | allele tchrom[]) 138 | { 139 | tchrom[scell[0].mov_cell_no] = scell[0].to_part; 140 | mcells[msize].cell_no = scell[0].mov_cell_no; 141 | mcells[msize].from = scell[0].from_part; 142 | mcells[msize].to = scell[0].to_part; 143 | mcells[msize].mgain = scell[0].mov_gain; 144 | } /* move_cell */ 145 | 146 | /* update gains after a move */ 147 | void update_gains(int noparts, 148 | int max_gain, 149 | selected_cell_t scell[], 150 | cells_t cells[], 151 | nets_t nets[], 152 | corn_t cnets[], 153 | corn_t ncells[], 154 | nets_info_t nets_info[], 155 | partb_t partb[][noparts - 1], 156 | cells_info_t cells_info[], 157 | allele tchrom[]) 158 | { 159 | int net_ptr = cells[scell[0].mov_cell_no].netlist; 160 | int mov_cell_no = scell[0].mov_cell_no; 161 | int from_part = scell[0].from_part; 162 | int to_part = scell[0].to_part; 163 | 164 | /* for each neighor net */ 165 | for (int i = 0; i < cells[mov_cell_no].cno_nets; i++) { 166 | 167 | int net_no = cnets[net_ptr + i].corn_no; 168 | int net_weight = nets[net_no].nweight; 169 | int cell_ptr = nets[net_no].celllist; 170 | 171 | /* do operations before the move */ 172 | if (nets_info[net_no].npartdeg[from_part] == nets[net_no].nno_cells) { 173 | 174 | update1(False, noparts, max_gain, from_part, mov_cell_no, 175 | cell_ptr, net_no, net_weight, 176 | nets, ncells, partb, cells_info, tchrom); 177 | 178 | } else if (nets_info[net_no].npartdeg[from_part] == (nets[net_no].nno_cells - 1)) { 179 | 180 | update2(False, noparts, max_gain, from_part, mov_cell_no, 181 | cell_ptr, net_no, net_weight, 182 | nets, ncells, partb, cells_info, tchrom); 183 | 184 | } 185 | 186 | /* update net info */ 187 | nets_info[net_no].npartdeg[from_part]--; 188 | nets_info[net_no].npartdeg[to_part]++; 189 | 190 | /* do operations after the move */ 191 | if (nets_info[net_no].npartdeg[to_part] == nets[net_no].nno_cells) { 192 | 193 | update1(True, noparts, max_gain, to_part, mov_cell_no, 194 | cell_ptr, net_no, net_weight, 195 | nets, ncells, partb, cells_info, tchrom); 196 | 197 | } else if (nets_info[net_no].npartdeg[to_part] == (nets[net_no].nno_cells - 1)) { 198 | 199 | update2(True, noparts, max_gain, to_part, mov_cell_no, 200 | cell_ptr, net_no, net_weight, 201 | nets, ncells, partb, cells_info, tchrom); 202 | 203 | } /* else */ 204 | 205 | } /* for i */ 206 | } /* update_gains */ 207 | 208 | /* update gain of a cell */ 209 | void update1(int flag, 210 | int noparts, 211 | int max_gain, 212 | int dest_part, 213 | int mov_cell_no, 214 | int cell_ptr, 215 | int net_no, 216 | int net_weight, 217 | nets_t nets[], 218 | corn_t ncells[], 219 | partb_t partb[][noparts - 1], 220 | cells_info_t cells_info[], 221 | allele tchrom[]) 222 | { 223 | int i = 0; 224 | while (i < nets[net_no].nno_cells) { 225 | 226 | int other_cell = ncells[cell_ptr + i].corn_no; 227 | int other_part_no = tchrom[other_cell]; 228 | if ((other_cell != mov_cell_no) && (cells_info[other_cell].locked == False)) { 229 | 230 | if (flag == False) { 231 | cells_info[other_cell].mgain[dest_part] -= net_weight; 232 | } else { 233 | cells_info[other_cell].mgain[dest_part] += net_weight; 234 | } 235 | 236 | /* since internal gains change, update all gains */ 237 | delete_partb_nodes_of_cell(noparts, other_cell, other_part_no, 238 | partb, cells_info); 239 | create_partb_nodes_of_cell(noparts, max_gain, 240 | other_cell, other_part_no, 241 | partb, cells_info); 242 | } /* if */ 243 | 244 | i++; 245 | } /* while */ 246 | } /* update1 */ 247 | 248 | /* update gain of a cell */ 249 | void update2(int flag, 250 | int noparts, 251 | int max_gain, 252 | int dest_part, 253 | int mov_cell_no, 254 | int cell_ptr, 255 | int net_no, 256 | int net_weight, 257 | nets_t nets[], 258 | corn_t ncells[], 259 | partb_t partb[][noparts - 1], 260 | cells_info_t cells_info[], 261 | allele tchrom[]) 262 | { 263 | int other_cell, other_part_no; 264 | 265 | int found = False; 266 | int i = 0; 267 | while ((i < nets[net_no].nno_cells) && (!found)) { 268 | 269 | other_cell = ncells[cell_ptr + i].corn_no; 270 | other_part_no = tchrom[other_cell]; 271 | if ((other_cell != mov_cell_no) && 272 | (cells_info[other_cell].locked == False) && 273 | (other_part_no != dest_part)) { 274 | found = True; 275 | } /* if */ 276 | 277 | i++; 278 | } /* while */ 279 | 280 | if (!found) return; 281 | 282 | if (flag == False) { 283 | cells_info[other_cell].mgain[dest_part] -= net_weight; 284 | } else { 285 | cells_info[other_cell].mgain[dest_part] += net_weight; 286 | } 287 | 288 | int mov_gain = calculate_gain(other_cell, other_part_no, 289 | dest_part, cells_info); 290 | int gain_inx = map_gain(mov_gain, max_gain); 291 | int mapped_part_no = map_part_no(dest_part, other_part_no); 292 | bnode_ptr_t tnode_ptr = delete_partb_node(False, mapped_part_no, 293 | &partb[other_part_no][mapped_part_no], 294 | &cells_info[other_cell]); 295 | insert_partb_node(tnode_ptr, mapped_part_no, gain_inx, 296 | &partb[other_part_no][mapped_part_no], 297 | &cells_info[other_cell]); 298 | } /* update2 */ 299 | 300 | void create_partb_nodes_of_cell(int noparts, 301 | int max_gain, 302 | int cell_no, 303 | int part_no, 304 | partb_t partb[][noparts - 1], 305 | cells_info_t cells_info[]) 306 | { 307 | if (cell_no == -1) { 308 | return; 309 | } 310 | 311 | /* for each possible move direction */ 312 | for (int mov_part_no = 0; mov_part_no < noparts; mov_part_no++) { 313 | 314 | if (mov_part_no != part_no) { /* part_no is home_part of cell_no */ 315 | 316 | int mov_gain = calculate_gain(cell_no, part_no, mov_part_no, cells_info); 317 | 318 | /* find mapped_after calculating gain & max */ 319 | int mapped_part_no = map_part_no(mov_part_no, part_no); 320 | int gain_inx = map_gain(mov_gain, max_gain); 321 | 322 | /* create a partb node */ 323 | create_partb_node(noparts, cell_no, part_no, mapped_part_no, 324 | gain_inx, partb, cells_info); 325 | 326 | } /* if mapped_part_no not equal part_no */ 327 | } /* for mapped_part_no */ 328 | } /* create_partb_nodes_of_cell */ 329 | 330 | /* EOF */ 331 | -------------------------------------------------------------------------------- /src/plm/ad_lib_plm.h: -------------------------------------------------------------------------------- 1 | #ifndef AD_LIB_PLM_INCLUDED 2 | #define AD_LIB_PLM_INCLUDED 3 | 4 | /* COPYRIGHT C 1991- Ali Dasdan */ 5 | 6 | /* map a given mov_gain into index to a bucket array */ 7 | int map_gain(int mov_gain, int max_gain); 8 | 9 | /* fill all bucket arrays */ 10 | void create_buckets(int nocells, 11 | int noparts, 12 | int max_gain, 13 | allele chrom[], 14 | partb_t partb[][noparts - 1], 15 | cells_info_t cells_info[]); 16 | 17 | /* select a cell to move */ 18 | int select_cell(int noparts, 19 | selected_cell_t scell[], 20 | parts_info_t parts_info[], 21 | cells_t cells[], 22 | partb_t partb[][noparts - 1], 23 | cells_info_t cells_info[]); 24 | 25 | /* move selected cell, and save the move in a file */ 26 | void move_cell(mcells_t mcells[], 27 | int msize, 28 | selected_cell_t scell[], 29 | allele tchrom[]); 30 | 31 | /* update gains after a move */ 32 | void update_gains(int noparts, 33 | int max_gain, 34 | selected_cell_t scell[], 35 | cells_t cells[], 36 | nets_t nets[], 37 | corn_t cnets[], 38 | corn_t ncells[], 39 | nets_info_t nets_info[], 40 | partb_t partb[][noparts - 1], 41 | cells_info_t cells_info[], 42 | allele tchrom[]); 43 | 44 | /* update gain of a cell */ 45 | void update1(int flag, 46 | int noparts, 47 | int max_gain, 48 | int dest_part, 49 | int mov_cell_no, 50 | int cell_ptr, 51 | int net_no, 52 | int net_weight, 53 | nets_t nets[], 54 | corn_t ncells[], 55 | partb_t partb[][noparts - 1], 56 | cells_info_t cells_info[], 57 | allele tchrom[]); 58 | 59 | /* update gain of a cell */ 60 | void update2(int flag, 61 | int noparts, 62 | int max_gain, 63 | int dest_part, 64 | int mov_cell_no, 65 | int cell_ptr, 66 | int net_no, 67 | int net_weight, 68 | nets_t nets[], 69 | corn_t ncells[], 70 | partb_t partb[][noparts - 1], 71 | cells_info_t cells_info[], 72 | allele tchrom[]); 73 | 74 | void create_partb_nodes_of_cell(int noparts, 75 | int max_gain, 76 | int cell_no, 77 | int part_no, 78 | partb_t partb[][noparts - 1], 79 | cells_info_t cells_info[]); 80 | 81 | #endif 82 | 83 | -------------------------------------------------------------------------------- /src/plm/ad_plm.c: -------------------------------------------------------------------------------- 1 | 2 | /* COPYRIGHT C 1991- Ali Dasdan */ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "ad_defs.h" 9 | #include "ad_random.h" 10 | #include "ad_fileio.h" 11 | #include "ad_readinput.h" 12 | #include "ad_partition.h" 13 | #include "ad_print.h" 14 | #include "ad_bucketio.h" 15 | #include "ad_lib.h" 16 | #include "ad_lib_plm.h" 17 | 18 | /* PARTITIONING BY LOCKED MOVES */ 19 | /* Direct multi-way partitioning. 20 | Locking is used. 21 | Cells are moved wrt their gains. 22 | prefix sum is computed at the end of the outher loop as in 1st heuristic. 23 | run until a local optimum is found 24 | */ 25 | 26 | int main(int argc, char *argv[]) 27 | { 28 | /* definitions */ 29 | int nocells; /* number of cells */ 30 | int nonets; /* number of nets */ 31 | int nopins; /* number of pins */ 32 | int noparts; /* number of partitions */ 33 | int totcellsize; /* total cell weight of the partition */ 34 | int totnetsize; /* total net weight of the partition */ 35 | int cutsize; /* cutsize of the partition */ 36 | int max_gain; /* max gain of a cell */ 37 | int max_cdeg; /* max density of a cell */ 38 | int max_ndeg; /* max density of a net */ 39 | int max_cweight; /* max cell weight */ 40 | int max_nweight; /* max net weight */ 41 | 42 | if (argc < 5) { 43 | printf("\nUsage: %s InputFileName NoParts InCount OutCount [Seed]\n", argv[0]); 44 | printf("\t#cells moved per phase = incount * nocells / 4\n"); 45 | printf("\t\tUse 1, 2, 3, or 4 for incount.\n"); 46 | printf("\t#cells moved per pass = nocells if outcount = 1,\n"); 47 | printf("\t#cells moved per pass = nocells * noparts if outcount = 2, and\n"); 48 | printf("\t#cells moved per pass = nocells * noparts * noparts if outcount = 3.\n"); 49 | exit(1); 50 | } /* if */ 51 | 52 | char fname[STR_SIZE]; 53 | sprintf(fname, "%s", argv[1]); 54 | 55 | noparts = atoi(argv[2]); 56 | 57 | int incount = atoi(argv[3]); 58 | int outcount = atoi(argv[4]); 59 | 60 | long seed; 61 | if (argc > 5) { 62 | seed = (long) atoi(argv[5]); 63 | } else { 64 | seed = (long) -1; 65 | } 66 | seed = randomize((long) seed); 67 | printf("SEED = %ld fname = %s\n", seed, fname); 68 | 69 | read_hgraph_size(fname, &nocells, &nonets, &nopins); 70 | 71 | /* determine what in- & out-count imply */ 72 | int max_moved_cells = incount * nocells / 4; 73 | switch (outcount) { 74 | case 1 : outcount = nocells; break; 75 | case 2 : outcount = nocells * noparts; break; 76 | case 3 : outcount = nocells * noparts * noparts; break; 77 | default : break; 78 | } 79 | /* max_noiter = outcount / max_moved_cells;*/ /* do that many iterations */ 80 | int max_noiter = outcount; 81 | 82 | /* alloc memory for all data structures */ 83 | cells_t *cells = (cells_t *) calloc(nocells, sizeof(cells_t)); 84 | assert(cells != NULL); 85 | cells_info_t *cells_info = (cells_info_t *) calloc(nocells, sizeof(cells_info_t)); 86 | assert(cells_info != NULL); 87 | for (int i = 0; i < nocells; i++) { 88 | cells_info[i].mgain = (int *) calloc(noparts, sizeof(int)); 89 | assert(cells_info[i].mgain != NULL); 90 | cells_info[i].partb_ptr = (bnode_ptr_t *) calloc(noparts - 1, sizeof(bnode_ptr_t)); 91 | assert(cells_info[i].partb_ptr != NULL); 92 | cells_info[i].partb_gain_inx = (int *) calloc(noparts - 1, sizeof(int)); 93 | assert(cells_info[i].partb_gain_inx != NULL); 94 | } 95 | 96 | nets_t *nets = (nets_t *) calloc(nonets, sizeof(nets_t)); 97 | assert(nets != NULL); 98 | nets_info_t *nets_info = (nets_info_t *) calloc(nonets, sizeof(nets_info_t)); 99 | assert(nets_info != NULL); 100 | for (int i = 0; i < nonets; i++) { 101 | nets[i].npartdeg = (int *) calloc(noparts, sizeof(int)); 102 | assert(nets[i].npartdeg != NULL); 103 | nets_info[i].npartdeg = (int *) calloc(noparts, sizeof(int)); 104 | assert(nets_info[i].npartdeg != NULL); 105 | } 106 | 107 | /* cells of nets */ 108 | corn_t *cnets = (corn_t *) calloc(nopins, sizeof(corn_t)); 109 | assert(cnets != NULL); 110 | /* nets of cells */ 111 | corn_t *ncells = (corn_t *) calloc(nopins, sizeof(corn_t)); 112 | assert(ncells != NULL); 113 | 114 | /* partition buckets */ 115 | partb_t partb[noparts][noparts - 1]; 116 | parts_info_t parts_info[noparts]; 117 | 118 | /* population (w/ one individual!) */ 119 | ind_t pop[MAX_POP]; 120 | for (int i = 0; i < MAX_POP; i++) { 121 | pop[i].chrom = (allele *) calloc(nocells, sizeof(allele)); 122 | assert(pop[i].chrom != NULL); 123 | pop[i].parts = (parts_t *) calloc(noparts, sizeof(parts_t)); 124 | assert(pop[i].parts != NULL); 125 | } 126 | 127 | /* selected cell */ 128 | selected_cell_t scell[1]; 129 | 130 | /* moved cells */ 131 | mcells_t *mcells = (mcells_t *) calloc(2 * max_noiter, sizeof(mcells_t)); 132 | assert(mcells != NULL); 133 | 134 | /* temp chrom */ 135 | allele *tchrom = (allele *) calloc(nocells, sizeof(allele)); 136 | assert(tchrom != NULL); 137 | 138 | read_hgraph(fname, nocells, nonets, nopins, noparts, 139 | &totcellsize, &totnetsize, &max_cdeg, &max_ndeg, 140 | &max_cweight, &max_nweight, 141 | cells, nets, cnets, ncells); 142 | 143 | max_gain = max_cdeg * max_nweight; 144 | int bucketsize = 2 * max_gain + 1; 145 | 146 | /* alloc memory (statically if possible) */ 147 | for (int i = 0; i < noparts; i++) { 148 | for (int j = 0; j < noparts - 1; ++j) { 149 | partb[i][j].bnode_ptr = (bnode_ptr_t *) calloc(bucketsize, sizeof(bnode_ptr_t)); 150 | } 151 | } 152 | 153 | float off_ratio = (float) 0.1; /* alpha in initial partitioning */ 154 | create_partition(nocells, noparts, totcellsize, max_cweight, &off_ratio, 155 | cells, nets, cnets, &pop[0]); 156 | 157 | #ifdef DEBUG 158 | printf("off=%f\n", off_ratio); 159 | for (int i = 0; i < noparts; i++) { 160 | printf("II %d %d %d %d\n", i, pop[0].parts[i].pmin_size, 161 | pop[0].parts[i].pcurr_size, pop[0]. parts[i].pmax_size); 162 | } 163 | #endif 164 | 165 | init_buckets(noparts, bucketsize, partb); 166 | cutsize = find_cut_size(nonets, noparts, totnetsize, nets, &pop[0]); 167 | 168 | #ifdef DEBUG 169 | printf("Totalsize = %d Initial cutsize = %d\n", totnetsize, cutsize); 170 | #endif 171 | 172 | int gain_sum; 173 | int glob_inx = 0; 174 | int pass_no = 0; 175 | do { 176 | 177 | copy_partition(noparts, parts_info, &pop[0]); 178 | 179 | copy_nets_info(nonets, noparts, nets, nets_info); 180 | 181 | for (int i = 0; i < nocells; i++) { 182 | tchrom[i] = pop[0].chrom[i]; 183 | } 184 | 185 | int msize = 0; /* index to mcells */ 186 | int noiter = 0; 187 | while (noiter < max_noiter) { 188 | 189 | compute_gains2(nocells, noparts, cells, nets, cnets, 190 | cells_info, tchrom, nets_info); 191 | 192 | create_buckets(nocells, noparts, max_gain, tchrom, 193 | partb, cells_info); 194 | 195 | int nlocked = 0; 196 | do { 197 | int move_possible = select_cell(noparts, scell, parts_info, cells, 198 | partb, cells_info); 199 | 200 | delete_partb_nodes_of_cell(noparts, scell[0].mov_cell_no, 201 | scell[0].from_part, partb, cells_info); 202 | /* lock cell */ 203 | cells_info[scell[0].mov_cell_no].locked = True; 204 | if (move_possible == True) { 205 | move_cell(mcells, msize, scell, tchrom); 206 | msize++; 207 | update_gains(noparts, max_gain, scell, 208 | cells, nets, cnets, ncells, nets_info, 209 | partb, cells_info, tchrom); 210 | } /* if */ 211 | nlocked++; 212 | 213 | noiter++; 214 | } while ((nlocked < max_moved_cells) && 215 | (noiter < max_noiter)); 216 | 217 | free_nodes(noparts, bucketsize, partb); 218 | 219 | } /* while */ 220 | 221 | int max_mcells_inx; 222 | gain_sum = find_move_set(mcells, msize, &max_mcells_inx); 223 | 224 | #ifdef DEBUG 225 | printf("gain_sum=%d max_mcells_inx=%d msize = %d\n", 226 | gain_sum, max_mcells_inx, msize); 227 | #endif 228 | 229 | if (gain_sum > 0) { 230 | int cut_gain = move_cells(False, nocells, msize, mcells, max_mcells_inx, 231 | cutsize, &glob_inx, &pop[0], cells, nets, cnets); 232 | cutsize -= cut_gain; 233 | } /* if */ 234 | pass_no++; 235 | 236 | #ifdef DEBUG 237 | printf("pass_no = %d Final cutsize = %d Check cutsize = %d\n", 238 | pass_no, cutsize, 239 | find_cut_size(nonets, noparts, totnetsize, nets, &pop[0])); 240 | #endif 241 | 242 | } while ((gain_sum > 0) && (cutsize > 0) && (pass_no < NO_ITERATIONS)); 243 | 244 | printf("pass_no = %d Final cutsize = %d Check cutsize = %d\n", pass_no, 245 | cutsize, find_cut_size(nonets, noparts, totnetsize, nets, &pop[0])); 246 | 247 | free_nodes(noparts, bucketsize, partb); 248 | 249 | #ifdef DEBUG 250 | printf("Final : Part_no min_size curr_size max_size\n"); 251 | for (int i = 0; i < noparts; i++) { 252 | printf("FF %d %d %d %d\n", i, pop[0].parts[i].pmin_size, 253 | pop[0].parts[i].pcurr_size, pop[0].parts[i].pmax_size); 254 | } 255 | #endif 256 | 257 | /* free memory for all data structures */ 258 | free(cells); 259 | for (int i = 0; i < nocells; i++) { 260 | free(cells_info[i].mgain); 261 | free(cells_info[i].partb_ptr); 262 | free(cells_info[i].partb_gain_inx); 263 | } 264 | free(cells_info); 265 | 266 | for (int i = 0; i < nonets; i++) { 267 | free(nets[i].npartdeg); 268 | free(nets_info[i].npartdeg); 269 | } 270 | free(nets); 271 | free(nets_info); 272 | 273 | free(cnets); 274 | free(ncells); 275 | 276 | for (int i = 0; i < noparts; i++) { 277 | for (int j = 0; j < noparts - 1; ++j) { 278 | free(partb[i][j].bnode_ptr); 279 | } 280 | } 281 | 282 | for (int i = 0; i < MAX_POP; i++) { 283 | free(pop[i].chrom); 284 | free(pop[i].parts); 285 | } 286 | 287 | free(mcells); 288 | 289 | free(tchrom); 290 | 291 | return (0); 292 | } /* main-plm */ 293 | 294 | /* EOF */ 295 | -------------------------------------------------------------------------------- /src/plm/utest.awk: -------------------------------------------------------------------------------- 1 | # Awk program called in utest.sh 2 | { 3 | # c = current cutsize 4 | # l = target cutsize 5 | c = $7 6 | s = "program=" p ": cutsize=" c " target=" t 7 | if (c == t) { 8 | print "Passed:", s; 9 | } else { 10 | print "Failed:", s; 11 | } 12 | } 13 | 14 | # EOF 15 | -------------------------------------------------------------------------------- /src/plm/utest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # testing each executable using input/hp1 4 | 5 | ./ad_plm.x ../../input/hp1 2 1 1 123456 | grep Final | awk -v p="ad_plm p1 2 1 1" -v t=1 -f utest.awk 6 | ./ad_plm.x ../../input/hp1 2 2 1 123456 | grep Final | awk -v p="ad_plm p1 2 2 1" -v t=1 -f utest.awk 7 | ./ad_plm.x ../../input/hp1 2 1 2 123456 | grep Final | awk -v p="ad_plm p1 2 1 2" -v t=1 -f utest.awk 8 | 9 | # testing each executable using input/hp9 10 | 11 | ./ad_plm.x ../../input/hp9 2 1 1 123456 | grep Final | awk -v p="ad_plm p9 2 1 1" -v t=26 -f utest.awk 12 | ./ad_plm.x ../../input/hp9 3 1 1 123456 | grep Final | awk -v p="ad_plm p9 3 1 1" -v t=157 -f utest.awk 13 | ./ad_plm.x ../../input/hp9 2 2 1 123456 | grep Final | awk -v p="ad_plm p9 2 2 1" -v t=35 -f utest.awk 14 | ./ad_plm.x ../../input/hp9 3 2 1 123456 | grep Final | awk -v p="ad_plm p9 3 2 1" -v t=163 -f utest.awk 15 | ./ad_plm.x ../../input/hp9 2 1 2 123456 | grep Final | awk -v p="ad_plm p9 2 1 2" -v t=27 -f utest.awk 16 | ./ad_plm.x ../../input/hp9 3 1 2 123456 | grep Final | awk -v p="ad_plm p9 3 1 2" -v t=175 -f utest.awk 17 | 18 | # EOF 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/sa/Makefile: -------------------------------------------------------------------------------- 1 | CC0 = gcc 2 | CC = $(CC0) 3 | LD = $(CC0) 4 | FLAGS1 = -O3 5 | FLAGS2 = -lm 6 | FLAGS3 = -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow 7 | DIR_H = ../share 8 | FLAGS = $(FLAGS1) $(FLAGS3) -I$(DIR_H) 9 | 10 | DEPS_SHARE = $(DIR_H)/ad_bucketio.h \ 11 | $(DIR_H)/ad_fileio.h \ 12 | $(DIR_H)/ad_lib.h \ 13 | $(DIR_H)/ad_partition.h \ 14 | $(DIR_H)/ad_print.h \ 15 | $(DIR_H)/ad_random.h \ 16 | $(DIR_H)/ad_readinput.h 17 | 18 | DEPS_SA1 = ad_lib_sa.h $(DIR_H)/ad_defs.h $(DEPS_SHARE) 19 | DEPS_SA2 = $(DEPS_SA1) 20 | DEPS_RSA = $(DEPS_SA1) 21 | 22 | OBJS = $(patsubst %.h,%.o,$(DEPS_SHARE)) 23 | OBJS_SA1 = $(OBJS) ad_lib_sa.o 24 | OBJS_SA2 = $(OBJS_SA1) 25 | OBJS_RSA = $(OBJS_SA1) 26 | 27 | all: ad_sa1 ad_sa2 ad_rsa 28 | 29 | ad_lib_sa.o: ad_lib_sa.c ad_lib_sa.h $(DIR_H)/ad_lib.h $(DIR_H)/ad_bucketio.h $(DIR_H)/ad_defs.h 30 | $(CC) $(FLAGS) -c -o $@ $< $(FLAGS2) 31 | 32 | ad_sa1: ad_sa1.c $(DEPS_SA1) $(OBJS_SA1) 33 | $(CC) $(FLAGS) -o $@.x $< $(OBJS_SA1) $(FLAGS2) 34 | 35 | ad_sa2: ad_sa2.c $(DEPS_SA2) $(OBJS_SA2) 36 | $(CC) $(FLAGS) -o $@.x $< $(OBJS_SA2) $(FLAGS2) 37 | 38 | ad_rsa: ad_rsa.c $(DEPS_RSA) $(OBJS_RSA) 39 | $(CC) $(FLAGS) -o $@.x $< $(OBJS_RSA) $(FLAGS2) 40 | 41 | # Testing: 42 | test: 43 | ./utest.sh 44 | 45 | # Cleaning: 46 | clean c cl cle clea: 47 | rm -f *.o *~ core *.x 48 | cleano: 49 | rm -f *.o *~ core 50 | 51 | # End of file 52 | -------------------------------------------------------------------------------- /src/sa/ad_lib_sa.c: -------------------------------------------------------------------------------- 1 | 2 | /* COPYRIGHT C 1991- Ali Dasdan */ 3 | 4 | #include 5 | #include 6 | #include 7 | #include "ad_defs.h" 8 | #include "ad_random.h" 9 | #include "ad_bucketio.h" 10 | #include "ad_lib.h" 11 | #include "ad_lib_sa.h" 12 | 13 | /* randomly select a move among (nocells * (noparts - 1)) move directions */ 14 | int select_cell(int nocells, 15 | int noparts, 16 | selected_cell_t scell[], 17 | allele tchrom[], 18 | cells_t cells[], 19 | parts_t parts[], 20 | cells_info_t cells_info[]) 21 | { 22 | int cell_no = irandom(0, nocells - 1); 23 | int selected = False; /* true if a cell is selected */ 24 | int nochecks = 0; /* number of cells tried */ 25 | while ((! selected) && (nochecks < nocells)) { 26 | nochecks++; 27 | int from = tchrom[cell_no]; 28 | int to = find_to_part(noparts, cell_no, from, cells, parts); 29 | /* no directions for this cell are feasible, so try another */ 30 | if ((to < 0) || (parts[from].pmax_cells < 1)) { 31 | cell_no = (cell_no + 1) % nocells; 32 | } else { 33 | selected = True; 34 | scell[0].mov_cell_no = cell_no; 35 | scell[0].from_part = from; 36 | scell[0].to_part = to; 37 | scell[0].mov_gain = calculate_gain(scell[0].mov_cell_no, 38 | scell[0].from_part, 39 | scell[0].to_part, 40 | cells_info); 41 | } /* else */ 42 | } /* while */ 43 | if (nochecks < nocells) { 44 | return (True); /* a move is found */ 45 | } else { 46 | return (False); 47 | } 48 | } /* select_cell */ 49 | 50 | /* find a to part to which the selected cell is to be moved */ 51 | /* return -1 if not found */ 52 | int find_to_part(int noparts, 53 | int cell_no, 54 | int from, 55 | cells_t cells[], 56 | parts_t parts[]) 57 | { 58 | int to = irandom(0, noparts - 1); 59 | int nochecks = 0; 60 | int selected = False; 61 | while ((! selected) && (nochecks < noparts)) { 62 | nochecks++; 63 | if ((to == from) || (! feasible_move(cell_no, from, to, cells, parts))) { 64 | to = (to + 1) % noparts; 65 | } else { 66 | selected = True; 67 | } 68 | } /* while */ 69 | if (selected) { 70 | return (to); 71 | } else { 72 | return (-1); 73 | } 74 | } /* find_to_part */ 75 | 76 | /* return true if the selected move is feasible, else false */ 77 | int feasible_move(int cell_no, 78 | int from, 79 | int to, 80 | cells_t cells[], 81 | parts_t parts[]) 82 | { 83 | int fpcurr_size = parts[from].pcurr_size; 84 | int fpmin_size = parts[from].pmin_size; 85 | int tpcurr_size = parts[to].pcurr_size; 86 | int tpmax_size = parts[to].pmax_size; 87 | if ((fpcurr_size >= (fpmin_size + cells[cell_no].cweight)) && 88 | ((tpcurr_size + cells[cell_no].cweight) <= tpmax_size)) { 89 | return (True); 90 | } else { 91 | return (False); 92 | } 93 | } /* feasible_move */ 94 | 95 | /* move the selected cell */ 96 | void move_cell(selected_cell_t scell[], 97 | allele tchrom[], 98 | cells_t cells[], 99 | parts_t parts[]) 100 | { 101 | parts[scell[0].from_part].pmax_cells--; 102 | parts[scell[0].to_part].pmax_cells++; 103 | parts[scell[0].from_part].pcurr_size -= 104 | cells[scell[0].mov_cell_no].cweight; 105 | parts[scell[0].to_part].pcurr_size += 106 | cells[scell[0].mov_cell_no].cweight; 107 | tchrom[scell[0].mov_cell_no] = scell[0].to_part; 108 | } /* move_cell */ 109 | 110 | /* update gains after a move */ 111 | void update_gains(selected_cell_t scell[], 112 | cells_t cells[], 113 | nets_t nets[], 114 | corn_t cnets[], 115 | corn_t ncells[], 116 | cells_info_t cells_info[], 117 | allele tchrom[]) 118 | { 119 | int net_ptr = cells[scell[0].mov_cell_no].netlist; 120 | int mov_cell_no = scell[0].mov_cell_no; 121 | int from_part = scell[0].from_part; 122 | int to_part = scell[0].to_part; 123 | 124 | /* for each neighor net */ 125 | for (int i = 0; i < cells[mov_cell_no].cno_nets; i++) { 126 | 127 | int net_no = cnets[net_ptr + i].corn_no; 128 | int net_weight = nets[net_no].nweight; 129 | int cell_ptr = nets[net_no].celllist; 130 | 131 | /* do operations before the move */ 132 | if (nets[net_no].npartdeg[from_part] == nets[net_no].nno_cells) { 133 | 134 | update1(False, from_part, mov_cell_no, 135 | cell_ptr, net_no, net_weight, 136 | nets, ncells, cells_info); 137 | 138 | } else if (nets[net_no].npartdeg[from_part] == (nets[net_no].nno_cells - 1)) { 139 | 140 | update2(False, from_part, mov_cell_no, 141 | cell_ptr, net_no, net_weight, 142 | nets, ncells, cells_info, tchrom); 143 | 144 | } /* else */ 145 | 146 | /* update net info */ 147 | nets[net_no].npartdeg[from_part]--; 148 | nets[net_no].npartdeg[to_part]++; 149 | 150 | /* do operations after the move */ 151 | if (nets[net_no].npartdeg[to_part] == nets[net_no].nno_cells) { 152 | 153 | update1(True, to_part, mov_cell_no, 154 | cell_ptr, net_no, net_weight, 155 | nets, ncells, cells_info); 156 | 157 | } else if (nets[net_no].npartdeg[to_part] == (nets[net_no].nno_cells - 1)) { 158 | 159 | update2(True, to_part, mov_cell_no, 160 | cell_ptr, net_no, net_weight, 161 | nets, ncells, cells_info, tchrom); 162 | 163 | } /* else */ 164 | } /* for i */ 165 | } /* update_gains */ 166 | 167 | /* update gain of a cell */ 168 | void update1(int flag, 169 | int dest_part, 170 | int mov_cell_no, 171 | int cell_ptr, 172 | int net_no, 173 | int net_weight, 174 | nets_t nets[], 175 | corn_t ncells[], 176 | cells_info_t cells_info[]) 177 | { 178 | int i = 0; 179 | while (i < nets[net_no].nno_cells) { 180 | int other_cell = ncells[cell_ptr + i].corn_no; 181 | if (other_cell != mov_cell_no) { 182 | 183 | if (flag == False) { 184 | cells_info[other_cell].mgain[dest_part] -= net_weight; 185 | } else { 186 | cells_info[other_cell].mgain[dest_part] += net_weight; 187 | } 188 | 189 | } /* if */ 190 | 191 | i++; 192 | } /* while */ 193 | } /* update1 */ 194 | 195 | /* update gain of a cell */ 196 | void update2(int flag, 197 | int dest_part, 198 | int mov_cell_no, 199 | int cell_ptr, 200 | int net_no, 201 | int net_weight, 202 | nets_t nets[], 203 | corn_t ncells[], 204 | cells_info_t cells_info[], 205 | allele tchrom[]) 206 | { 207 | int other_cell, other_part_no; 208 | 209 | int found = False; 210 | int i = 0; 211 | while ((i < nets[net_no].nno_cells) && (!found)) { 212 | 213 | other_cell = ncells[cell_ptr + i].corn_no; 214 | other_part_no = tchrom[other_cell]; 215 | if ((other_cell != mov_cell_no) && 216 | (other_part_no != dest_part)) { 217 | found = True; 218 | } /* if */ 219 | 220 | i++; 221 | } /* while */ 222 | 223 | if (!found) return; 224 | 225 | if (flag == False) { 226 | cells_info[other_cell].mgain[dest_part] -= net_weight; 227 | } else { 228 | cells_info[other_cell].mgain[dest_part] += net_weight; 229 | } 230 | } /* update2 */ 231 | 232 | /* copy pop structures */ 233 | void copy_pop(int nocells, 234 | int noparts, 235 | ind_t from_pop[], 236 | ind_t to_pop[]) 237 | { 238 | for (int i = 0; i < nocells; i++) { 239 | to_pop[0].chrom[i] = from_pop[0].chrom[i]; 240 | } /* for i */ 241 | for (int i = 0; i < noparts; i++) { 242 | to_pop[0].parts[i].pmax_cells = from_pop[0].parts[i].pmax_cells; 243 | to_pop[0].parts[i].pmax_size = from_pop[0].parts[i].pmax_size; 244 | to_pop[0].parts[i].pmin_size = from_pop[0].parts[i].pmin_size; 245 | to_pop[0].parts[i].pcurr_size = from_pop[0].parts[i].pcurr_size; 246 | to_pop[0].parts[i].pratio = from_pop[0].parts[i].pratio; 247 | } /* for i */ 248 | to_pop[0].incost = from_pop[0].incost; 249 | } /* copy_pop */ 250 | 251 | /* copy nets structures */ 252 | void copy_nets(int nonets, 253 | int noparts, 254 | nets_t from_nets[], 255 | nets_t to_nets[]) 256 | { 257 | for (int i = 0; i < nonets; i++) { 258 | to_nets[i].nno_cells = from_nets[i].nno_cells; 259 | to_nets[i].nweight = from_nets[i].nweight; 260 | to_nets[i].celllist = from_nets[i].celllist; 261 | for (int j = 0; j < noparts; j++) { 262 | to_nets[i].npartdeg[j] = from_nets[i].npartdeg[j]; 263 | } 264 | } 265 | } /* copy_nets */ 266 | 267 | /* EOF */ 268 | -------------------------------------------------------------------------------- /src/sa/ad_lib_sa.h: -------------------------------------------------------------------------------- 1 | #ifndef AD_LIB_SA_INCLUDED 2 | #define AD_LIB_SA_INCLUDED 3 | 4 | /* COPYRIGHT C 1991- Ali Dasdan */ 5 | 6 | /* randomly select a move among (nocells * (noparts - 1)) move directions */ 7 | int select_cell(int nocells, 8 | int noparts, 9 | selected_cell_t scell[], 10 | allele tchrom[], 11 | cells_t cells[], 12 | parts_t parts[], 13 | cells_info_t cells_info[]); 14 | 15 | /* find a to part to which the selected cell is to be moved */ 16 | /* return -1 if not found */ 17 | int find_to_part(int noparts, 18 | int cell_no, 19 | int from, 20 | cells_t cells[], 21 | parts_t parts[]); 22 | 23 | /* return true if the selected move is feasible, else false */ 24 | int feasible_move(int cell_no, 25 | int from, 26 | int to, 27 | cells_t cells[], 28 | parts_t parts[]); 29 | 30 | /* move the selected cell */ 31 | void move_cell(selected_cell_t scell[], 32 | allele tchrom[], 33 | cells_t cells[], 34 | parts_t parts[]); 35 | 36 | /* update gains after a move */ 37 | void update_gains(selected_cell_t scell[], 38 | cells_t cells[], 39 | nets_t nets[], 40 | corn_t cnets[], 41 | corn_t ncells[], 42 | cells_info_t cells_info[], 43 | allele tchrom[]); 44 | 45 | /* update gain of a cell */ 46 | void update1(int flag, 47 | int dest_part, 48 | int mov_cell_no, 49 | int cell_ptr, 50 | int net_no, 51 | int net_weight, 52 | nets_t nets[], 53 | corn_t ncells[], 54 | cells_info_t cells_info[]); 55 | 56 | /* update gain of a cell */ 57 | void update2(int flag, 58 | int dest_part, 59 | int mov_cell_no, 60 | int cell_ptr, 61 | int net_no, 62 | int net_weight, 63 | nets_t nets[], 64 | corn_t ncells[], 65 | cells_info_t cells_info[], 66 | allele tchrom[]); 67 | 68 | /* copy pop structures */ 69 | void copy_pop(int nocells, 70 | int noparts, 71 | ind_t pop1[], 72 | ind_t pop2[]); 73 | 74 | /* copy nets structures */ 75 | void copy_nets(int nonets, 76 | int noparts, 77 | nets_t from_nets[], 78 | nets_t to_nets[]); 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /src/sa/ad_rsa.c: -------------------------------------------------------------------------------- 1 | 2 | /* COPYRIGHT C 1991- Ali Dasdan */ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "ad_defs.h" 10 | #include "ad_random.h" 11 | #include "ad_fileio.h" 12 | #include "ad_readinput.h" 13 | #include "ad_partition.h" 14 | #include "ad_lib.h" 15 | #include "ad_lib_sa.h" 16 | 17 | /* Simulated Annealing for Multiple-way Hypergraph Partitioning - 18 | based on the paper: Johnson et al., Optimization by Simulated 19 | Annealing, Operations Research, 37(6), 1989. */ 20 | 21 | /* Uses the ratio cut metric (cutsize divided by the product of the 22 | part sizes) to relax the balance constraint to a softer 23 | constraint. This implementation works for 2-way partitioning 24 | only. */ 25 | 26 | int main(int argc, char *argv[]) 27 | { 28 | /* partitioning variables */ 29 | int nocells; /* number of cells */ 30 | int nonets; /* number of nets */ 31 | int nopins; /* number of pins */ 32 | int noparts; /* number of partitions */ 33 | int totcellsize; /* total cell weight of the partition */ 34 | int totnetsize; /* total net weight of the partition */ 35 | int cutsize; /* cutsize of the partition */ 36 | int max_gain; /* max gain of a cell */ 37 | int max_cdeg; /* max density of a cell */ 38 | int max_ndeg; /* max density of a net */ 39 | int max_cweight; /* max cell weight */ 40 | int max_nweight; /* max net weight */ 41 | 42 | /* SA algorithm variables */ 43 | float temperature; /* temperature in SA alg. */ 44 | float tempfactor; /* cooling ratio */ 45 | float minpercent; /* percentage of accepted moves */ 46 | float cutoff; /* a speedup option - see the paper */ 47 | int delta; /* cost difference between the last two states */ 48 | int freezelimit; /* when freezecount reaches this limit, the system is frozen */ 49 | int freezecount; 50 | int nochanges; /* number of accepted states */ 51 | int changeslimit; /* limit on max number of accepted changes */ 52 | int notrials; /* number of tried states */ 53 | int trialslimit; /* limit on max number of tried states */ 54 | int sizefactor; /* propartionality constant for temperature length */ 55 | int neigh_size; /* neighborhood size */ 56 | int selected; /* set if a feasible move is found */ 57 | int changed; /* set if a change occurs in best_cutsize */ 58 | int same; /* count the number of times cutsize remains the same */ 59 | int samecount; /* limit on the counter "same" */ 60 | int prev_cutsize; /* previous cutsize value - used with "same" */ 61 | int pass_no; /* pass number */ 62 | 63 | /* additional variables for ratio cut partitioning */ 64 | float ratiosize; /* current ratio size */ 65 | float rdelta; /* decrease in ratiosize due to a move */ 66 | float bprod; /* product of sizes of from and to parts before the move */ 67 | float aprod; /* product of sizes of from and to parts after the move */ 68 | float prev_ratiosize; /* previous ratiosize */ 69 | float best_ratiosize; /* best ratiosize so far */ 70 | 71 | if (argc < 3) { 72 | printf("\nUsage: %s InputFileName NoParts [Seed]\n", argv[0]); 73 | exit(1); 74 | } /* if */ 75 | 76 | char fname[STR_SIZE]; 77 | sprintf(fname, "%s", argv[1]); 78 | 79 | noparts = atoi(argv[2]); 80 | if (noparts > 2) { 81 | printf("Warning: SA with ratio cut works for 2-way partitioning only.\n"); 82 | noparts = 2; 83 | } 84 | 85 | long seed; 86 | if (argc > 3) { 87 | seed = (long) atoi(argv[3]); 88 | } else { 89 | seed = -1; 90 | } 91 | seed = randomize((long) seed); 92 | printf("SEED = %ld fname = %s\n", seed, fname); 93 | 94 | read_hgraph_size(fname, &nocells, &nonets, &nopins); 95 | 96 | /* alloc memory for all data structures */ 97 | cells_t *cells = (cells_t *) calloc(nocells, sizeof(cells_t)); 98 | assert(cells != NULL); 99 | cells_info_t *cells_info = (cells_info_t *) calloc(nocells, sizeof(cells_info_t)); 100 | assert(cells_info != NULL); 101 | for (int i = 0; i < nocells; i++) { 102 | cells_info[i].mgain = (int *) calloc(noparts, sizeof(int)); 103 | assert(cells_info[i].mgain != NULL); 104 | cells_info[i].partb_ptr = NULL; 105 | cells_info[i].partb_gain_inx = NULL; 106 | } 107 | 108 | nets_t *nets = (nets_t *) calloc(nonets, sizeof(nets_t)); 109 | assert(nets != NULL); 110 | nets_info_t *nets_info = (nets_info_t *) calloc(nonets, sizeof(nets_info_t)); 111 | assert(nets_info != NULL); 112 | for (int i = 0; i < nonets; i++) { 113 | nets[i].npartdeg = (int *) calloc(noparts, sizeof(int)); 114 | assert(nets[i].npartdeg != NULL); 115 | nets_info[i].npartdeg = (int *) calloc(noparts, sizeof(int)); 116 | assert(nets_info[i].npartdeg != NULL); 117 | } 118 | 119 | /* cells of nets */ 120 | corn_t *cnets = (corn_t *) calloc(nopins, sizeof(corn_t)); 121 | assert(cnets != NULL); 122 | /* nets of cells */ 123 | corn_t *ncells = (corn_t *) calloc(nopins, sizeof(corn_t)); 124 | assert(ncells != NULL); 125 | 126 | /* population (w/ one individual!) */ 127 | ind_t pop[MAX_POP]; 128 | for (int i = 0; i < MAX_POP; i++) { 129 | pop[i].chrom = (allele *) calloc(nocells, sizeof(allele)); 130 | assert(pop[i].chrom != NULL); 131 | pop[i].parts = (parts_t *) calloc(noparts, sizeof(parts_t)); 132 | assert(pop[i].parts != NULL); 133 | } 134 | 135 | /* selected cell */ 136 | selected_cell_t scell[1]; 137 | 138 | /* properties of the best solution */ 139 | int best_cutsize; 140 | 141 | nets_t *best_nets = (nets_t *) calloc(nonets, sizeof(nets_t)); 142 | assert(best_nets != NULL); 143 | for (int i = 0; i < nonets; i++) { 144 | best_nets[i].npartdeg = (int *) calloc(noparts, sizeof(int)); 145 | assert(best_nets[i].npartdeg != NULL); 146 | } 147 | 148 | ind_t best_pop[MAX_POP]; 149 | for (int i = 0; i < MAX_POP; i++) { 150 | best_pop[i].chrom = (allele *) calloc(nocells, sizeof(allele)); 151 | assert(best_pop[i].chrom != NULL); 152 | best_pop[i].parts = (parts_t *) calloc(noparts, sizeof(parts_t)); 153 | assert(best_pop[i].parts != NULL); 154 | } 155 | 156 | read_hgraph(fname, nocells, nonets, nopins, noparts, 157 | &totcellsize, &totnetsize, &max_cdeg, &max_ndeg, 158 | &max_cweight, &max_nweight, 159 | cells, nets, cnets, ncells); 160 | 161 | /* create the initial partition or solution */ 162 | float off_ratio = (float) 0.05; /* alpha in initial partitioning */ 163 | create_partition(nocells, noparts, totcellsize, max_cweight, &off_ratio, 164 | cells, nets, cnets, &pop[0]); 165 | 166 | #ifdef DEBUG1 167 | printf("off=%f\n", off_ratio); 168 | printf("Initial : Part_no min_size curr_size max_size\n"); 169 | for (int i = 0; i < noparts; i++) { 170 | printf("II %d %d %d %d\n", i, pop[0].parts[i].pmin_size, 171 | pop[0].parts[i].pcurr_size, pop[0].parts[i].pmax_size); 172 | } 173 | #endif 174 | 175 | max_gain = max_cdeg * max_nweight; 176 | 177 | /* find initial cutsize */ 178 | cutsize = find_cut_size(nonets, noparts, totnetsize, nets, &pop[0]); 179 | 180 | /* find initial ratiosize */ 181 | ratiosize = (float) cutsize; 182 | for (int i = 0; i < noparts; i++) { 183 | ratiosize /= (float) pop[0].parts[i].pcurr_size; 184 | } 185 | 186 | #ifdef DEBUG1 187 | printf("Totalsize = %d Initial cutsize = %d\n", totnetsize, cutsize); 188 | #endif 189 | 190 | /* compute costs (gains) of cells in hypergraph */ 191 | compute_gains(nocells, noparts, cells, nets, cnets, cells_info, pop[0].chrom); 192 | 193 | /* initialize the current champion solution */ 194 | best_ratiosize = ratiosize; 195 | best_cutsize = cutsize; 196 | copy_pop(nocells, noparts, pop, best_pop); 197 | copy_nets(nonets, noparts, nets, best_nets); 198 | 199 | /* initialize variables of SA algorithm */ 200 | changed = False; 201 | neigh_size = nocells * (noparts - 1); 202 | sizefactor = 16; /* 16 in paper */ 203 | minpercent = 0.005; /* 0.02 in paper */ 204 | cutoff = 1.0; /* 1.0 in paper */ 205 | temperature = 10.0; /* 0.6 - not given in paper */ 206 | tempfactor = 0.95; /* 0.95 in paper */ 207 | freezelimit = 5; /* 5 in paper */ 208 | freezecount = 0; 209 | pass_no = 0; 210 | same = 0; 211 | samecount = nocells; 212 | prev_ratiosize = -1.0; 213 | prev_cutsize = -1; 214 | trialslimit = sizefactor * neigh_size; 215 | changeslimit = (int) (cutoff * sizefactor * neigh_size); 216 | 217 | /* while not yet frozen */ 218 | while (freezecount < freezelimit) { 219 | 220 | /* perform the following exploration trialslimit times */ 221 | nochanges = notrials = 0; 222 | while ((notrials < trialslimit) && (nochanges < changeslimit)) { 223 | notrials++; 224 | 225 | /* randomly select a cell to move to a randomly selected part */ 226 | selected = select_cell(nocells, noparts, scell, pop[0].chrom, 227 | cells, pop[0].parts, cells_info); 228 | if (! selected) { 229 | printf("Error: Cannot find a move to select.\n"); 230 | exit(1); 231 | } /* if */ 232 | 233 | /* delta is the change in the cutsize based cost function */ 234 | delta = -scell[0].mov_gain; 235 | 236 | /* rdelta is the change in the ratiocut based cost function */ 237 | int from_part_size = pop[0].parts[scell[0].from_part].pcurr_size; 238 | int to_part_size = pop[0].parts[scell[0].to_part].pcurr_size; 239 | bprod = (float) (from_part_size * to_part_size); 240 | aprod = bprod + (float) cells[scell[0].from_part].cweight * 241 | (float) (from_part_size - to_part_size); 242 | rdelta = -(ratiosize * ((float) 1.0 - (bprod / aprod)) + 243 | (float) scell[0].mov_gain / aprod); 244 | 245 | /* if delta is negative, this change is a downhill move so 246 | accept the new solution */ 247 | /* if delta is positive, this change is an uphill move so 248 | accept with an ever decreasing probability that depends 249 | on delta and the current temperature */ 250 | if (((float) rdelta <= 0.0) || 251 | (((float) rdelta > 0.0) && 252 | (rand01() <= (float) exp((double) -rdelta / (double) temperature)))) { 253 | 254 | #ifdef DEBUG2 255 | printf("cell=%d from=%d to=%d gain=%d ratio=%f\n", 256 | scell[0].mov_cell_no, scell[0].from_part, 257 | scell[0].to_part, scell[0].mov_gain, rdelta); 258 | #endif 259 | 260 | nochanges++; 261 | 262 | /* move the selected cell */ 263 | move_cell(scell, pop[0].chrom, cells, pop[0].parts); 264 | 265 | /* update the costs of the neighbor cells */ 266 | update_gains(scell, cells, nets, cnets, ncells, 267 | cells_info, pop[0].chrom); 268 | cutsize += delta; 269 | ratiosize += rdelta; 270 | 271 | /* update the current champion solution */ 272 | if (ratiosize < best_ratiosize) { 273 | changed = True; 274 | best_cutsize = cutsize; 275 | best_ratiosize = ratiosize; 276 | copy_pop(nocells, noparts, pop, best_pop); 277 | copy_nets(nonets, noparts, nets, best_nets); 278 | } /* if */ 279 | 280 | } /* if the selected move is accepted */ 281 | } /* while */ 282 | 283 | #ifdef DEBUG1 284 | printf("changes=%d trials=%d accept=%f temperature=%f\n", 285 | nochanges, notrials, 286 | (100.0 * (float) nochanges / notrials), temperature); 287 | #endif 288 | 289 | /* reduce the temperature and update the other variables of SA 290 | algorithm */ 291 | temperature = tempfactor * temperature; 292 | if (changed) { 293 | freezecount = 0; 294 | } 295 | if (((float) nochanges / notrials) < minpercent) { 296 | freezecount++; 297 | } 298 | pass_no++; 299 | changed = False; 300 | 301 | float diff = ratiosize - prev_ratiosize; 302 | if (diff < 0.0) diff = -diff; 303 | if (diff <= 0.0001 * prev_ratiosize) { 304 | /* if the change is less than 1 in 10000, it is practially 305 | the same */ 306 | same++; 307 | } else { 308 | same = 0; 309 | prev_ratiosize = ratiosize; 310 | } 311 | /* if has seen the same solution enough number of times, it is 312 | time to quit */ 313 | if (same >= samecount) { 314 | freezecount = freezelimit; /* exit */ 315 | } 316 | 317 | #ifdef DEBUG1 318 | printf("pass_no = %d Final cutsize = %d Check cutsize = %d\n", 319 | pass_no, best_cutsize, 320 | find_cut_size(nonets, noparts, totnetsize, 321 | best_nets, &best_pop[0])); 322 | #endif 323 | 324 | } /* while */ 325 | 326 | #ifdef DEBUG1 327 | printf("Why : same=%d accept rate=%f\n", same, (float) nochanges / notrials); 328 | #endif 329 | 330 | printf("pass_no = %d Final cutsize = %d Check cutsize = %d\n", 331 | pass_no, best_cutsize, 332 | find_cut_size(nonets, noparts, totnetsize, best_nets, &best_pop[0])); 333 | 334 | #ifdef DEBUG1 335 | printf("Final : Part_no min_size curr_size max_size\n"); 336 | for (int i = 0; i < noparts; i++) { 337 | printf("FF %d %d %d %d\n", i, pop[0].parts[i].pmin_size, 338 | pop[0].parts[i].pcurr_size, pop[0].parts[i].pmax_size); 339 | } 340 | #endif 341 | 342 | /* free memory for all data structures */ 343 | free(cells); 344 | for (int i = 0; i < nocells; i++) { 345 | free(cells_info[i].mgain); 346 | } 347 | free(cells_info); 348 | 349 | for (int i = 0; i < nonets; i++) { 350 | free(nets[i].npartdeg); 351 | free(nets_info[i].npartdeg); 352 | free(best_nets[i].npartdeg); 353 | } 354 | free(nets); 355 | free(nets_info); 356 | free(best_nets); 357 | 358 | free(cnets); 359 | free(ncells); 360 | 361 | for (int i = 0; i < MAX_POP; i++) { 362 | free(pop[i].chrom); 363 | free(pop[i].parts); 364 | free(best_pop[i].chrom); 365 | free(best_pop[i].parts); 366 | } 367 | 368 | return (0); 369 | } /* main-sa1 */ 370 | 371 | /* EOF */ 372 | -------------------------------------------------------------------------------- /src/sa/ad_sa1.c: -------------------------------------------------------------------------------- 1 | 2 | /* COPYRIGHT C 1991- Ali Dasdan */ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "ad_defs.h" 10 | #include "ad_random.h" 11 | #include "ad_fileio.h" 12 | #include "ad_readinput.h" 13 | #include "ad_partition.h" 14 | #include "ad_lib.h" 15 | #include "ad_lib_sa.h" 16 | 17 | /* Simulated Annealing for Multiple-way Hypergraph Partitioning - 18 | based on the paper: Johnson et al., Optimization by Simulated 19 | Annealing, Operations Research, 37(6), 1989. */ 20 | 21 | int main(int argc, char *argv[]) 22 | { 23 | /* partitioning variables */ 24 | int nocells; /* number of cells */ 25 | int nonets; /* number of nets */ 26 | int nopins; /* number of pins */ 27 | int noparts; /* number of partitions */ 28 | int totcellsize; /* total cell weight of the partition */ 29 | int totnetsize; /* total net weight of the partition */ 30 | int cutsize; /* cutsize of the partition */ 31 | int max_gain; /* max gain of a cell */ 32 | int max_cdeg; /* max density of a cell */ 33 | int max_ndeg; /* max density of a net */ 34 | int max_cweight; /* max cell weight */ 35 | int max_nweight; /* max net weight */ 36 | 37 | /* SA algorithm variables */ 38 | float temperature; /* temperature in SA alg. */ 39 | float tempfactor; /* cooling ratio */ 40 | float minpercent; /* percentage of accepted moves */ 41 | float cutoff; /* a speedup option - see the paper */ 42 | int delta; /* cost difference between the last two states */ 43 | int freezelimit; /* when freezecount reaches this limit, the system is frozen */ 44 | int freezecount; 45 | int nochanges; /* number of accepted states */ 46 | int changeslimit; /* limit on max number of accepted changes */ 47 | int notrials; /* number of tried states */ 48 | int trialslimit; /* limit on max number of tried states */ 49 | int sizefactor; /* propartionality constant for temperature length */ 50 | int neigh_size; /* neighborhood size */ 51 | int selected; /* set if a feasible move is found */ 52 | int changed; /* set if a change occurs in best_cutsize */ 53 | int same; /* count the number of times cutsize remains the same */ 54 | int samecount; /* limit on the counter "same" */ 55 | int prev_cutsize; /* previous cutsize value - used with "same" */ 56 | int pass_no; /* pass number */ 57 | 58 | if (argc < 3) { 59 | printf("\nUsage: %s InputFileName NoParts [Seed]\n", argv[0]); 60 | exit(1); 61 | } /* if */ 62 | 63 | char fname[STR_SIZE]; 64 | sprintf(fname, "%s", argv[1]); 65 | 66 | noparts = atoi(argv[2]); 67 | 68 | long seed; 69 | if (argc > 3) { 70 | seed = (long) atoi(argv[3]); 71 | } else { 72 | seed = -1; 73 | } 74 | seed = randomize((long) seed); 75 | printf("SEED = %ld fname = %s\n", seed, fname); 76 | 77 | read_hgraph_size(fname, &nocells, &nonets, &nopins); 78 | 79 | /* alloc memory for all data structures */ 80 | cells_t *cells = (cells_t *) calloc(nocells, sizeof(cells_t)); 81 | assert(cells != NULL); 82 | cells_info_t *cells_info = (cells_info_t *) calloc(nocells, sizeof(cells_info_t)); 83 | assert(cells_info != NULL); 84 | for (int i = 0; i < nocells; i++) { 85 | cells_info[i].mgain = (int *) calloc(noparts, sizeof(int)); 86 | assert(cells_info[i].mgain != NULL); 87 | cells_info[i].partb_ptr = NULL; 88 | cells_info[i].partb_gain_inx = NULL; 89 | } 90 | 91 | nets_t *nets = (nets_t *) calloc(nonets, sizeof(nets_t)); 92 | assert(nets != NULL); 93 | nets_info_t *nets_info = (nets_info_t *) calloc(nonets, sizeof(nets_info_t)); 94 | assert(nets_info != NULL); 95 | for (int i = 0; i < nonets; i++) { 96 | nets[i].npartdeg = (int *) calloc(noparts, sizeof(int)); 97 | assert(nets[i].npartdeg != NULL); 98 | nets_info[i].npartdeg = (int *) calloc(noparts, sizeof(int)); 99 | assert(nets_info[i].npartdeg != NULL); 100 | } 101 | 102 | /* cells of nets */ 103 | corn_t *cnets = (corn_t *) calloc(nopins, sizeof(corn_t)); 104 | assert(cnets != NULL); 105 | /* nets of cells */ 106 | corn_t *ncells = (corn_t *) calloc(nopins, sizeof(corn_t)); 107 | assert(ncells != NULL); 108 | 109 | /* population (w/ one individual!) */ 110 | ind_t pop[MAX_POP]; 111 | for (int i = 0; i < MAX_POP; i++) { 112 | pop[i].chrom = (allele *) calloc(nocells, sizeof(allele)); 113 | assert(pop[i].chrom != NULL); 114 | pop[i].parts = (parts_t *) calloc(noparts, sizeof(parts_t)); 115 | assert(pop[i].parts != NULL); 116 | } 117 | 118 | /* selected cell */ 119 | selected_cell_t scell[1]; 120 | 121 | /* properties of the best solution */ 122 | int best_cutsize; 123 | 124 | nets_t *best_nets = (nets_t *) calloc(nonets, sizeof(nets_t)); 125 | assert(best_nets != NULL); 126 | for (int i = 0; i < nonets; i++) { 127 | best_nets[i].npartdeg = (int *) calloc(noparts, sizeof(int)); 128 | assert(best_nets[i].npartdeg != NULL); 129 | } 130 | 131 | ind_t best_pop[MAX_POP]; 132 | for (int i = 0; i < MAX_POP; i++) { 133 | best_pop[i].chrom = (allele *) calloc(nocells, sizeof(allele)); 134 | assert(best_pop[i].chrom != NULL); 135 | best_pop[i].parts = (parts_t *) calloc(noparts, sizeof(parts_t)); 136 | assert(best_pop[i].parts != NULL); 137 | } 138 | 139 | read_hgraph(fname, nocells, nonets, nopins, noparts, 140 | &totcellsize, &totnetsize, &max_cdeg, &max_ndeg, 141 | &max_cweight, &max_nweight, 142 | cells, nets, cnets, ncells); 143 | 144 | /* create the initial partition or solution */ 145 | float off_ratio = (float) 0.1; /* alpha in initial partitioning */ 146 | create_partition(nocells, noparts, totcellsize, max_cweight, &off_ratio, 147 | cells, nets, cnets, &pop[0]); 148 | 149 | #ifdef DEBUG1 150 | printf("off=%f\n", off_ratio); 151 | printf("Initial : Part_no min_size curr_size max_size\n"); 152 | for (int i = 0; i < noparts; i++) { 153 | printf("II %d %d %d %d\n", i, pop[0].parts[i].pmin_size, 154 | pop[0].parts[i].pcurr_size, pop[0].parts[i].pmax_size); 155 | } 156 | #endif 157 | 158 | max_gain = max_cdeg * max_nweight; 159 | 160 | /* find initial cutsize */ 161 | cutsize = find_cut_size(nonets, noparts, totnetsize, nets, &pop[0]); 162 | #ifdef DEBUG1 163 | printf("Totalsize = %d Initial cutsize = %d\n", totnetsize, cutsize); 164 | #endif 165 | 166 | /* compute costs (gains) of cells in hypergraph */ 167 | compute_gains(nocells, noparts, cells, nets, cnets, cells_info, pop[0].chrom); 168 | 169 | /* initialize the current champion solution */ 170 | best_cutsize = cutsize; 171 | copy_pop(nocells, noparts, pop, best_pop); 172 | copy_nets(nonets, noparts, nets, best_nets); 173 | 174 | /* initialize variables of SA algorithm */ 175 | changed = False; 176 | neigh_size = nocells * (noparts - 1); 177 | sizefactor = 16; /* 16 in paper */ 178 | minpercent = 0.02; /* 0.02 in paper */ 179 | cutoff = 1.0; /* 1.0 in paper */ 180 | temperature = 10.0; /* 0.6 - not given in paper */ 181 | tempfactor = 0.95; /* 0.95 in paper */ 182 | freezelimit = 5; /* 5 in paper */ 183 | freezecount = 0; 184 | pass_no = 0; 185 | same = 0; 186 | samecount = nocells / 2; 187 | prev_cutsize = -1; 188 | trialslimit = sizefactor * neigh_size; 189 | changeslimit = (int) (cutoff * sizefactor * neigh_size); 190 | 191 | /* while not yet frozen */ 192 | while (freezecount < freezelimit) { 193 | 194 | /* perform the following exploration trialslimit times */ 195 | nochanges = notrials = 0; 196 | while ((notrials < trialslimit) && (nochanges < changeslimit)) { 197 | notrials++; 198 | 199 | /* randomly select a cell to move to a randomly selected part */ 200 | selected = select_cell(nocells, noparts, scell, pop[0].chrom, 201 | cells, pop[0].parts, cells_info); 202 | if (! selected) { 203 | printf("Error: Cannot find a move to select.\n"); 204 | exit(1); 205 | } /* if */ 206 | 207 | /* delta is the change in the cost function */ 208 | delta = -scell[0].mov_gain; 209 | 210 | /* if delta is negative, this change is a downhill move so 211 | accept the new solution */ 212 | /* if delta is positive, this change is an uphill move so 213 | accept with an ever decreasing probability that depends 214 | on delta and the current temperature */ 215 | if (((float) delta <= 0.0) || 216 | (((float) delta > 0.0) && 217 | (rand01() <= (float) exp((double) -delta / (double) temperature)))) { 218 | 219 | #ifdef DEBUG2 220 | printf("cell=%d from=%d to=%d gain=%d\n", 221 | scell[0].mov_cell_no, scell[0].from_part, 222 | scell[0].to_part, scell[0].mov_gain); 223 | #endif 224 | 225 | nochanges++; 226 | 227 | /* move the selected cell */ 228 | move_cell(scell, pop[0].chrom, cells, pop[0].parts); 229 | 230 | /* update the costs of the neighbor cells */ 231 | update_gains(scell, cells, nets, cnets, ncells, 232 | cells_info, pop[0].chrom); 233 | cutsize += delta; 234 | 235 | /* update the current champion solution */ 236 | if (cutsize < best_cutsize) { 237 | changed = True; 238 | best_cutsize = cutsize; 239 | copy_pop(nocells, noparts, pop, best_pop); 240 | copy_nets(nonets, noparts, nets, best_nets); 241 | } /* if */ 242 | 243 | } /* if the selected move is accepted */ 244 | } /* while */ 245 | 246 | #ifdef DEBUG1 247 | printf("changes=%d trials=%d accept=%f temperature=%f\n", 248 | nochanges, notrials, 249 | (100.0 * (float) nochanges / notrials), temperature); 250 | #endif 251 | 252 | /* reduce the temperature and update the other variables of SA 253 | algorithm */ 254 | temperature = tempfactor * temperature; 255 | if (changed) { 256 | freezecount = 0; 257 | } 258 | if (((float) nochanges / notrials) < minpercent) { 259 | freezecount++; 260 | } 261 | pass_no++; 262 | changed = False; 263 | if (cutsize == prev_cutsize) { 264 | same++; 265 | } else { 266 | same = 0; 267 | prev_cutsize = cutsize; 268 | } 269 | /* if has seen the same solution enough number of times, it is 270 | time to quit */ 271 | if (same >= samecount) { 272 | freezecount = freezelimit; /* exit */ 273 | } 274 | 275 | #ifdef DEBUG1 276 | printf("pass_no = %d Final cutsize = %d Check cutsize = %d\n", 277 | pass_no, best_cutsize, 278 | find_cut_size(nonets, noparts, totnetsize, 279 | best_nets, &best_pop[0])); 280 | #endif 281 | 282 | } /* while */ 283 | 284 | #ifdef DEBUG1 285 | printf("Why : same=%d accept rate=%f\n", same, (float) nochanges / notrials); 286 | #endif 287 | 288 | printf("pass_no = %d Final cutsize = %d Check cutsize = %d\n", 289 | pass_no, best_cutsize, 290 | find_cut_size(nonets, noparts, totnetsize, best_nets, &best_pop[0])); 291 | 292 | #ifdef DEBUG1 293 | printf("Final : Part_no min_size curr_size max_size\n"); 294 | for (int i = 0; i < noparts; i++) { 295 | printf("FF %d %d %d %d\n", i, pop[0].parts[i].pmin_size, 296 | pop[0].parts[i].pcurr_size, pop[0].parts[i].pmax_size); 297 | } 298 | #endif 299 | 300 | /* free memory for all data structures */ 301 | free(cells); 302 | for (int i = 0; i < nocells; i++) { 303 | free(cells_info[i].mgain); 304 | } 305 | free(cells_info); 306 | 307 | for (int i = 0; i < nonets; i++) { 308 | free(nets[i].npartdeg); 309 | free(nets_info[i].npartdeg); 310 | free(best_nets[i].npartdeg); 311 | } 312 | free(nets); 313 | free(nets_info); 314 | free(best_nets); 315 | 316 | free(cnets); 317 | free(ncells); 318 | 319 | for (int i = 0; i < MAX_POP; i++) { 320 | free(pop[i].chrom); 321 | free(pop[i].parts); 322 | free(best_pop[i].chrom); 323 | free(best_pop[i].parts); 324 | } 325 | 326 | return (0); 327 | } /* main-sa1 */ 328 | 329 | /* EOF */ 330 | -------------------------------------------------------------------------------- /src/sa/ad_sa2.c: -------------------------------------------------------------------------------- 1 | 2 | /* COPYRIGHT C 1991- Ali Dasdan */ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "ad_defs.h" 10 | #include "ad_random.h" 11 | #include "ad_fileio.h" 12 | #include "ad_readinput.h" 13 | #include "ad_partition.h" 14 | #include "ad_lib.h" 15 | #include "ad_lib_sa.h" 16 | 17 | /* Simulated Annealing for Multiple-way Hypergraph Partitioning - 18 | based on the paper: Peterson et al., Neural networks and 19 | NP-complete problems; a performance study of the graph bisectioning 20 | problem, Complex Systems 2, 1989. */ 21 | 22 | int main(int argc, char *argv[]) 23 | { 24 | /* partitioning variables */ 25 | int nocells; /* number of cells */ 26 | int nonets; /* number of nets */ 27 | int nopins; /* number of pins */ 28 | int noparts; /* number of partitions */ 29 | int totcellsize; /* total cell weight of the partition */ 30 | int totnetsize; /* total net weight of the partition */ 31 | int cutsize; /* cutsize of the partition */ 32 | int max_gain; /* max gain of a cell */ 33 | int max_cdeg; /* max density of a cell */ 34 | int max_ndeg; /* max density of a net */ 35 | int max_cweight; /* max cell weight */ 36 | int max_nweight; /* max net weight */ 37 | 38 | /* SA algorithm variables */ 39 | float costsum; /* sum of cutsizes during a temperature length */ 40 | float cost2sum; /* sum of squares of cutsizes during a temperature length */ 41 | float percentchanges; /* percentage of accepted moves (= changes) */ 42 | float costvariance; /* variance of cutsizes (= cost) */ 43 | float temperature; /* temperature in SA alg. */ 44 | float tempfactor; /* cooling ratio */ 45 | int templength; /* number of runs until equilibrium at a certain temperature */ 46 | int nochanges; /* number of accepted states */ 47 | int notrials; /* number of tried states */ 48 | int selected; /* set if a feasible move is found */ 49 | int changed; /* set if a state is accepted */ 50 | int delta; /* cost difference between the last two states */ 51 | int nouphills; /* number of uphill moves */ 52 | int frozen; /* set if the system is frozen - after all three regions */ 53 | int region2; /* flags to identify the regions during entire run of SA */ 54 | int region3; 55 | int region4; 56 | int pass_no; /* pass number */ 57 | 58 | if (argc < 3) { 59 | printf("\nUsage: %s InputFileName NoParts [Seed]\n", argv[0]); 60 | exit(1); 61 | } /* if */ 62 | 63 | char fname[STR_SIZE]; 64 | sprintf(fname, "%s", argv[1]); 65 | 66 | noparts = atoi(argv[2]); 67 | 68 | long seed; 69 | if (argc > 3) { 70 | seed = (long) atoi(argv[3]); 71 | } else { 72 | seed = -1; 73 | } 74 | seed = randomize((long) seed); 75 | printf("SEED = %ld fname = %s\n", seed, fname); 76 | 77 | read_hgraph_size(fname, &nocells, &nonets, &nopins); 78 | 79 | /* alloc memory for all data structures */ 80 | cells_t *cells = (cells_t *) calloc(nocells, sizeof(cells_t)); 81 | assert(cells != NULL); 82 | cells_info_t *cells_info = (cells_info_t *) calloc(nocells, sizeof(cells_info_t)); 83 | assert(cells_info != NULL); 84 | for (int i = 0; i < nocells; i++) { 85 | cells_info[i].mgain = (int *) calloc(noparts, sizeof(int)); 86 | assert(cells_info[i].mgain != NULL); 87 | cells_info[i].partb_ptr = NULL; 88 | cells_info[i].partb_gain_inx = NULL; 89 | } 90 | 91 | nets_t *nets = (nets_t *) calloc(nonets, sizeof(nets_t)); 92 | assert(nets != NULL); 93 | nets_info_t *nets_info = (nets_info_t *) calloc(nonets, sizeof(nets_info_t)); 94 | assert(nets_info != NULL); 95 | for (int i = 0; i < nonets; i++) { 96 | nets[i].npartdeg = (int *) calloc(noparts, sizeof(int)); 97 | assert(nets[i].npartdeg != NULL); 98 | nets_info[i].npartdeg = (int *) calloc(noparts, sizeof(int)); 99 | assert(nets_info[i].npartdeg != NULL); 100 | } 101 | 102 | /* cells of nets */ 103 | corn_t *cnets = (corn_t *) calloc(nopins, sizeof(corn_t)); 104 | assert(cnets != NULL); 105 | /* nets of cells */ 106 | corn_t *ncells = (corn_t *) calloc(nopins, sizeof(corn_t)); 107 | assert(ncells != NULL); 108 | 109 | /* population (w/ one individual!) */ 110 | ind_t pop[MAX_POP]; 111 | for (int i = 0; i < MAX_POP; i++) { 112 | pop[i].chrom = (allele *) calloc(nocells, sizeof(allele)); 113 | assert(pop[i].chrom != NULL); 114 | pop[i].parts = (parts_t *) calloc(noparts, sizeof(parts_t)); 115 | assert(pop[i].parts != NULL); 116 | } 117 | 118 | /* selected cell */ 119 | selected_cell_t scell[1]; 120 | 121 | /* properties of the best solution */ 122 | int best_cutsize; 123 | 124 | nets_t *best_nets = (nets_t *) calloc(nonets, sizeof(nets_t)); 125 | assert(best_nets != NULL); 126 | for (int i = 0; i < nonets; i++) { 127 | best_nets[i].npartdeg = (int *) calloc(noparts, sizeof(int)); 128 | assert(best_nets[i].npartdeg != NULL); 129 | } 130 | 131 | ind_t best_pop[MAX_POP]; 132 | for (int i = 0; i < MAX_POP; i++) { 133 | best_pop[i].chrom = (allele *) calloc(nocells, sizeof(allele)); 134 | assert(best_pop[i].chrom != NULL); 135 | best_pop[i].parts = (parts_t *) calloc(noparts, sizeof(parts_t)); 136 | assert(best_pop[i].parts != NULL); 137 | } 138 | 139 | read_hgraph(fname, nocells, nonets, nopins, noparts, 140 | &totcellsize, &totnetsize, &max_cdeg, &max_ndeg, 141 | &max_cweight, &max_nweight, 142 | cells, nets, cnets, ncells); 143 | 144 | 145 | /* create the initial partition or solution */ 146 | float off_ratio = (float) 0.1; /* alpha in initial partitioning */ 147 | create_partition(nocells, noparts, totcellsize, max_cweight, &off_ratio, 148 | cells, nets, cnets, &pop[0]); 149 | 150 | #ifdef DEBUG1 151 | printf("off=%f\n", off_ratio); 152 | printf("Initial : Part_no min_size curr_size max_size\n"); 153 | for (int i = 0; i < noparts; i++) { 154 | printf("II %d %d %d %d\n", i, pop[0].parts[i].pmin_size, 155 | pop[0].parts[i].pcurr_size, pop[0].parts[i].pmax_size); 156 | } 157 | #endif 158 | 159 | max_gain = max_cdeg * max_nweight; 160 | 161 | /* find initial cutsize */ 162 | cutsize = find_cut_size(nonets, noparts, totnetsize, nets, &pop[0]); 163 | 164 | #if DEBUG 165 | printf("Totalsize = %d Initial cutsize = %d\n", totnetsize, cutsize); 166 | #endif 167 | 168 | /* compute costs (gains) of cells in hypergraph */ 169 | compute_gains(nocells, noparts, cells, nets, cnets, cells_info, pop[0].chrom); 170 | 171 | /* initialize the current champion solution */ 172 | best_cutsize = cutsize; 173 | copy_pop(nocells, noparts, pop, best_pop); 174 | copy_nets(nonets, noparts, nets, best_nets); 175 | 176 | /* initialize variables of SA algorithm */ 177 | temperature = 10.0; 178 | templength = nocells * (noparts - 1); 179 | 180 | /* the whole run has three different regions: region1 is the initialization. */ 181 | region2 = True; 182 | region3 = region4 = False; 183 | pass_no = 0; 184 | 185 | /* while not yet frozen */ 186 | frozen = False; 187 | while (! frozen) { 188 | 189 | costsum = 0.0; 190 | cost2sum = 0.0; 191 | nouphills = 0; 192 | nochanges = 0; 193 | changed = False; 194 | 195 | /* perform the following exploration templength times */ 196 | for (notrials = 0; notrials < templength; notrials++) { 197 | 198 | /* randomly select a cell to move to a randomly selected part */ 199 | selected = select_cell(nocells, noparts, scell, pop[0].chrom, 200 | cells, pop[0].parts, cells_info); 201 | if (! selected) { 202 | printf("Error: Cannot find a move to select.\n"); 203 | exit(1); 204 | } /* if */ 205 | 206 | /* delta is the change in the cost function */ 207 | delta = -scell[0].mov_gain; 208 | 209 | /* if delta is negative, this change is a downhill move so 210 | accept the new solution */ 211 | /* if delta is positive, this change is an uphill move so 212 | accept with an ever decreasing probability that depends 213 | on delta and the current temperature */ 214 | if (((float) delta <= 0.0) || 215 | (((float) delta > 0.0) && 216 | (rand01() <= (float) exp((double) -delta / (double) temperature)))) { 217 | 218 | #ifdef DEBUG2 219 | printf ("cell=%d from=%d to=%d gain=%d\n", 220 | scell[0].mov_cell_no, scell[0].from_part, 221 | scell[0].to_part, scell[0].mov_gain); 222 | #endif 223 | 224 | /* move the selected cell */ 225 | move_cell(scell, pop[0].chrom, cells, pop[0].parts); 226 | 227 | /* update the costs of the neighbor cells */ 228 | update_gains(scell, cells, nets, cnets, ncells, 229 | cells_info, pop[0].chrom); 230 | cutsize += delta; 231 | 232 | /* update the current champion solution */ 233 | if (cutsize < best_cutsize) { 234 | best_cutsize = cutsize; 235 | copy_pop(nocells, noparts, pop, best_pop); 236 | copy_nets(nonets, noparts, nets, best_nets); 237 | } 238 | 239 | /* update variables due to the change */ 240 | changed = True; 241 | nochanges++; 242 | costsum += (float) cutsize; 243 | cost2sum += (float) (cutsize * cutsize); 244 | if ((float) delta > 0.0) { 245 | nouphills++; 246 | } 247 | 248 | } /* if the selected move is accepted */ 249 | } /* for */ 250 | 251 | #ifdef DEBUG1 252 | printf("changes=%d trials=%d \% accept=%f temperature=%f\n", 253 | nochanges, notrials, 254 | (100.0 * (float) nochanges / notrials), temperature); 255 | #endif 256 | 257 | /* update variables of SA algorithm */ 258 | pass_no++; 259 | 260 | #ifdef DEBUG1 261 | printf("pass_no = %d Region=%d%d%d Final cutsize = %d Check cutsize = %d\n", 262 | pass_no, region2, region3, region4, cutsize, 263 | find_cut_size(nonets, noparts, totnetsize, best_nets, &best_pop[0])); 264 | #endif 265 | 266 | if (changed) { 267 | tempfactor = 0.95; 268 | 269 | if (region2) { /* when in region2 of the run: heating up */ 270 | costvariance = cost2sum / nochanges - 271 | ((costsum * costsum) / (nochanges * nochanges)); 272 | costvariance = costvariance / temperature; 273 | if (costvariance >= 0.05) { 274 | tempfactor = 1.25; /* = 1.0 / 0.8 */ 275 | } else { 276 | region2 = False; region3 = True; 277 | } 278 | } else if (region3) { /* when in region3 of the run: cooling */ 279 | percentchanges = (float) nochanges / templength; 280 | if (percentchanges > 0.5) { 281 | tempfactor = 0.95; 282 | } else { 283 | region3 = False; region4 = True; 284 | } 285 | } else if (region4) { /* when in region4 of the run: slow cooling */ 286 | if (nouphills > 0) { 287 | tempfactor = 0.95; 288 | templength = nocells * (noparts - 1) * (noparts - 1); 289 | } else { 290 | region4 = False; 291 | } 292 | } else { 293 | frozen = True; 294 | } 295 | 296 | /* reduce the temperature */ 297 | temperature = tempfactor * temperature; 298 | } else { 299 | printf("Warning: No change during this temperature length.\n"); 300 | exit(1); 301 | } /* else if not changed */ 302 | } /* while not frozen */ 303 | 304 | printf("pass_no = %d Final cutsize = %d Check cutsize = %d\n", 305 | pass_no, best_cutsize, 306 | find_cut_size(nonets, noparts, totnetsize, best_nets, &best_pop[0])); 307 | 308 | #ifdef DEBUG1 309 | printf("Final : Part_no min_size curr_size max_size\n"); 310 | for (int i = 0; i < noparts; i++) { 311 | printf("FF %d %d %d %d\n", i, pop[0].parts[i].pmin_size, 312 | pop[0].parts[i].pcurr_size, pop[0].parts[i].pmax_size); 313 | } 314 | #endif 315 | 316 | /* free memory for all data structures */ 317 | free(cells); 318 | for (int i = 0; i < nocells; i++) { 319 | free(cells_info[i].mgain); 320 | } 321 | free(cells_info); 322 | 323 | for (int i = 0; i < nonets; i++) { 324 | free(nets[i].npartdeg); 325 | free(nets_info[i].npartdeg); 326 | free(best_nets[i].npartdeg); 327 | } 328 | free(nets); 329 | free(nets_info); 330 | free(best_nets); 331 | 332 | free(cnets); 333 | free(ncells); 334 | 335 | for (int i = 0; i < MAX_POP; i++) { 336 | free(pop[i].chrom); 337 | free(pop[i].parts); 338 | free(best_pop[i].chrom); 339 | free(best_pop[i].parts); 340 | } 341 | 342 | return (0); 343 | } /* main-sa2 */ 344 | 345 | /* EOF */ 346 | -------------------------------------------------------------------------------- /src/sa/utest.awk: -------------------------------------------------------------------------------- 1 | # Awk program called in utest.sh 2 | { 3 | # c = current cutsize 4 | # l = target cutsize 5 | c = $7 6 | s = "program=" p ": cutsize=" c " target=" t 7 | if (c == t) { 8 | print "Passed:", s; 9 | } else { 10 | print "Failed:", s; 11 | } 12 | } 13 | 14 | # EOF 15 | -------------------------------------------------------------------------------- /src/sa/utest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # testing each executable using input/hp1 4 | 5 | ./ad_sa1.x ../../input/hp1 2 123456 | grep Final | awk -v p="ad_sa1 p1 2" -v t=1 -f utest.awk 6 | ./ad_sa2.x ../../input/hp1 2 123456 | grep Final | awk -v p="ad_sa2 p1 2" -v t=1 -f utest.awk 7 | ./ad_rsa.x ../../input/hp1 2 123456 | grep Final | awk -v p="ad_rsa p1 2" -v t=1 -f utest.awk 8 | 9 | # testing each executable using input/hp9 10 | 11 | ./ad_sa1.x ../../input/hp9 2 123456 | grep Final | awk -v p="ad_sa1 p9 2" -v t=40 -f utest.awk 12 | ./ad_sa1.x ../../input/hp9 3 123456 | grep Final | awk -v p="ad_sa1 p9 3" -v t=56 -f utest.awk 13 | ./ad_sa2.x ../../input/hp9 2 123456 | grep Final | awk -v p="ad_sa2 p9 2" -v t=70 -f utest.awk 14 | ./ad_sa2.x ../../input/hp9 3 123456 | grep Final | awk -v p="ad_sa2 p9 3" -v t=119 -f utest.awk 15 | ./ad_rsa.x ../../input/hp9 2 123456 | grep Final | awk -v p="ad_rsa p9 2" -v t=35 -f utest.awk 16 | 17 | # EOF 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/share/Makefile: -------------------------------------------------------------------------------- 1 | CC0 = gcc 2 | CC = $(CC0) 3 | LD = $(CC0) 4 | FLAGS1 = -O3 5 | FLAGS2 = -lm 6 | FLAGS3 = -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow 7 | FLAGS = $(FLAGS1) $(FLAGS3) 8 | 9 | DEPS_COMMON = ad_bucketio.h ad_fileio.h ad_lib.h ad_partition.h ad_print.h ad_random.h ad_readinput.h 10 | OBJS = $(patsubst %.h,%.o,$(DEPS_COMMON)) 11 | 12 | all: $(OBJS) 13 | 14 | ad_bucketio.o: ad_bucketio.c ad_bucketio.h ad_defs.h 15 | $(CC) $(FLAGS) -c -o $@ $< 16 | 17 | ad_fileio.o: ad_fileio.c ad_fileio.h 18 | $(CC) $(FLAGS) -c -o $@ $< 19 | 20 | ad_lib.o: ad_lib.c ad_lib.h ad_defs.h 21 | $(CC) $(FLAGS) -c -o $@ $< 22 | 23 | ad_partition.o: ad_partition.c ad_partition.h ad_defs.h ad_fileio.h ad_random.h 24 | $(CC) $(FLAGS) -c -o $@ $< 25 | 26 | ad_print.o: ad_print.c ad_print.h ad_defs.h 27 | $(CC) $(FLAGS) -c -o $@ $< 28 | 29 | ad_random.o: ad_random.c 30 | $(CC) $(FLAGS) -c -o $@ $< 31 | 32 | ad_readinput.o: ad_readinput.c ad_readinput.h ad_fileio.h ad_defs.h 33 | $(CC) $(FLAGS) -c -o $@ $< 34 | 35 | # Testing: 36 | test: 37 | ./utest.sh 38 | 39 | # Cleaning: 40 | clean c cl cle clea: 41 | rm -f *.o *~ core *.x 42 | cleano: 43 | rm -f *.o *~ core 44 | 45 | # End of file 46 | -------------------------------------------------------------------------------- /src/share/ad_bucketio.c: -------------------------------------------------------------------------------- 1 | 2 | /* COPYRIGHT C 1991- Ali Dasdan */ 3 | 4 | #include 5 | #include 6 | #include 7 | #include "ad_defs.h" 8 | #include "ad_bucketio.h" 9 | 10 | /* create a partb node */ 11 | void create_partb_node(int noparts, 12 | int mov_cell_no, 13 | int home_part, 14 | int mapped_dest_part, 15 | int mov_gain_inx, 16 | partb_t partb[][noparts - 1], 17 | cells_info_t cells_info[]) 18 | { 19 | bnode_ptr_t tnode_ptr = (bnode_ptr_t) malloc(sizeof(bnode_t)); 20 | if (tnode_ptr == NULL) { 21 | printf("Error: Cannot allocate memory for tnode_ptr.\n"); 22 | exit(1); 23 | } /* if */ 24 | tnode_ptr->cell_no = mov_cell_no; 25 | insert_partb_node(tnode_ptr, 26 | mapped_dest_part, mov_gain_inx, 27 | &partb[home_part][mapped_dest_part], 28 | &cells_info[mov_cell_no]); 29 | } /* create_partb_node */ 30 | 31 | /* insert a node into partb */ 32 | void insert_partb_node(bnode_ptr_t tnode_ptr, 33 | int mapped_dest_part, 34 | int mov_gain_inx, 35 | partb_t *partb_ptr, 36 | cells_info_t *cells_info_ptr) 37 | { 38 | /* 39 | partb_ptr = partb[home_part][mapped_dest_part] 40 | cells_info_ptr = cells_info[mov_cell_no] 41 | */ 42 | int bucket_empty = False; 43 | if (partb_ptr->bnode_ptr[mov_gain_inx] == NULL) { 44 | bucket_empty = True; 45 | } 46 | tnode_ptr->lptr = NULL; 47 | tnode_ptr->rptr = partb_ptr->bnode_ptr[mov_gain_inx]; 48 | if (! bucket_empty) { 49 | (tnode_ptr->rptr)->lptr = tnode_ptr; 50 | } 51 | partb_ptr->bnode_ptr[mov_gain_inx] = tnode_ptr; 52 | 53 | /* insert into cells_info */ 54 | cells_info_ptr->partb_ptr[mapped_dest_part] = tnode_ptr; 55 | cells_info_ptr->partb_gain_inx[mapped_dest_part] = mov_gain_inx; 56 | 57 | /* update indices */ 58 | if (partb_ptr->nobuckets == 0) { 59 | partb_ptr->max_inx = mov_gain_inx; 60 | partb_ptr->min_inx = mov_gain_inx; 61 | } else if (mov_gain_inx > partb_ptr->max_inx) { 62 | partb_ptr->max_inx = mov_gain_inx; 63 | } else if (mov_gain_inx < partb_ptr->min_inx) { 64 | partb_ptr->min_inx = mov_gain_inx; 65 | } 66 | if (bucket_empty) { 67 | partb_ptr->nobuckets++; 68 | } 69 | } /* insert_partb_node */ 70 | 71 | /* delete all nodes of a cell from partb */ 72 | void delete_partb_nodes_of_cell(int noparts, 73 | int mov_cell_no, 74 | int home_part, 75 | partb_t partb[][noparts - 1], 76 | cells_info_t cells_info[]) 77 | { 78 | for (int mapped_dest_part = 0; mapped_dest_part < (noparts - 1); mapped_dest_part++) { 79 | delete_partb_node(True, mapped_dest_part, 80 | &partb[home_part][mapped_dest_part], 81 | &cells_info[mov_cell_no]); 82 | } 83 | } /* delete_partb_nodes_of_cell */ 84 | 85 | /* delete a partb node */ 86 | bnode_ptr_t delete_partb_node(int deletion_ok, 87 | int mapped_dest_part, 88 | partb_t *partb_ptr, 89 | cells_info_t *cells_info_ptr) 90 | { 91 | /* 92 | cells_info_ptr = cells_info[mov_cell_no] 93 | partb_ptr = partb[home_part][mapped_dest_part] 94 | */ 95 | bnode_ptr_t tnode_ptr = cells_info_ptr->partb_ptr[mapped_dest_part]; 96 | int mov_gain_inx = cells_info_ptr->partb_gain_inx[mapped_dest_part]; 97 | if (tnode_ptr != NULL) { 98 | if (tnode_ptr->lptr == NULL) { /* if 1st node */ 99 | if (tnode_ptr->rptr != NULL) { /* make next node the 1st node */ 100 | (tnode_ptr->rptr)->lptr = NULL; 101 | } 102 | partb_ptr->bnode_ptr[mov_gain_inx] = tnode_ptr->rptr; 103 | if (partb_ptr->bnode_ptr[mov_gain_inx] == NULL) { 104 | partb_ptr->nobuckets--; 105 | if (partb_ptr->nobuckets == 0) { /* if no more full buckets */ 106 | partb_ptr->max_inx = -1; 107 | partb_ptr->min_inx = -1; 108 | } else { /* set max_inx to the next full bucket index */ 109 | while ((partb_ptr->max_inx > partb_ptr->min_inx) && 110 | (partb_ptr->bnode_ptr[partb_ptr->max_inx] == NULL)) { 111 | partb_ptr->max_inx--; 112 | } /* while */ 113 | } /* else */ 114 | } /* if bucket is empty */ 115 | } else { 116 | (tnode_ptr->lptr)->rptr = tnode_ptr->rptr; 117 | if (tnode_ptr->rptr != NULL) { 118 | (tnode_ptr->rptr)->lptr = tnode_ptr->lptr; 119 | } 120 | } /* else */ 121 | 122 | if (deletion_ok) { 123 | free(tnode_ptr); 124 | cells_info_ptr->partb_ptr[mapped_dest_part] = NULL; 125 | } /* if */ 126 | } /* if tnode_ptr is not nil */ 127 | 128 | return (tnode_ptr); 129 | } /* delete_partb_node */ 130 | 131 | /* EOF */ 132 | -------------------------------------------------------------------------------- /src/share/ad_bucketio.h: -------------------------------------------------------------------------------- 1 | #ifndef AD_BUCKETIO_INCLUDED 2 | #define AD_BUCKETIO_INCLUDED 3 | 4 | /* COPYRIGHT C 1991- Ali Dasdan */ 5 | 6 | /* create a partb node */ 7 | void create_partb_node(int noparts, 8 | int mov_cell_no, 9 | int home_part, 10 | int mapped_dest_part, 11 | int mov_gain_inx, 12 | partb_t partb[][noparts - 1], 13 | cells_info_t cells_info[]); 14 | 15 | /* insert a node into partb */ 16 | void insert_partb_node(bnode_ptr_t tnode_ptr, 17 | int mapped_dest_part, 18 | int mov_gain_inx, 19 | partb_t *partb_ptr, 20 | cells_info_t *cells_info_ptr); 21 | 22 | /* delete all nodes of a cell from partb */ 23 | void delete_partb_nodes_of_cell(int noparts, 24 | int mov_cell_no, 25 | int home_part, 26 | partb_t partb[][noparts - 1], 27 | cells_info_t cells_info[]); 28 | 29 | /* delete a partb node */ 30 | bnode_ptr_t delete_partb_node(int deletion_ok, 31 | int mapped_dest_part, 32 | partb_t *partb_ptr, 33 | cells_info_t *cells_info_ptr); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/share/ad_defs.h: -------------------------------------------------------------------------------- 1 | #ifndef AD_DEFS_INCLUDED 2 | #define AD_DEFS_INCLUDED 3 | 4 | /* COPYRIGHT C 1991- Ali Dasdan */ 5 | 6 | /* naming conventions : 7 | cell = node, net = edge, 8 | */ 9 | 10 | #define True 1 /* boolean true */ 11 | #define False 0 /* boolean false */ 12 | 13 | #define MAX_POP 1 /* max numbr of individuals in population */ 14 | #define NIL -1 /* point to nowhere */ 15 | #define STR_SIZE 30 /* string size */ 16 | #define NO_ITERATIONS 200 /* max number of iterations for KL */ 17 | #define EPSILON 0.01 /* min move value of a cell */ 18 | 19 | /* cells type */ 20 | typedef struct cells_st { 21 | int cno_nets; /* total number of nets on the cell */ 22 | int cno_inets; /* number of internal nets */ 23 | int cweight; /* weight of cell */ 24 | int netlist; /* pointer to nets on the cell */ 25 | } cells_t; 26 | 27 | /* nets type */ 28 | typedef struct nets_st { 29 | int nno_cells; /* total number of cells on the net */ 30 | int nweight; /* weight of node */ 31 | int celllist; /* pointer to cells on the net */ 32 | int *npartdeg; /* #cells of the net in each part */ 33 | } nets_t; 34 | 35 | /* nets info type */ 36 | typedef struct nets_info_st { 37 | int *npartdeg; /* #cells of the net in each part */ 38 | } nets_info_t; 39 | 40 | /* cell cornlist type - CorN = Cell or Net */ 41 | typedef struct corn_st { 42 | int corn_no; /* cell or net number */ 43 | } corn_t; 44 | 45 | /* allele definition - for compatibility purposes */ 46 | typedef int allele; 47 | 48 | /* partition type */ 49 | typedef struct parts_st { 50 | int pmax_cells; /* maximum number of cells in partition */ 51 | int pmax_size; /* maximum size of part */ 52 | int pmin_size; /* minimum size of part */ 53 | int pcurr_size; /* current size of part */ 54 | float pratio; /* pmax_size / totsize */ 55 | } parts_t; 56 | 57 | /* individual type */ 58 | typedef struct pop_st { 59 | allele *chrom; /* string holding partitions */ 60 | parts_t *parts; /* partition array */ 61 | int incost; /* sum of net weights - cut cost */ 62 | } ind_t; 63 | 64 | /* temporary partition type */ 65 | typedef struct tparts_st { /* used while creating partition celllists */ 66 | char filled; /* set if partition is filled with cells */ 67 | int pcells_inx; /* an index to pcells */ 68 | } tparts_t; 69 | 70 | /* bucket nodes (= bnode) */ 71 | typedef struct bnode_st *bnode_ptr_t; 72 | 73 | typedef struct bnode_st { 74 | int cell_no; /* cell in the node */ 75 | bnode_ptr_t lptr; /* pointer to left node */ 76 | bnode_ptr_t rptr; /* pointer to right node */ 77 | } bnode_t; 78 | 79 | /* partition bucket (partb) type */ 80 | typedef struct partb_st { 81 | bnode_ptr_t *bnode_ptr; 82 | int max_inx; /* max index of filled bucket cell */ 83 | int min_inx; /* min index of filled bucket cell */ 84 | int nobuckets; /* number of filled buckets */ 85 | } partb_t; 86 | 87 | /* additional information for cells */ 88 | typedef struct cells_info_st { 89 | int mcount; /* count of moves that cell performs */ 90 | int locked; /* set if cell is locked */ 91 | int *mgain; /* external costs of moving cell_no to all parts */ 92 | /* only mgain[part_no of cell_no] is internal cost */ 93 | bnode_ptr_t *partb_ptr; /* pointer to partb node */ 94 | int *partb_gain_inx; /* index to partb bucket */ 95 | /* pointers to part_bucket */ 96 | } cells_info_t; 97 | 98 | /* selected cell structure */ 99 | typedef struct selected_cell_st { 100 | int mov_cell_no; /* current properties */ 101 | int from_part; 102 | int to_part; 103 | int mov_gain; 104 | } selected_cell_t; 105 | 106 | /* moved cells array */ 107 | typedef struct mcells_st { 108 | int cell_no; /* the cell moved */ 109 | int from; /* cell's home partition */ 110 | int to; /* cell's destination partition */ 111 | int mgain; /* move gain */ 112 | } mcells_t; 113 | 114 | /* partition information type */ 115 | typedef struct parts_info_st { 116 | int pmax_cells; /* maximum number of cells in partition */ 117 | int pmax_size; /* maximum size of part */ 118 | int pmin_size; /* minimum size of part */ 119 | int pcurr_size; /* current size of part */ 120 | } parts_info_t; 121 | 122 | /* precomputed exponential values */ 123 | typedef struct eval_st { 124 | float val; 125 | } eval_t; 126 | 127 | #endif 128 | -------------------------------------------------------------------------------- /src/share/ad_fileio.c: -------------------------------------------------------------------------------- 1 | 2 | /* COPYRIGHT C 1991- Ali Dasdan */ 3 | 4 | #include 5 | #include 6 | #include 7 | #include "ad_fileio.h" 8 | 9 | /* open file fp with filename = fname and mode = mode */ 10 | void open_file(FILE **fp, 11 | char *fname, 12 | char *mode) 13 | { 14 | if ((*fp = fopen(fname, mode)) == NULL) { 15 | printf("Error: File %s can NOT be opened with mode %s: errno= %d error= %s\n", 16 | fname, mode, errno, strerror(errno)); 17 | exit(1); 18 | } 19 | } /* open_file */ 20 | 21 | /* close file fp */ 22 | void close_file(FILE **fp) 23 | { 24 | if (fclose(*fp) != 0) { 25 | printf("Error: Cannot close file: errno= %d error= %s\n", errno, strerror(errno)); 26 | exit(1); 27 | } 28 | } /* close_file */ 29 | 30 | /* EOF */ 31 | -------------------------------------------------------------------------------- /src/share/ad_fileio.h: -------------------------------------------------------------------------------- 1 | #ifndef AD_FILEIO_INCLUDED 2 | #define AD_FILEIO_INCLUDED 3 | 4 | /* COPYRIGHT C 1991- Ali Dasdan */ 5 | 6 | #include 7 | 8 | /* open file fp with filename = fname and mode = mode */ 9 | void open_file(FILE **fp, 10 | char *fname, 11 | char *mode); 12 | 13 | /* close file fp */ 14 | void close_file(FILE **fp); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/share/ad_lib.c: -------------------------------------------------------------------------------- 1 | 2 | /* COPYRIGHT C 1991- Ali Dasdan */ 3 | 4 | #include 5 | #include 6 | #include "ad_defs.h" 7 | #include "ad_lib.h" 8 | 9 | /* initialize all bucket indices and pointers */ 10 | void init_buckets(int noparts, 11 | int bucketsize, 12 | partb_t partb[][noparts - 1]) 13 | { 14 | /* init partition bucket indices */ 15 | for (int i = 0; i < noparts; i++) { 16 | for (int j = 0; j < (noparts - 1); j++) { 17 | 18 | partb[i][j].max_inx = partb[i][j].min_inx = -1; 19 | partb[i][j].nobuckets = 0; 20 | 21 | /* init partb bucket pointers */ 22 | for (int k = 0; k < bucketsize; k++) { 23 | partb[i][j].bnode_ptr[k] = NULL; 24 | } 25 | 26 | } /* for j */ 27 | } /* for i */ 28 | } /* init_buckets */ 29 | 30 | /* map part no such that home_part is excluded */ 31 | int map_part_no(int dest_part, int home_part) 32 | { 33 | if (dest_part < home_part) { 34 | return (dest_part); 35 | } else if (dest_part > home_part) { 36 | return (dest_part - 1); 37 | } else { 38 | printf("Error: Unexpected inputs\n"); 39 | exit(1); 40 | } 41 | } /* map_part_no */ 42 | 43 | /* compute move gain from home_part to dest_part */ 44 | int calculate_gain(int cell_no, 45 | int home_part, 46 | int dest_part, 47 | cells_info_t cells_info[]) 48 | { 49 | int mov_gain = cells_info[cell_no].mgain[dest_part] - 50 | cells_info[cell_no].mgain[home_part]; 51 | return mov_gain; 52 | } /* calculate_gain */ 53 | 54 | /* compute gains of all cells and place them into cells_info */ 55 | void compute_gains(int nocells, 56 | int noparts, 57 | cells_t cells[], 58 | nets_t nets[], 59 | corn_t cnets[], 60 | cells_info_t cells_info[], 61 | allele tchrom[]) 62 | { 63 | for (int cell_no = 0; cell_no < nocells; cell_no++) { 64 | 65 | /* initialize cells_info */ 66 | cells_info[cell_no].locked = False; 67 | cells_info[cell_no].mcount = 0; 68 | 69 | /* find info about the cell */ 70 | int net_ptr = cells[cell_no].netlist; 71 | cells[cell_no].cno_inets = 0; 72 | 73 | /* initialize external & internal costs */ 74 | for (int j = 0; j < noparts; j++) { 75 | cells_info[cell_no].mgain[j] = 0; 76 | } 77 | int part_no = tchrom[cell_no]; 78 | 79 | /* for each net on the cell cell_no */ 80 | for (int j = 0; j < cells[cell_no].cno_nets; j++) { 81 | 82 | int net_no = cnets[net_ptr].corn_no; 83 | int net_weight = nets[net_no].nweight; 84 | 85 | /* if only one cell in part_no */ 86 | /* else if all cells in part_no */ 87 | if (nets[net_no].npartdeg[part_no] == 1) { 88 | 89 | /* find the part in which all other cells of net lie */ 90 | int found = False; 91 | int tpart_no = 0; 92 | while ((tpart_no < noparts) && (!found)) { 93 | if ((tpart_no != part_no) && 94 | (nets[net_no].npartdeg[tpart_no] == (nets[net_no].nno_cells - 1))) { 95 | found = True; 96 | cells_info[cell_no].mgain[tpart_no] += net_weight; 97 | } /* if tpart_no */ 98 | tpart_no++; 99 | } /* while */ 100 | 101 | } else if (nets[net_no].npartdeg[part_no] == nets[net_no].nno_cells) { 102 | /* update internal cost */ 103 | cells_info[cell_no].mgain[part_no] += net_weight; 104 | } /* else */ 105 | net_ptr++; 106 | 107 | } /* for all nets j on cell cell_no */ 108 | 109 | } /* for all cells cell_no */ 110 | } /* compute_gains */ 111 | 112 | /* compute gains of all cells and place them into cells_info */ 113 | void compute_gains2(int nocells, 114 | int noparts, 115 | cells_t cells[], 116 | nets_t nets[], 117 | corn_t cnets[], 118 | cells_info_t cells_info[], 119 | allele tchrom[], 120 | nets_info_t nets_info[]) 121 | { 122 | for (int cell_no = 0; cell_no < nocells; cell_no++) { 123 | 124 | /* initialize cells_info */ 125 | cells_info[cell_no].locked = False; 126 | cells_info[cell_no].mcount = 0; 127 | 128 | /* find info about the cell */ 129 | cells[cell_no].cno_inets = 0; 130 | int net_ptr = cells[cell_no].netlist; 131 | 132 | /* initialize external & internal costs */ 133 | for (int j = 0; j < noparts; j++) { 134 | cells_info[cell_no].mgain[j] = 0; 135 | } 136 | int part_no = tchrom[cell_no]; 137 | 138 | /* for each net on cell_no */ 139 | for (int j = 0; j < cells[cell_no].cno_nets; j++) { 140 | 141 | int net_no = cnets[net_ptr].corn_no; 142 | int net_weight = nets[net_no].nweight; 143 | 144 | /* if only one cell in part_no */ 145 | /* else if all cells in part_no */ 146 | if (nets_info[net_no].npartdeg[part_no] == 1) { 147 | 148 | /* find the part in which all other cells of net lie */ 149 | int found = False; 150 | int tpart_no = 0; 151 | while ((tpart_no < noparts) && (!found)) { 152 | if ((tpart_no != part_no) && 153 | (nets_info[net_no].npartdeg[tpart_no] == 154 | (nets[net_no].nno_cells - 1))) { 155 | found = True; 156 | cells_info[cell_no].mgain[tpart_no] += net_weight; 157 | } /* if tpart_no */ 158 | tpart_no++; 159 | } /* while */ 160 | 161 | } else if (nets_info[net_no].npartdeg[part_no] == nets[net_no].nno_cells) { 162 | /* update internal cost */ 163 | cells_info[cell_no].mgain[part_no] += net_weight; 164 | } /* else */ 165 | net_ptr++; 166 | 167 | } /* for all nets j on cell cell_no */ 168 | 169 | } /* for all cells cell_no */ 170 | } /* compute_gains2 */ 171 | 172 | /* free all allocated nodes */ 173 | void free_nodes(int noparts, 174 | int bucketsize, 175 | partb_t partb[][noparts - 1]) 176 | { 177 | /* delete nodes connected to partb */ 178 | for (int i = 0; i < noparts; i++) { 179 | for (int j = 0; j < (noparts - 1); j++) { 180 | 181 | for (int k = 0; k < bucketsize; k++) { 182 | bnode_ptr_t next = partb[i][j].bnode_ptr[k]; 183 | partb[i][j].bnode_ptr[k] = NULL; 184 | while (next != NULL) { 185 | bnode_ptr_t prev = next; 186 | next = next->rptr; 187 | free(prev); 188 | } /* while */ 189 | } /* for k */ 190 | 191 | partb[i][j].max_inx = -1; 192 | partb[i][j].min_inx = -1; 193 | partb[i][j].nobuckets = 0; 194 | } /* for j */ 195 | } /* for i */ 196 | } /* free_nodes */ 197 | 198 | /* count number of bucket nodes */ 199 | void number_nodes(int noparts, 200 | int bucketsize, 201 | int *npartb, 202 | partb_t partb[][noparts - 1]) 203 | { 204 | *npartb = 0; 205 | 206 | /* count nodes connected to partb */ 207 | for (int i = 0; i < noparts; i++) { 208 | for (int j = 0; j < (noparts - 1); j++) { 209 | for (int k = 0; k < bucketsize; k++) { 210 | bnode_ptr_t next = partb[i][j].bnode_ptr[k]; 211 | while (next != NULL) { 212 | next = next->rptr; 213 | (*npartb)++; 214 | } /* while */ 215 | } /* for k */ 216 | } /* for j */ 217 | } /* for i */ 218 | } /* number_nodes */ 219 | 220 | /* find set of cells to be actually moved */ 221 | int find_move_set(mcells_t mcells[], 222 | int msize, 223 | int *max_mcells_inx) 224 | { 225 | int max_gain_sum = 0; 226 | *max_mcells_inx = -1; 227 | int gain_sum = 0; 228 | for (int i = 0; i < msize; i++) { 229 | gain_sum += mcells[i].mgain; 230 | if (gain_sum > max_gain_sum) { 231 | *max_mcells_inx = i; 232 | max_gain_sum = gain_sum; 233 | } /* if */ 234 | } /* for i */ 235 | 236 | return max_gain_sum; 237 | } /* find_move_set */ 238 | 239 | /* move cells actually - permanently */ 240 | int move_cells(int wflag, 241 | int nocells, 242 | int msize, 243 | mcells_t mcells[], 244 | int max_mcells_inx, 245 | int cutsize, 246 | int *glob_inx, 247 | ind_t *ind, 248 | cells_t cells[], 249 | nets_t nets[], 250 | corn_t cnets[]) 251 | { 252 | /* used only under wflag == True */ 253 | int tcutsize, fcutsize; 254 | tcutsize = fcutsize = cutsize; 255 | 256 | if (wflag == True) { 257 | if ((*glob_inx) == 0) { 258 | printf("%d %d %d\n", *glob_inx, tcutsize, fcutsize); 259 | (*glob_inx)++; 260 | } /* if */ 261 | } /* if */ 262 | 263 | int cut_gain = 0; 264 | for (int i = 0; i <= max_mcells_inx; i++) { 265 | 266 | if (wflag == True) { 267 | tcutsize -= mcells[i].mgain; 268 | fcutsize = tcutsize; 269 | printf("%d %d %d\n", *glob_inx, tcutsize, fcutsize); 270 | (*glob_inx)++; 271 | } /* if wflag */ 272 | 273 | ind->chrom[mcells[i].cell_no] = mcells[i].to; 274 | cut_gain += mcells[i].mgain; 275 | 276 | /* update partition size limits */ 277 | ind->parts[mcells[i].from].pmax_cells--; 278 | ind->parts[mcells[i].from].pcurr_size -= cells[mcells[i].cell_no].cweight; 279 | ind->parts[mcells[i].to].pmax_cells++; 280 | ind->parts[mcells[i].to].pcurr_size += cells[mcells[i].cell_no].cweight; 281 | 282 | /* find the nets on the cell moved and update its npartdeg */ 283 | int cnets_inx = cells[mcells[i].cell_no].netlist; 284 | for (int j = 0; j < cells[mcells[i].cell_no].cno_nets; j++) { 285 | int net_no = cnets[cnets_inx + j].corn_no; 286 | nets[net_no].npartdeg[mcells[i].from]--; 287 | nets[net_no].npartdeg[mcells[i].to]++; 288 | } /* for j */ 289 | 290 | } /* for i */ 291 | 292 | for (int i = max_mcells_inx + 1; i < msize; i++) { 293 | if (wflag == True) { 294 | tcutsize -= mcells[i].mgain; 295 | printf("%d %d %d\n", *glob_inx, tcutsize, fcutsize); 296 | (*glob_inx)++; 297 | } /* if wflag */ 298 | } /* for i */ 299 | 300 | for (int i = msize; i < nocells; i++) { 301 | if (wflag == True) { 302 | printf("%d %d %d\n", *glob_inx, fcutsize, fcutsize); 303 | (*glob_inx)++; 304 | } /* if wflag */ 305 | } /* for i */ 306 | 307 | return cut_gain; 308 | } /* move_cells */ 309 | 310 | /* finds cut size of a given partition - used for control */ 311 | int find_cut_size(int nonets, 312 | int noparts, 313 | int totnetsize, 314 | nets_t nets[], 315 | ind_t *ind) 316 | { 317 | ind->incost = 0; 318 | for (int i = 0; i < nonets; i++) { 319 | 320 | int found = False; 321 | int j = 0; 322 | while ((j < noparts) && (!found)) { 323 | if (nets[i].npartdeg[j] == nets[i].nno_cells) { 324 | found = True; 325 | } 326 | j++; 327 | } /* while */ 328 | if (found) { 329 | ind->incost += nets[i].nweight; 330 | } 331 | } /* for i */ 332 | 333 | return (totnetsize - ind->incost); 334 | } /* find_cut_size */ 335 | 336 | /* save nets info in nets_info */ 337 | void copy_nets_info(int nonets, 338 | int noparts, 339 | nets_t nets[], 340 | nets_info_t nets_info[]) 341 | { 342 | for (int i = 0; i < nonets; i++) { 343 | for (int j = 0; j < noparts; j++) { 344 | nets_info[i].npartdeg[j] = nets[i].npartdeg[j]; 345 | } /* for j */ 346 | } /* for i */ 347 | } /* copy_nets_info */ 348 | 349 | /* EOF */ 350 | -------------------------------------------------------------------------------- /src/share/ad_lib.h: -------------------------------------------------------------------------------- 1 | #ifndef AD_LIB_INCLUDED 2 | #define AD_LIB_INCLUDED 3 | 4 | /* COPYRIGHT C 1991- Ali Dasdan */ 5 | 6 | /* initialize all bucket indices and pointers */ 7 | void init_buckets(int noparts, 8 | int bucketsize, 9 | partb_t partb[][noparts - 1]); 10 | 11 | /* map part no such that home_part is excluded */ 12 | int map_part_no(int dest_part, int home_part); 13 | 14 | /* compute move gain from home_part to dest_part */ 15 | int calculate_gain(int cell_no, 16 | int home_part, 17 | int dest_part, 18 | cells_info_t cells_info[]); 19 | 20 | /* compute gains of all cells and place them into cells_info */ 21 | void compute_gains(int nocells, 22 | int noparts, 23 | cells_t cells[], 24 | nets_t nets[], 25 | corn_t cnets[], 26 | cells_info_t cells_info[], 27 | allele tchrom[]); 28 | 29 | /* compute gains of all cells and place them into cells_info */ 30 | void compute_gains2(int nocells, 31 | int noparts, 32 | cells_t cells[], 33 | nets_t nets[], 34 | corn_t cnets[], 35 | cells_info_t cells_info[], 36 | allele tchrom[], 37 | nets_info_t nets_info[]); 38 | 39 | /* free all allocated nodes */ 40 | void free_nodes(int noparts, 41 | int bucketsize, 42 | partb_t partb[][noparts - 1]); 43 | 44 | /* count number of bucket nodes */ 45 | void number_nodes(int noparts, 46 | int bucketsize, 47 | int *npartb, 48 | partb_t partb[][noparts - 1]); 49 | 50 | /* find set of cells to be actually moved */ 51 | int find_move_set(mcells_t mcells[], 52 | int msize, 53 | int *max_mcells_inx); 54 | 55 | /* move cells actually - permanently */ 56 | int move_cells(int wflag, 57 | int nocells, 58 | int msize, 59 | mcells_t mcells[], 60 | int max_mcells_inx, 61 | int cutsize, 62 | int *glob_inx, 63 | ind_t *ind, 64 | cells_t cells[], 65 | nets_t nets[], 66 | corn_t cnets[]); 67 | 68 | /* finds cut size of a given partition - used for control */ 69 | int find_cut_size(int nonets, 70 | int noparts, 71 | int totnetsize, 72 | nets_t nets[], 73 | ind_t *ind); 74 | 75 | /* save nets info in nets_info */ 76 | void copy_nets_info(int nonets, 77 | int noparts, 78 | nets_t nets[], 79 | nets_info_t nets_info[]); 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /src/share/ad_partition.c: -------------------------------------------------------------------------------- 1 | 2 | /* COPYRIGHT C 1991- Ali Dasdan */ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "ad_random.h" 9 | #include "ad_fileio.h" 10 | #include "ad_defs.h" 11 | #include "ad_partition.h" 12 | 13 | /* create initial partition */ 14 | int create_partition(int nocells, 15 | int noparts, 16 | int totcellsize, 17 | int max_cweight, 18 | float *off_ratio, 19 | cells_t cells[], 20 | nets_t nets[], 21 | corn_t cnets[], 22 | ind_t *ind) 23 | { 24 | /* init current size */ 25 | for (int i = 0; i < noparts; i++) { 26 | ind->parts[i].pratio = 1.0 / noparts; 27 | ind->parts[i].pcurr_size = 0; 28 | ind->parts[i].pmax_cells = 0; 29 | } /* for i */ 30 | 31 | /* allocate temporary memory */ 32 | int *tparts = (int *) calloc(noparts, sizeof(int)); 33 | if (tparts == NULL) { 34 | printf("Error: Unable to allocate memory for tparts.\n"); 35 | exit(1); 36 | } /* if */ 37 | 38 | /* insert cells */ 39 | for (int i = 0; i < nocells; i++) { 40 | 41 | /* find minimum */ 42 | int min_inx = 0; 43 | int min_size = ind->parts[0].pcurr_size; 44 | for (int j = 1; j < noparts; j++) { 45 | if (min_size > ind->parts[j].pcurr_size) { 46 | min_inx = j; 47 | min_size = ind->parts[j].pcurr_size; 48 | } /* if */ 49 | } /* for j */ 50 | 51 | /* find a new minimum among the same minimums */ 52 | int tcount = -1; /* tparts is used to randomize partitioning */ 53 | for (int j = 0; j < noparts; j++) { 54 | if (ind->parts[j].pcurr_size == min_size) { 55 | tcount++; 56 | tparts[tcount] = j; 57 | } /* if */ 58 | } /* for j */ 59 | min_inx = tparts[irandom(0, tcount)]; 60 | 61 | /* assign cell i to part[min_inx] */ 62 | ind->chrom[i] = min_inx; 63 | ind->parts[min_inx].pcurr_size += cells[i].cweight; 64 | ind->parts[min_inx].pmax_cells++; 65 | 66 | /* find net info */ 67 | int cnets_inx = cells[i].netlist; 68 | for (int j = 0; j < cells[i].cno_nets; j++) { 69 | int net_no = cnets[cnets_inx + j].corn_no; 70 | nets[net_no].npartdeg[min_inx]++; 71 | } /* for j */ 72 | 73 | } /* for i */ 74 | 75 | free(tparts); 76 | 77 | /* determine min & max part sizes */ 78 | /* also adjust the min & max part sizes */ 79 | int part_fit = True; 80 | int max_size = -1; 81 | while (((*off_ratio) < 1.05) && (part_fit)) { 82 | 83 | for (int i = 0; i < noparts; i++) { 84 | float part_size = ((float) totcellsize) * ind->parts[i].pratio; 85 | if (part_size < max_cweight) { 86 | printf("\nError: Too small part size.\n"); 87 | exit(1); 88 | } /* if */ 89 | ind->parts[i].pmax_size = (int) (part_size * (1.0 + (*off_ratio)) + 1.0); 90 | ind->parts[i].pmin_size = (int) (part_size * (1.0 - (*off_ratio)) - 1.0); 91 | if (ind->parts[i].pmax_size > max_size) { 92 | max_size = ind->parts[i].pmax_size; 93 | } 94 | } /* for i */ 95 | 96 | int i = 0; 97 | while ((i < noparts) && (part_fit)) { 98 | if (ind->parts[i].pmax_size < ind->parts[i].pcurr_size) 99 | part_fit = False; 100 | i++; 101 | } /* while */ 102 | 103 | if (part_fit) { 104 | part_fit = False; 105 | } else { 106 | part_fit = True; 107 | (*off_ratio) += 0.05; 108 | if ((*off_ratio) > 1.0) { 109 | printf("\nError: Cannot adjust part sizes.\n"); 110 | exit(1); 111 | } /* if */ 112 | } /* if not fit */ 113 | 114 | } /* while */ 115 | 116 | return max_size; 117 | } /* create_partition */ 118 | 119 | /* copy partition properties to parts_info for temporary use */ 120 | void copy_partition(int noparts, 121 | parts_info_t parts_info[], 122 | ind_t *ind) 123 | { 124 | for (int i = 0; i < noparts; i++) { 125 | parts_info[i].pmax_cells = ind->parts[i].pmax_cells; 126 | parts_info[i].pmin_size = ind->parts[i].pmin_size; 127 | parts_info[i].pcurr_size = ind->parts[i].pcurr_size; 128 | parts_info[i].pmax_size = ind->parts[i].pmax_size; 129 | } /* for i */ 130 | } /* copy_partition */ 131 | 132 | /* read a partition prepared beforehand */ 133 | int read_partition(FILE *fp, 134 | char *filename, 135 | int noparts, 136 | cells_t cells[], 137 | nets_t nets[], 138 | corn_t cnets[], 139 | ind_t *ind) 140 | { 141 | int max_size = -1; 142 | open_file(&fp, filename, "r"); 143 | 144 | for (int i = 0; i < noparts; i++) { 145 | 146 | int part_no; 147 | if (fscanf(fp, "%d", &part_no) == EOF) { 148 | printf("Error: Cannot read from %s: errno= %d error= %s\n", filename, errno, strerror(errno)); 149 | } 150 | 151 | if (fscanf(fp, "%d%d%d%d", 152 | &(ind->parts[part_no].pmax_cells), 153 | &(ind->parts[part_no].pmin_size), 154 | &(ind->parts[part_no].pcurr_size), 155 | &(ind->parts[part_no].pmax_size)) == EOF) { 156 | printf("Error: Cannot read from %s: errno= %d error= %s\n", filename, errno, strerror(errno)); 157 | } 158 | 159 | if (ind->parts[part_no].pmax_size > max_size) 160 | max_size = ind->parts[part_no].pmax_size; 161 | 162 | for (int j = 0; j < ind->parts[part_no].pmax_cells; j++) { 163 | 164 | int cell_no; 165 | if (fscanf(fp, "%d", &cell_no) == EOF) { 166 | printf("Error: Cannot read from %s: errno= %d error= %s\n", filename, errno, strerror(errno)); 167 | } 168 | ind->chrom[cell_no] = part_no; 169 | 170 | /* find net info */ 171 | int cnets_inx = cells[cell_no].netlist; 172 | for (int k = 0; k < cells[cell_no].cno_nets; k++) { 173 | int net_no = cnets[cnets_inx + k].corn_no; 174 | nets[net_no].npartdeg[part_no]++; 175 | } /* for k */ 176 | 177 | } /* for j */ 178 | 179 | } /* for i */ 180 | 181 | close_file(&fp); 182 | 183 | return max_size; 184 | } /* read_partition */ 185 | 186 | /* write a partition */ 187 | void write_partition(FILE *fp, 188 | char *filename, 189 | int nocells, 190 | int noparts, 191 | ind_t *ind) 192 | { 193 | open_file(&fp, filename, "w"); 194 | 195 | for (int i = 0; i < noparts; i++) { 196 | fprintf(fp, "%d %d %d %d %d\n", i, 197 | ind->parts[i].pmax_cells, 198 | ind->parts[i].pmin_size, 199 | ind->parts[i].pcurr_size, 200 | ind->parts[i].pmax_size); 201 | for (int j = 0; j < nocells; j++) 202 | if (ind->chrom[j] == i) 203 | fprintf(fp, "%d ", j); 204 | fprintf(fp, "\n"); 205 | } /* for i */ 206 | 207 | close_file(&fp); 208 | } /* read_partition */ 209 | 210 | /* EOF */ 211 | -------------------------------------------------------------------------------- /src/share/ad_partition.h: -------------------------------------------------------------------------------- 1 | #ifndef AD_PARTITION_INCLUDED 2 | #define AD_PARTITION_INCLUDED 3 | 4 | /* COPYRIGHT C 1991- Ali Dasdan */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "ad_random.h" 11 | #include "ad_fileio.h" 12 | #include "ad_defs.h" 13 | #include "ad_partition.h" 14 | 15 | /* create initial partition */ 16 | int create_partition(int nocells, 17 | int noparts, 18 | int totcellsize, 19 | int max_cweight, 20 | float *off_ratio, 21 | cells_t cells[], 22 | nets_t nets[], 23 | corn_t cnets[], 24 | ind_t *ind); 25 | 26 | /* copy partition properties to parts_info for temporary use */ 27 | void copy_partition(int noparts, 28 | parts_info_t parts_info[], 29 | ind_t *ind); 30 | 31 | /* read a partition prepared beforehand */ 32 | int read_partition(FILE *fp, 33 | char *filename, 34 | int noparts, 35 | cells_t cells[], 36 | nets_t nets[], 37 | corn_t cnets[], 38 | ind_t *ind); 39 | 40 | /* write a partition */ 41 | void write_partition(FILE *fp, 42 | char *filename, 43 | int nocells, 44 | int noparts, 45 | ind_t *ind); 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /src/share/ad_print.c: -------------------------------------------------------------------------------- 1 | 2 | /* COPYRIGHT C 1991- Ali Dasdan */ 3 | 4 | #include 5 | #include "ad_defs.h" 6 | #include "ad_print.h" 7 | 8 | void print_hgraph(int nocells, 9 | int nonets, 10 | cells_t cells[], 11 | nets_t nets[], 12 | corn_t ncells[]) 13 | { 14 | printf("\nHYPERGRAPH\n"); 15 | printf("%d\n%d\n", nocells, nonets); 16 | for (int i = 0; i < nonets; i++) { 17 | printf("%d %d ", nets[i].nweight, nets[i].nno_cells); 18 | for (int j = 0; j < nets[i].nno_cells; j++) 19 | printf("%d ", ncells[j + nets[i].celllist].corn_no); 20 | printf("\n"); 21 | } /* for i */ 22 | for (int i = 0; i < nocells; i++) 23 | printf("%d\n", cells[i].cweight); 24 | } /* print_hgraph */ 25 | 26 | void print_vars(int nocells, 27 | int nonets, 28 | int noparts, 29 | int nopins, 30 | int totcellsize, 31 | int totnetsize, 32 | int max_cdeg, 33 | int max_ndeg, 34 | int max_cweight, 35 | int max_nweight) 36 | { 37 | printf("\nHYPERGRAPH VARIABLES\n"); 38 | printf("nocells= %d\n", nocells); 39 | printf("noparts= %d\n", noparts); 40 | printf("nonets= %d\n", nonets); 41 | printf("nopins= %d\n", nopins); 42 | printf("totcellsize= %d\n", totcellsize); 43 | printf("totnetsize= %d\n", totnetsize); 44 | printf("max_cdeg= %d\n", max_cdeg); 45 | printf("max_ndeg= %d\n", max_ndeg); 46 | printf("max_cweight= %d\n", max_cweight); 47 | printf("max_nweight= %d\n", max_nweight); 48 | } /* print_vars */ 49 | 50 | void print_cnets(int nopins, corn_t cnets[]) 51 | { 52 | printf("\nCNETS\n"); 53 | for (int i = 0; i < nopins; i++) { 54 | printf("%d ", cnets[i].corn_no); 55 | if ((i % 10) == 0) { 56 | printf("\n"); 57 | } 58 | } 59 | printf("\n"); 60 | } /* print_cnets */ 61 | 62 | void print_ncells(int nopins, corn_t ncells[]) 63 | { 64 | printf("\nNCELLS\n"); 65 | for (int i = 0; i < nopins; i++) { 66 | printf("%d ", ncells[i].corn_no); 67 | if ((i % 10) == 0) { 68 | printf("\n"); 69 | } 70 | } 71 | printf("\n"); 72 | } /* print_ncells */ 73 | 74 | void print_parts(int nocells, 75 | int noparts, 76 | ind_t *ind, 77 | allele tchrom[]) 78 | { 79 | printf("\nPARTS\n"); 80 | 81 | for (int i = 0; i < noparts; i++) { 82 | 83 | printf("part_no=%d: %d <= %d <= %d * #cells=%d\n", i, 84 | ind->parts[i].pmin_size, 85 | ind->parts[i].pcurr_size, 86 | ind->parts[i].pmax_size, 87 | ind->parts[i].pmax_cells); 88 | 89 | int k = 0; 90 | for (int j = 0; j < nocells; j++) { 91 | if (tchrom[j] == i) { 92 | printf("%d ", j); 93 | k++; 94 | if (k % 20 == 0) { 95 | printf("\n"); 96 | } 97 | } /* if */ 98 | } /* for j */ 99 | 100 | printf("\n"); 101 | 102 | } /* for i */ 103 | } /* print_parts */ 104 | 105 | void print_parts_info(int nocells, 106 | int noparts, 107 | allele chrom[], 108 | parts_info_t parts_info[]) 109 | { 110 | printf("\nPARTS_INFO\n"); 111 | 112 | for (int i = 0; i < noparts; i++) { 113 | 114 | printf("part_no=%d: %d <= %d <= %d * #cells=%d\n", i, 115 | parts_info[i].pmin_size, 116 | parts_info[i].pcurr_size, 117 | parts_info[i].pmax_size, 118 | parts_info[i].pmax_cells); 119 | 120 | for (int j = 0; j < nocells; j++) { 121 | if (chrom[j] == i) { 122 | printf("%d ", j); 123 | } 124 | } /* for j */ 125 | 126 | printf("\n"); 127 | 128 | } /* for i */ 129 | } /* print_parts_info */ 130 | 131 | void print_cells(int nocells, 132 | cells_t cells[], 133 | corn_t cnets[]) 134 | { 135 | printf("\nCELLS\n"); 136 | 137 | int totsize = 0; 138 | for (int i = 0; i < nocells; i++) { 139 | 140 | printf("c=%d #n=%d cw=%d nl=%d ns= ", 141 | i, cells[i].cno_nets, cells[i].cweight, cells[i].netlist); 142 | 143 | totsize += cells[i].cweight; 144 | 145 | for (int j = 0; j < cells[i].cno_nets; j++) 146 | printf("%d ", cnets[cells[i].netlist + j].corn_no); 147 | 148 | printf("\n"); 149 | 150 | } /* for */ 151 | 152 | printf("totcellsize = %d\n", totsize); 153 | } /* print_cells */ 154 | 155 | void print_nets(int nonets, 156 | int noparts, 157 | nets_t nets[], 158 | corn_t ncells[]) 159 | { 160 | printf("\nNETS\n"); 161 | 162 | int totsize = 0; 163 | for (int i = 0; i < nonets; i++) { 164 | 165 | printf("n=%d #c=%d nw=%d cl=%d p(n)= ", i, nets[i].nno_cells, 166 | nets[i].nweight, nets[i].celllist); 167 | 168 | totsize += nets[i].nweight; 169 | 170 | for (int j = 0; j < noparts; j++) 171 | printf("%d:%d ", j, nets[i].npartdeg[j]); 172 | 173 | printf("\ncs= "); 174 | 175 | for (int j = 0; j < nets[i].nno_cells; j++) 176 | printf("%d ", ncells[nets[i].celllist + j].corn_no); 177 | 178 | printf("\n"); 179 | 180 | } /* for i*/ 181 | 182 | printf("totnetsize= %d\n", totsize); 183 | } /* print_nets */ 184 | 185 | void print_chrom(int nocells, allele chrom[]) 186 | { 187 | printf("\nCHROM:\n"); 188 | for (int i = 0; i < nocells; i++) { 189 | printf("%d ", chrom[i]); 190 | } 191 | printf("\n"); 192 | } /* print_chrom */ 193 | 194 | void print_cells_info(int nocells, 195 | int noparts, 196 | cells_info_t cells_info[]) 197 | { 198 | printf("\nCELLS_INFO\n"); 199 | for (int i = 0; i < nocells; i++) { 200 | printf("c=%d mc=%d l=%d mg= ", i, cells_info[i].mcount, cells_info[i].locked); 201 | for (int j = 0; j < noparts; j++) 202 | printf("%d ", cells_info[i].mgain[j]); 203 | printf("\n"); 204 | } /* for i */ 205 | } /* print_cells_info */ 206 | 207 | void print_inx(int noparts, partb_t partb[][noparts - 1]) 208 | { 209 | printf("\nINDICES:\n"); 210 | for (int i = 0; i < noparts; i++) { 211 | for (int j = 0; j < (noparts - 1); j++) { 212 | printf("(%d,%d) max=%d min=%d nobucs=%d\n", 213 | i, j, partb[i][j].max_inx, partb[i][j].min_inx, partb[i][j].nobuckets); 214 | } /* for j */ 215 | } /* for i */ 216 | } /* print_inx */ 217 | 218 | void print_buckets(int noparts, 219 | int bucketsize, 220 | partb_t partb[][noparts - 1]) 221 | { 222 | printf("\nPARTB:\n"); 223 | 224 | for (int i = 0; i < noparts; i++) { 225 | for (int j = 0; j < (noparts - 1); j++) { 226 | for (int k = 0; k < bucketsize; k++) { 227 | 228 | bnode_ptr_t next = partb[i][j].bnode_ptr[k]; 229 | if (next != NULL) { 230 | printf("Partb[%d][%d].bnode_ptr[%d]=", i, j, k); 231 | while (next != NULL) { 232 | if (next->lptr != NULL) { 233 | printf("%d<", (next->lptr)->cell_no); 234 | } 235 | printf("%d>", next->cell_no); 236 | if (next->rptr != NULL) { 237 | printf("%d ", (next->rptr)->cell_no); 238 | } 239 | next = next->rptr; 240 | } /* while */ 241 | 242 | printf("\n"); 243 | 244 | } /* if */ 245 | } /* for k */ 246 | } /* for j */ 247 | } /* for i */ 248 | } /* print_buckets */ 249 | 250 | /* EOF */ 251 | -------------------------------------------------------------------------------- /src/share/ad_print.h: -------------------------------------------------------------------------------- 1 | #ifndef AD_PRINT_INCLUDED 2 | #define AD_PRINT_INCLUDED 3 | 4 | /* COPYRIGHT C 1991- Ali Dasdan */ 5 | 6 | void print_hgraph(int nocells, 7 | int nonets, 8 | cells_t cells[], 9 | nets_t nets[], 10 | corn_t ncells[]); 11 | 12 | void print_vars(int nocells, 13 | int nonets, 14 | int noparts, 15 | int nopins, 16 | int totcellsize, 17 | int totnetsize, 18 | int max_cdeg, 19 | int max_ndeg, 20 | int max_cweight, 21 | int max_nweight); 22 | 23 | void print_cnets(int nopins, corn_t cnets[]); 24 | 25 | void print_ncells(int nopins, corn_t ncells[]); 26 | 27 | void print_parts(int nocells, 28 | int noparts, 29 | ind_t *ind, 30 | allele tchrom[]); 31 | 32 | void print_parts_info(int nocells, 33 | int noparts, 34 | allele chrom[], 35 | parts_info_t parts_info[]); 36 | 37 | void print_cells(int nocells, 38 | cells_t cells[], 39 | corn_t cnets[]); 40 | 41 | void print_nets(int nonets, 42 | int noparts, 43 | nets_t nets[], 44 | corn_t ncells[]); 45 | 46 | void print_chrom(int nocells, allele chrom[]); 47 | 48 | void print_cells_info(int nocells, 49 | int noparts, 50 | cells_info_t cells_info[]); 51 | 52 | void print_inx(int noparts, partb_t partb[][noparts - 1]); 53 | 54 | void print_buckets(int noparts, 55 | int bucketsize, 56 | partb_t partb[][noparts - 1]); 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /src/share/ad_random.c: -------------------------------------------------------------------------------- 1 | 2 | /* COPYRIGHT C 1991- Ali Dasdan */ 3 | 4 | #include 5 | #include 6 | #include "ad_random.h" 7 | 8 | /* initializes random number generator with seed or */ 9 | /* with any value if seed = -1 */ 10 | long randomize(long seed) 11 | { 12 | long in_seed; 13 | 14 | if (seed == -1) { 15 | time(&in_seed); /* init with current time */ 16 | } else { 17 | in_seed = seed; /* init with seed */ 18 | } 19 | srand48(in_seed); 20 | 21 | return in_seed; 22 | } /* randomize */ 23 | 24 | /* generates a float random number in [0, 1) */ 25 | float rand01() 26 | { 27 | return (float) drand48(); 28 | } /* rand01 */ 29 | 30 | /* generates a int random number in [min, max] */ 31 | /* if int output is needed, prms are true min & max */ 32 | int irandom(int min, int max) 33 | { 34 | if (min >= max) { 35 | return min; 36 | } else { 37 | int retval = (int) (rand01() * (float) (max + 1 - min) + (float) min); 38 | if (retval > max) { 39 | retval = max; 40 | } 41 | return retval; 42 | } /* else */ 43 | } /* irandom */ 44 | 45 | /* EOF */ 46 | -------------------------------------------------------------------------------- /src/share/ad_random.h: -------------------------------------------------------------------------------- 1 | #ifndef AD_RANDOM_INCLUDED 2 | #define AD_RANDOM_INCLUDED 3 | 4 | /* COPYRIGHT C 1991- Ali Dasdan */ 5 | 6 | #include 7 | 8 | /* These two lines of code are TERRIBLY necessary */ 9 | double drand48(); 10 | void srand48(); 11 | 12 | /* initializes random number generator with seed or */ 13 | /* with any value if seed = -1 */ 14 | long randomize(long seed); 15 | 16 | /* generates a float random number in [0, 1) */ 17 | float rand01(); 18 | 19 | /* generates a int random number in [min, max] */ 20 | /* if int output is needed, prms are true min & max */ 21 | int irandom(int min, int max); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/share/ad_readinput.c: -------------------------------------------------------------------------------- 1 | 2 | /* COPYRIGHT C 1991- Ali Dasdan */ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "ad_defs.h" 9 | #include "ad_fileio.h" 10 | #include "ad_readinput.h" 11 | 12 | /* initialize cells array */ 13 | void init_cells(int nocells, cells_t cells[]) 14 | { 15 | for (int i = 0; i < nocells; i++) { 16 | cells[i].cno_nets = 0; 17 | cells[i].cno_inets = 0; 18 | cells[i].netlist = NIL; 19 | } /* for */ 20 | } /* init_cells */ 21 | 22 | /* initialize nets array */ 23 | void init_nets(int nonets, 24 | int noparts, 25 | nets_t nets[]) 26 | { 27 | for (int i = 0; i < nonets; i++) { 28 | nets[i].nno_cells = 0; 29 | nets[i].celllist = NIL; 30 | for (int j = 0; j < noparts; j++) { 31 | nets[i].npartdeg[j] = 0; 32 | } 33 | } /* for i */ 34 | } /* init_nets */ 35 | 36 | /* initialize netlist pointers */ 37 | void init_netlist(int nonets, 38 | cells_t cells[], 39 | nets_t nets[], 40 | corn_t cnets[], 41 | corn_t ncells[]) 42 | { 43 | for (int i = 0; i < nonets; i++) { 44 | for (int j = 0; j < nets[i].nno_cells; j++) { 45 | int cell_no = ncells[nets[i].celllist + j].corn_no; 46 | int cnets_inx = cells[cell_no].netlist + cells[cell_no].cno_inets; 47 | cnets[cnets_inx].corn_no = i; 48 | cells[cell_no].cno_inets++; 49 | if (cells[cell_no].cno_inets > cells[cell_no].cno_nets) { 50 | printf("Error: Inconsistency in cell_%d degrees.\n", j); 51 | exit(1); 52 | } /* if */ 53 | } /* for j */ 54 | } /* for i */ 55 | } /* init_netlist */ 56 | 57 | void read_hgraph_size(char fname[], 58 | int *nocells, 59 | int *nonets, 60 | int *nopins) 61 | { 62 | FILE *fp; 63 | 64 | open_file(&fp, fname, "r"); 65 | 66 | if (fscanf(fp, "%d%d%d", nocells, nonets, nopins) == EOF) { 67 | printf("Error: Cannot read from %s: errno= %d error= %s\n", fname, errno, strerror(errno)); 68 | close_file(&fp); 69 | exit(1); 70 | } 71 | 72 | if ((*nocells < 0) || (*nonets < 0) || (*nopins < 0)) { 73 | printf("Error: Invalid attributes of graph.\n"); 74 | close_file(&fp); 75 | exit(1); 76 | } /* if */ 77 | 78 | close_file(&fp); 79 | } /* read_hgraph_size */ 80 | 81 | /* read input hypergraph and construct cells, nets, cnets, & ncells arrays */ 82 | void read_hgraph(char fname[], 83 | int nocells, 84 | int nonets, 85 | int nopins, 86 | int noparts, 87 | int *totcellsize, 88 | int *totnetsize, 89 | int *max_cdeg, 90 | int *max_ndeg, 91 | int *max_cweight, 92 | int *max_nweight, 93 | cells_t cells[], 94 | nets_t nets[], 95 | corn_t cnets[], 96 | corn_t ncells[]) 97 | { 98 | FILE *fp; 99 | open_file(&fp, fname, "r"); 100 | 101 | /* hgraph size is already read so re-read and discard. */ 102 | int ignore1, ignore2, ignore3; 103 | if (fscanf(fp, "%d%d%d", &ignore1, &ignore2, &ignore3) == EOF) { 104 | printf("Error: Cannot read from %s: errno= %d error= %s\n", fname, errno, strerror(errno)); 105 | close_file(&fp); 106 | exit(1); 107 | } 108 | 109 | /* initialize cells & nets arrays */ 110 | init_cells(nocells, cells); 111 | init_nets(nonets, noparts, nets); 112 | 113 | /* initialize variables */ 114 | *max_cweight = -1; 115 | *max_nweight = -1; 116 | *max_cdeg = -1; 117 | *max_ndeg = -1; 118 | *totcellsize = 0; 119 | *totnetsize = 0; 120 | 121 | /* read nets */ 122 | int ncells_inx = 0; 123 | for (int i = 0; i < nonets; i++) { 124 | if (fscanf(fp, "%d%d", &nets[i].nweight, &nets[i].nno_cells) == EOF) { 125 | printf("Error: Cannot read from %s: errno= %d error= %s\n", fname, errno, strerror(errno)); 126 | close_file(&fp); 127 | exit(1); 128 | } 129 | (*totnetsize) += nets[i].nweight; 130 | if (nets[i].nweight > (*max_nweight)) { 131 | *max_nweight = nets[i].nweight; 132 | } 133 | if (nets[i].nno_cells > (*max_ndeg)) { 134 | *max_ndeg = nets[i].nno_cells; 135 | } 136 | nets[i].celllist = ncells_inx; 137 | 138 | for (int j = 0; j < nets[i].nno_cells; j++) { 139 | int cell_no; 140 | if (fscanf(fp, "%d", &cell_no) == EOF) { 141 | printf("Error: Cannot read from %s: errno= %d error= %s\n", fname, errno, strerror(errno)); 142 | close_file(&fp); 143 | exit(1); 144 | } 145 | ncells[ncells_inx].corn_no = cell_no; 146 | ncells_inx++; 147 | cells[cell_no].cno_nets++; 148 | } /* for j */ 149 | } /* for i */ 150 | 151 | /* read cell weights */ 152 | int cnets_inx = 0; 153 | for (int i = 0; i < nocells; i++) { 154 | if (fscanf(fp, "%d", &cells[i].cweight) == EOF) { 155 | printf("Error: Cannot read from %s: errno= %d error= %s\n", fname, errno, strerror(errno)); 156 | close_file(&fp); 157 | exit(1); 158 | } 159 | (*totcellsize) += cells[i].cweight; 160 | if (cells[i].cweight > (*max_cweight)) 161 | *max_cweight = cells[i].cweight; 162 | if (cells[i].cno_nets > (*max_cdeg)) 163 | *max_cdeg = cells[i].cno_nets; 164 | cells[i].netlist = cnets_inx; 165 | cnets_inx += cells[i].cno_nets; 166 | } /* for i */ 167 | 168 | close_file(&fp); 169 | 170 | /* create netlists */ 171 | init_netlist(nonets, cells, nets, cnets, ncells); 172 | } /* read_hgraph */ 173 | 174 | /* EOF */ 175 | -------------------------------------------------------------------------------- /src/share/ad_readinput.h: -------------------------------------------------------------------------------- 1 | #ifndef AD_READINPUT_INCLUDED 2 | #define AD_READINPUT_INCLUDED 3 | 4 | /* COPYRIGHT C 1991- Ali Dasdan */ 5 | 6 | /* initialize cells array */ 7 | void init_cells(int nocells, cells_t cells[]); 8 | 9 | /* initialize nets array */ 10 | void init_nets(int nonets, 11 | int noparts, 12 | nets_t nets[]); 13 | 14 | /* initialize netlist pointers */ 15 | void init_netlist(int nonets, 16 | cells_t cells[], 17 | nets_t nets[], 18 | corn_t cnets[], 19 | corn_t ncells[]); 20 | 21 | void read_hgraph_size(char fname[], 22 | int *nocells, 23 | int *nets, 24 | int *nopins); 25 | 26 | /* read input hypergraph and construct cells, nets, cnets, & ncells arrays */ 27 | void read_hgraph(char fname[], 28 | int nocells, 29 | int nonets, 30 | int nopins, 31 | int noparts, 32 | int *totcellsize, 33 | int *totnetsize, 34 | int *max_cdeg, 35 | int *max_ndeg, 36 | int *max_cweight, 37 | int *max_nweight, 38 | cells_t cells[], 39 | nets_t nets[], 40 | corn_t cnets[], 41 | corn_t ncells[]); 42 | 43 | #endif 44 | --------------------------------------------------------------------------------