KiCad PCB EDA Suite
Loading...
Searching...
No Matches
fill_bench_tool.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.TXT for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
25
26#include <chrono>
27#include <iostream>
28#include <vector>
29
30#include <wx/filename.h>
31
32#include <board.h>
33#include <board_commit.h>
36#include <core/profile.h>
37#include <drc/drc_engine.h>
38#include <mmh3_hash.h>
39#include <pcb_io/pcb_io_mgr.h>
41#include <tool/tool_manager.h>
42#include <zone.h>
43#include <zone_filler.h>
44
46
47
51static int fill_bench_main_func( int argc, char** argv )
52{
53 if( argc < 2 )
54 {
55 std::cerr << "Usage: fill_bench <board.kicad_pcb> [iterations]" << std::endl;
57 }
58
59 wxString boardPath = wxString::FromUTF8( argv[1] );
60 int iterations = argc > 2 ? std::atoi( argv[2] ) : 1;
61
62 std::unique_ptr<BOARD> board;
63
64 {
65 PROF_TIMER loadTimer;
66 board.reset( PCB_IO_MGR::Load( PCB_IO_MGR::KICAD_SEXP, boardPath, nullptr, {}, nullptr, nullptr ) );
67 std::cout << "Load: " << loadTimer.SinceStart<std::chrono::milliseconds>().count() << " ms"
68 << std::endl;
69 }
70
71 if( !board )
72 {
73 std::cerr << "Failed to load board" << std::endl;
75 }
76
77 BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings();
78
79 auto drcEngine = std::make_shared<DRC_ENGINE>( board.get(), &bds );
80 drcEngine->InitEngine( wxFileName() );
81 bds.m_DRCEngine = drcEngine;
82
83 board->BuildListOfNets();
84 board->BuildConnectivity();
85
86 std::cout << "Zones: " << board->Zones().size() << ", nets: " << board->GetNetCount() << std::endl;
87
88 TOOL_MANAGER toolMgr;
89 toolMgr.SetEnvironment( board.get(), nullptr, nullptr, nullptr, nullptr );
90
92 toolMgr.RegisterTool( dummyTool );
93
94 std::vector<ZONE*> toFill;
95
96 for( ZONE* zone : board->Zones() )
97 toFill.push_back( zone );
98
99 for( int i = 0; i < iterations; ++i )
100 {
101 BOARD_COMMIT commit( dummyTool );
102 ZONE_FILLER filler( board.get(), &commit );
103
104 PROF_TIMER fillTimer;
105 bool ok = filler.Fill( toFill, false, nullptr );
106 double ms = static_cast<double>( fillTimer.SinceStart<std::chrono::milliseconds>().count() );
107
108 std::cout << "Fill #" << i << ": " << ms << " ms" << ( ok ? "" : " (FAILED)" )
109 << std::endl;
110 }
111
112 // Order-independent digest, so two configs can be checked for identical output.
113 double totalArea = 0.0;
114 unsigned long long outlineCount = 0;
115 unsigned long long vertexCount = 0;
116
117 // Order-sensitive so two runs match only when the fill is byte-identical, not merely
118 // equal in area.
119 MMH3_HASH streamHash( 0x5A4F4E45 );
120
121 for( ZONE* zone : board->Zones() )
122 {
123 for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() )
124 {
125 if( !zone->HasFilledPolysForLayer( layer ) )
126 continue;
127
128 std::shared_ptr<SHAPE_POLY_SET> polys = zone->GetFilledPolysList( layer );
129 totalArea += polys->Area();
130 outlineCount += (unsigned long long) polys->OutlineCount();
131 vertexCount += (unsigned long long) polys->FullPointCount();
132
133 for( auto it = polys->CIterateWithHoles(); it; ++it )
134 {
135 streamHash.add( it->x );
136 streamHash.add( it->y );
137 }
138 }
139 }
140
141 HASH_128 digest = streamHash.digest();
142
143 std::cout << "FillSummary area=" << std::fixed << totalArea << " outlines=" << outlineCount
144 << " vertices=" << vertexCount << " streamhash=" << digest.ToString() << std::endl;
145
147}
148
149
150static bool registered = UTILITY_REGISTRY::Register( { "fill_bench",
151 "Benchmark zone filling on a board",
Container for design settings for a BOARD object.
std::shared_ptr< DRC_ENGINE > m_DRCEngine
A streaming C++ equivalent for MurmurHash3_x64_128.
Definition mmh3_hash.h:56
FORCE_INLINE void add(const std::string &input)
Definition mmh3_hash.h:117
FORCE_INLINE HASH_128 digest()
Definition mmh3_hash.h:136
static BOARD * Load(PCB_FILE_T aFileType, const wxString &aFileName, BOARD *aAppendToMe=nullptr, const std::map< std::string, UTF8 > *aProperties=nullptr, PROJECT *aProject=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr)
Find the requested #PLUGIN and if found, calls the #PLUGIN::LoadBoard() function on it using the argu...
@ KICAD_SEXP
S-expression Pcbnew file format.
Definition pcb_io_mgr.h:54
A small class to help profiling.
Definition profile.h:46
DURATION SinceStart(bool aSinceLast=false)
Definition profile.h:133
Master controller class:
void RegisterTool(TOOL_BASE *aTool)
Add a tool to the manager set and sets it up.
void SetEnvironment(EDA_ITEM *aModel, KIGFX::VIEW *aView, KIGFX::VIEW_CONTROLS *aViewControls, APP_SETTINGS_BASE *aSettings, TOOLS_HOLDER *aFrame)
Set the work environment (model, view, view controls and the parent window).
static bool Register(const KI_TEST::UTILITY_PROGRAM &aProgInfo)
Register a utility program factory function against an ID string.
bool Fill(const std::vector< ZONE * > &aZones, bool aCheck=false, wxWindow *aParent=nullptr)
Fills the given list of zones.
Handle a list of polygons defining a copper zone.
Definition zone.h:70
static bool registered
static int fill_bench_main_func(int argc, char **argv)
Headless zone-fill benchmark; times a full refill over N iterations.
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:56
@ OK
Tool exited OK.
@ TOOL_SPECIFIC
Tools can define their own statuses from here onwards.
@ BAD_CMDLINE
The command line was not correct for the tool.
A storage class for 128-bit hash value.
Definition hash_128.h:32
std::string ToString() const
Definition hash_128.h:43