ZLayout EDA Library v1.0.0
Advanced Electronic Design Automation Layout Library with Bilingual Documentation
Loading...
Searching...
No Matches
ultra_large_scale_example.cpp
Go to the documentation of this file.
1
12
13#include <zlayout/zlayout.hpp>
15#include <chrono>
16#include <iostream>
17#include <random>
18#include <iomanip>
19
20using namespace zlayout;
21using namespace zlayout::spatial;
22
27private:
28 std::mt19937 rng;
29 std::uniform_real_distribution<double> coord_dist;
30 std::uniform_real_distribution<double> size_dist;
31
32public:
33 UltraLargeScaleDemo() : rng(std::random_device{}()),
34 coord_dist(0.0, 100000.0), // 100mm x 100mm chip
35 size_dist(0.001, 0.1) {} // 1μm to 100μm components
36
40 std::vector<std::pair<geometry::Rectangle, geometry::Rectangle>>
41 generate_components(size_t count) {
42 std::vector<std::pair<geometry::Rectangle, geometry::Rectangle>> components;
43 components.reserve(count);
44
45 std::cout << "Generating " << count << " components..." << std::endl;
46
47 for (size_t i = 0; i < count; ++i) {
48 double x = coord_dist(rng);
49 double y = coord_dist(rng);
50 double width = size_dist(rng);
51 double height = size_dist(rng);
52
53 geometry::Rectangle component(x, y, width, height);
54 components.emplace_back(component, component); // object, bbox pair
55
56 if (i % 10000000 == 0 && i > 0) {
57 std::cout << " Generated " << i << " components..." << std::endl;
58 }
59 }
60
61 return components;
62 }
63
68 std::cout << "\n=== IP Block Hierarchy Demo ===" << std::endl;
69
70 // Create world bounds (100mm x 100mm)
71 geometry::Rectangle world_bounds(0, 0, 100000, 100000);
72
73 // Create hierarchical spatial index
74 HierarchicalSpatialIndex<geometry::Rectangle> index(world_bounds, 1000000, 10);
75
76 // Create CPU complex
77 index.create_ip_block("CPU", geometry::Rectangle(10000, 10000, 20000, 20000));
78 index.create_ip_block("ALU", geometry::Rectangle(12000, 12000, 5000, 5000), "CPU");
79 index.create_ip_block("FPU", geometry::Rectangle(18000, 12000, 5000, 5000), "CPU");
80 index.create_ip_block("Cache", geometry::Rectangle(12000, 18000, 10000, 8000), "CPU");
81
82 // Create GPU complex
83 index.create_ip_block("GPU", geometry::Rectangle(40000, 10000, 30000, 30000));
84 index.create_ip_block("Shader_Array", geometry::Rectangle(42000, 12000, 26000, 26000), "GPU");
85
86 // Create Memory complex
87 index.create_ip_block("Memory", geometry::Rectangle(10000, 50000, 60000, 40000));
88 index.create_ip_block("DDR_Controller", geometry::Rectangle(12000, 52000, 15000, 8000), "Memory");
89 index.create_ip_block("L3_Cache", geometry::Rectangle(30000, 52000, 20000, 15000), "Memory");
90
91 std::cout << "Created hierarchical IP block structure" << std::endl;
92
93 // Get statistics
94 auto stats = index.get_statistics();
95 std::cout << "Total blocks: " << stats.total_blocks << std::endl;
96 std::cout << "Max depth: " << stats.max_depth << std::endl;
97 }
98
103 std::cout << "\n=== Performance Benchmark ===" << std::endl;
104
105 std::vector<size_t> test_sizes = {
106 1000000, // 1M components
107 10000000, // 10M components
108 100000000, // 100M components
109 1000000000 // 1B components (if memory allows)
110 };
111
112 geometry::Rectangle world_bounds(0, 0, 100000, 100000);
113
114 for (size_t size : test_sizes) {
115 std::cout << "\nTesting with " << size << " components:" << std::endl;
116
117 try {
118 // Create optimized index
120 world_bounds, size);
121
122 // Generate test data
123 auto components = generate_components(size);
124
125 // Measure insertion time
126 auto start = std::chrono::high_resolution_clock::now();
127 index->parallel_bulk_insert(components);
128 auto end = std::chrono::high_resolution_clock::now();
129
130 auto insertion_time = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
131 std::cout << " Insertion time: " << insertion_time.count() << " ms" << std::endl;
132
133 // Test queries
134 start = std::chrono::high_resolution_clock::now();
135 geometry::Rectangle query_rect(25000, 25000, 10000, 10000);
136 auto results = index->parallel_query_range(query_rect);
137 end = std::chrono::high_resolution_clock::now();
138
139 auto query_time = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
140 std::cout << " Query time: " << query_time.count() << " μs" << std::endl;
141 std::cout << " Results found: " << results.size() << std::endl;
142
143 // Test intersection detection
144 start = std::chrono::high_resolution_clock::now();
145 auto intersections = index->parallel_find_intersections();
146 end = std::chrono::high_resolution_clock::now();
147
148 auto intersection_time = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
149 std::cout << " Intersection detection time: " << intersection_time.count() << " ms" << std::endl;
150 std::cout << " Potential intersections: " << intersections.size() << std::endl;
151
152 // Get statistics
153 auto stats = index->get_statistics();
154 std::cout << " Memory usage: " << std::fixed << std::setprecision(2)
155 << stats.memory_usage_mb << " MB" << std::endl;
156 std::cout << " Total blocks: " << stats.total_blocks << std::endl;
157 std::cout << " Avg objects per block: " << stats.avg_objects_per_block << std::endl;
158
159 } catch (const std::exception& e) {
160 std::cout << " Error: " << e.what() << std::endl;
161 std::cout << " (Likely insufficient memory for this scale)" << std::endl;
162 break;
163 }
164 }
165 }
166
171 std::cout << "\n=== Large Scale Design Rule Checking ===" << std::endl;
172
173 const size_t component_count = 10000000; // 10M components
174 geometry::Rectangle world_bounds(0, 0, 100000, 100000);
175
177 world_bounds, component_count);
178
179 // Generate components
180 auto components = generate_components(component_count);
181
182 std::cout << "Inserting " << component_count << " components..." << std::endl;
183 auto start = std::chrono::high_resolution_clock::now();
184 index->parallel_bulk_insert(components);
185 auto end = std::chrono::high_resolution_clock::now();
186
187 auto insertion_time = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
188 std::cout << "Insertion completed in " << insertion_time.count() << " ms" << std::endl;
189
190 // DRC: Check minimum spacing violations
191 std::cout << "\nPerforming design rule checking..." << std::endl;
192 const double min_spacing = 0.01; // 10μm minimum spacing
193
194 start = std::chrono::high_resolution_clock::now();
195 auto potential_violations = index->parallel_find_intersections();
196 end = std::chrono::high_resolution_clock::now();
197
198 auto drc_time = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
199 std::cout << "DRC completed in " << drc_time.count() << " ms" << std::endl;
200
201 // Filter for actual violations
202 size_t real_violations = 0;
203 for (const auto& [rect1, rect2] : potential_violations) {
204 double distance = rect1.distance_to(rect2);
205 if (distance < min_spacing) {
206 real_violations++;
207 }
208 }
209
210 std::cout << "Potential violations: " << potential_violations.size() << std::endl;
211 std::cout << "Actual violations: " << real_violations << std::endl;
212 std::cout << "Violation rate: " << std::fixed << std::setprecision(4)
213 << (double)real_violations / component_count * 100 << "%" << std::endl;
214 }
215
220 std::cout << "\n=== Memory Pool Efficiency Demo ===" << std::endl;
221
222 const size_t allocation_count = 1000000;
223
224 // Test with standard allocation
225 std::cout << "Testing standard allocation..." << std::endl;
226 auto start = std::chrono::high_resolution_clock::now();
227
228 std::vector<geometry::Rectangle*> ptrs;
229 for (size_t i = 0; i < allocation_count; ++i) {
230 ptrs.push_back(new geometry::Rectangle(0, 0, 1, 1));
231 }
232 for (auto* ptr : ptrs) {
233 delete ptr;
234 }
235
236 auto end = std::chrono::high_resolution_clock::now();
237 auto std_time = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
238 std::cout << "Standard allocation time: " << std_time.count() << " ms" << std::endl;
239
240 // Test with memory pool
241 std::cout << "Testing memory pool allocation..." << std::endl;
242 start = std::chrono::high_resolution_clock::now();
243
245 std::vector<geometry::Rectangle*> pool_ptrs;
246
247 for (size_t i = 0; i < allocation_count; ++i) {
248 pool_ptrs.push_back(pool.allocate());
249 }
250 for (auto* ptr : pool_ptrs) {
251 pool.deallocate(ptr);
252 }
253
254 end = std::chrono::high_resolution_clock::now();
255 auto pool_time = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
256 std::cout << "Memory pool allocation time: " << pool_time.count() << " ms" << std::endl;
257
258 double speedup = (double)std_time.count() / pool_time.count();
259 std::cout << "Memory pool speedup: " << std::fixed << std::setprecision(2)
260 << speedup << "x" << std::endl;
261 }
262
266 void zorder_demo() {
267 std::cout << "\n=== Z-Order Curve Spatial Hashing Demo ===" << std::endl;
268
269 geometry::Rectangle bounds(0, 0, 1000, 1000);
270
271 // Test points
272 std::vector<geometry::Point> points = {
273 geometry::Point(100, 100),
274 geometry::Point(200, 100),
275 geometry::Point(100, 200),
276 geometry::Point(200, 200),
277 geometry::Point(500, 500),
278 geometry::Point(750, 250),
279 geometry::Point(250, 750)
280 };
281
282 std::cout << "Point -> Z-order code mapping:" << std::endl;
283 for (const auto& point : points) {
284 uint64_t z_code = ZOrderCurve::encode_point(point, bounds);
285 auto decoded = ZOrderCurve::decode(z_code);
286
287 std::cout << " (" << point.x << ", " << point.y << ") -> "
288 << std::hex << z_code << std::dec
289 << " -> (" << decoded.first << ", " << decoded.second << ")" << std::endl;
290 }
291
292 // Demonstrate spatial locality
293 std::cout << "\nSpatial locality demonstration:" << std::endl;
294 std::vector<std::pair<geometry::Point, uint64_t>> point_codes;
295
296 for (const auto& point : points) {
297 uint64_t z_code = ZOrderCurve::encode_point(point, bounds);
298 point_codes.emplace_back(point, z_code);
299 }
300
301 // Sort by Z-order
302 std::sort(point_codes.begin(), point_codes.end(),
303 [](const auto& a, const auto& b) { return a.second < b.second; });
304
305 std::cout << "Points sorted by Z-order:" << std::endl;
306 for (const auto& [point, z_code] : point_codes) {
307 std::cout << " (" << point.x << ", " << point.y << ") ["
308 << std::hex << z_code << std::dec << "]" << std::endl;
309 }
310 }
311
316 std::cout << "\n=== Spatial Index Algorithm Comparison ===" << std::endl;
317
318 const size_t component_count = 1000000; // 1M components for comparison
319 geometry::Rectangle world_bounds(0, 0, 10000, 10000);
320
321 // Generate test data
322 auto components = generate_components(component_count);
323
324 // Test QuadTree
325 std::cout << "\nTesting QuadTree..." << std::endl;
326 auto bbox_func = [](const geometry::Rectangle& rect) { return rect; };
327 QuadTree<geometry::Rectangle> quadtree(world_bounds, bbox_func, 100, 8);
328
329 auto start = std::chrono::high_resolution_clock::now();
330 for (const auto& [component, bbox] : components) {
331 quadtree.insert(component);
332 }
333 auto end = std::chrono::high_resolution_clock::now();
334 auto qt_insert_time = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
335
336 // Test R-tree
337 std::cout << "Testing R-tree..." << std::endl;
339
340 start = std::chrono::high_resolution_clock::now();
341 for (const auto& [component, bbox] : components) {
342 rtree.insert(component, bbox);
343 }
344 end = std::chrono::high_resolution_clock::now();
345 auto rt_insert_time = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
346
347 // Test query performance
348 geometry::Rectangle query_rect(2500, 2500, 1000, 1000);
349
350 start = std::chrono::high_resolution_clock::now();
351 auto qt_results = quadtree.query_range(query_rect);
352 end = std::chrono::high_resolution_clock::now();
353 auto qt_query_time = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
354
355 start = std::chrono::high_resolution_clock::now();
356 auto rt_results = rtree.query_range(query_rect);
357 end = std::chrono::high_resolution_clock::now();
358 auto rt_query_time = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
359
360 // Print results
361 std::cout << "\nResults:" << std::endl;
362 std::cout << " QuadTree insertion: " << qt_insert_time.count() << " ms" << std::endl;
363 std::cout << " R-tree insertion: " << rt_insert_time.count() << " ms" << std::endl;
364 std::cout << " QuadTree query: " << qt_query_time.count() << " μs ("
365 << qt_results.size() << " results)" << std::endl;
366 std::cout << " R-tree query: " << rt_query_time.count() << " μs ("
367 << rt_results.size() << " results)" << std::endl;
368
369 // Memory usage comparison
370 auto qt_stats = quadtree.get_statistics();
371 std::cout << "\nMemory and structure:" << std::endl;
372 std::cout << " QuadTree nodes: " << qt_stats.total_nodes << std::endl;
373 std::cout << " QuadTree depth: " << qt_stats.max_depth_reached << std::endl;
374 std::cout << " QuadTree efficiency: " << std::fixed << std::setprecision(2)
375 << qt_stats.tree_efficiency << std::endl;
376 }
377};
378
379int main() {
380 std::cout << "=== Ultra-Large Scale EDA Layout Optimization Demo ===" << std::endl;
381 std::cout << "This demo showcases handling billions of components efficiently" << std::endl;
382
383 try {
385
386 // Run demonstrations
388 demo.zorder_demo();
389 demo.memory_pool_demo();
391
392 // Performance benchmarks (may take a while)
393 std::cout << "\nStarting performance benchmarks..." << std::endl;
394 std::cout << "Note: Large scale tests may take several minutes and require significant memory" << std::endl;
395
398
399 } catch (const std::exception& e) {
400 std::cerr << "Error: " << e.what() << std::endl;
401 return 1;
402 }
403
404 std::cout << "\nDemo completed successfully!" << std::endl;
405 return 0;
406}
Advanced spatial indexing for ultra-large scale EDA layouts.
Simulate creating a massive EDA layout with billions of components.
void design_rule_checking()
Demonstrate design rule checking at scale.
void performance_benchmark()
Test performance with different scales.
void zorder_demo()
Demonstrate Z-order curve spatial hashing.
void memory_pool_demo()
Demonstrate memory pool efficiency.
void algorithm_comparison()
Compare different spatial indexing algorithms.
void demonstrate_ip_blocks()
Demonstrate hierarchical IP block creation.
std::vector< std::pair< geometry::Rectangle, geometry::Rectangle > > generate_components(size_t count)
Generate random components for testing.
2D point with high-precision coordinates and utility methods
Definition point.hpp:23
Axis-aligned rectangle for bounding boxes and simple EDA components.
Definition rectangle.hpp:26
Hierarchical spatial index for ultra-large datasets.
void create_ip_block(const std::string &name, const geometry::Rectangle &boundary, const std::string &parent_name="root")
Memory pool for efficient object allocation.
Quadtree spatial index for efficient range and intersection queries.
Definition quadtree.hpp:120
bool insert(const T &object)
Insert object into quadtree.
Definition quadtree.hpp:627
std::vector< T > query_range(const geometry::Rectangle &range) const
Query objects in rectangular range.
Definition quadtree.hpp:638
Statistics get_statistics() const
Calculate tree statistics.
Definition quadtree.hpp:682
High-performance R-tree implementation.
void insert(const T &object, const geometry::Rectangle &bbox)
std::vector< T > query_range(const geometry::Rectangle &range) const
static std::unique_ptr< HierarchicalSpatialIndex< T > > create_optimized_index(const geometry::Rectangle &world_bounds, size_t expected_object_count, IndexType preferred_type=IndexType::HYBRID)
static std::pair< uint32_t, uint32_t > decode(uint64_t z)
static uint64_t encode_point(const geometry::Point &point, const geometry::Rectangle &bounds)
Main namespace for ZLayout library.
Definition component.hpp:20
ZLayout - Advanced Electronic Design Automation Layout Library.