13 #ifndef PARTITION_TOPOLOGY_VERBOSE
14 #define PARTITION_TOPOLOGY_VERBOSE 0
18 * Author: Harshitha Menon, Nikhil Jain, Yanhua Sun
19 * Contact: gplkrsh2@illinois.edu, nikhil@illinois.edu, sun51@illinois.edu
21 * More details about this implementation of the Hilbert curve can be found
22 * from https://github.com/straup/gae-spacetimeid/blob/master/hilbert.py
23 * and this is a C++ implementation of what is given there.
25 static int gray_encode(int i) {
26 //cout << "gray_encode " << i << " " << (i^(i/2)) << endl;
30 static int gray_decode(int n) {
43 static void initial_start_end(int nChunks, int dim, int& start, int& end) {
45 ////cout << "-nchunks - 1 mod dim " << ((-nChunks-1)%dim) << endl;
46 int mod_val = (-nChunks - 1) % dim;
50 end = pow((double)2, (double)mod_val);
53 static int pack_index(vector<int> chunks, int dim) {
54 int p = pow((double)2, (double)dim);
55 int chunk_size = chunks.size();
57 for (int i = 0;i < chunk_size; i++) {
58 val = val*p + chunks[i] ;
63 static vector<int> transpose_bits(vector<int> srcs, int nDests) {
64 int nSrcs = srcs.size();
68 for (int j = nDests - 1; j > -1; j--) {
70 ////cout << "nSrcs " << nSrcs << endl;
71 for (int k = 0; k < nSrcs; k++) {
72 dest = dest * 2 + srcs[k] % 2;
74 ////cout << "dest " << dest << endl;
81 static vector<int> pack_coords(vector<int> coord_chunks, int dim) {
82 return transpose_bits(coord_chunks, dim);
85 static vector<int> unpack_coords(const vector<int> &coords, int dim) {
87 for(int i=0; i<coords.size(); i++)
89 if(coords[i] > biggest)
92 int nChunks = max(1, int( ceil( log( (double)biggest + 1)/log(2.0f) ) ) );
93 return transpose_bits( coords, nChunks );
97 static void unpack_index(int i, int dim, vector<int>& chunks) {
98 int p = pow((double)2, (double)dim);
99 int nChunks = max(1, int(ceil(double(log((double)i+1))/log((double)p))));
100 //cout << "num chunks " << nChunks << endl;
101 chunks.resize(nChunks);
102 for (int j = nChunks-1; j > -1; j--) {
105 ////cout << "chunks[" << j << "] " << chunks[j] << endl;
107 //cout << "chunk size " << chunks.size() << endl;
110 static int gray_encode_travel(int start, int end, int mask, int i) {
111 int travel_bit = start ^ end;
112 int modulus = mask + 1;
113 int g = gray_encode(i) * (travel_bit * 2);
114 //cout << "start " << start << " end " << end << "travel_bits " << travel_bit << " modulus " << modulus << " g " << g << endl;
115 return ((g | (g/modulus) ) & mask) ^ start;
118 static int gray_decode_travel(int start, int end, int mask, int i) {
119 int travel_bit = start ^ end;
120 int modulus = mask + 1;
121 int rg = (i ^ start) * ( modulus/(travel_bit * 2));
122 return gray_decode((rg | (rg / modulus)) & mask);
125 static void child_start_end(int parent_start, int parent_end, int mask, int i, int&
126 child_start, int& child_end) {
127 int start_i = max(0, (i-1)&~1);
128 //cout << "start_i " << start_i << endl;
129 int end_i = min(mask, (i+1)|1);
130 //cout << "end_i " << end_i << endl;
131 child_start = gray_encode_travel(parent_start, parent_end, mask, start_i);
132 child_end = gray_encode_travel(parent_start, parent_end, mask, end_i);
133 //cout << "child_start " << child_start << " child end " << child_end << endl;
136 vector<int> int_to_Hilbert(int i, int dim) {
137 int nChunks, mask, start, end;
138 vector<int> index_chunks;
139 unpack_index(i, dim, index_chunks);
140 nChunks = index_chunks.size();
141 //cout << "int to hilbert of " << i << " in dim " << dim << " size " << nChunks << endl;
142 mask = pow((double)2, (double)dim) - 1;
143 //cout << "mask " << mask << endl;
144 initial_start_end(nChunks, dim, start, end);
145 //cout << "start " << start << " end " << end << endl;
146 vector<int> coord_chunks;
147 coord_chunks.resize(nChunks);
148 for (int j = 0; j < nChunks; j++) {
150 coord_chunks[j] = gray_encode_travel(start, end, mask, i);
151 //cout << "coord_chuunk " << j << " : " << coord_chunks[j] << endl;
152 ////cout << "going for child start end" << endl;
153 child_start_end(start, end, mask, i, start, end);
154 //cout << "child start end " << start << " " << end << endl;
156 return pack_coords(coord_chunks, dim);
159 int Hilbert_to_int(const vector<int>& coords, int dim)
161 vector<int> coord_chunks = unpack_coords( coords, dim );
163 int nChunks = coord_chunks.size();
164 int mask = pow((double)2, (double)dim) - 1;
166 initial_start_end(nChunks, dim, start, end);
167 vector<int> index_chunks;
168 index_chunks.resize(nChunks);
169 for (int j = 0; j < nChunks; j++) {
170 i = gray_decode_travel( start, end, mask, coord_chunks[ j ] );
171 index_chunks[ j ] = i;
172 child_start_end(start, end, mask, i, start, end);
175 return pack_index( index_chunks, dim );