Use hashlib in most remaining code

Signed-off-by: gatecat <gatecat@ds0.me>
This commit is contained in:
gatecat 2021-06-02 11:36:56 +01:00
parent b8a68f5f35
commit eca1a4cee4
20 changed files with 53 additions and 58 deletions

View File

@ -108,7 +108,7 @@ void archcheck_locs(const Context *ctx)
for (int x = 0; x < ctx->getGridDimX(); x++) for (int x = 0; x < ctx->getGridDimX(); x++)
for (int y = 0; y < ctx->getGridDimY(); y++) { for (int y = 0; y < ctx->getGridDimY(); y++) {
dbg("> %d %d\n", x, y); dbg("> %d %d\n", x, y);
std::unordered_set<int> usedz; pool<int> usedz;
for (int z = 0; z < ctx->getTileBelDimZ(x, y); z++) { for (int z = 0; z < ctx->getTileBelDimZ(x, y); z++) {
BelId bel = ctx->getBelByLocation(Loc(x, y, z)); BelId bel = ctx->getBelByLocation(Loc(x, y, z));
@ -162,10 +162,10 @@ struct LruWireCacheMap
// list is oldest wire in cache. // list is oldest wire in cache.
std::list<WireId> last_access_list; std::list<WireId> last_access_list;
// Quick wire -> list element lookup. // Quick wire -> list element lookup.
std::unordered_map<WireId, std::list<WireId>::iterator> last_access_map; dict<WireId, std::list<WireId>::iterator> last_access_map;
std::unordered_map<PipId, WireId> pips_downhill; dict<PipId, WireId> pips_downhill;
std::unordered_map<PipId, WireId> pips_uphill; dict<PipId, WireId> pips_uphill;
void removeWireFromCache(WireId wire_to_remove) void removeWireFromCache(WireId wire_to_remove)
{ {
@ -255,8 +255,8 @@ void archcheck_conn(const Context *ctx)
log_info("Checking all wires...\n"); log_info("Checking all wires...\n");
#ifndef USING_LRU_CACHE #ifndef USING_LRU_CACHE
std::unordered_map<PipId, WireId> pips_downhill; dict<PipId, WireId> pips_downhill;
std::unordered_map<PipId, WireId> pips_uphill; dict<PipId, WireId> pips_uphill;
#endif #endif
for (WireId wire : ctx->getWires()) { for (WireId wire : ctx->getWires()) {
@ -347,7 +347,7 @@ void archcheck_buckets(const Context *ctx)
for (BelBucketId bucket : ctx->getBelBuckets()) { for (BelBucketId bucket : ctx->getBelBuckets()) {
// Find out which cell types are in this bucket. // Find out which cell types are in this bucket.
std::unordered_set<IdString> cell_types_in_bucket; pool<IdString> cell_types_in_bucket;
for (IdString cell_type : ctx->getCellTypes()) { for (IdString cell_type : ctx->getCellTypes()) {
if (ctx->getBelBucketForCellType(cell_type) == bucket) { if (ctx->getBelBucketForCellType(cell_type) == bucket) {
cell_types_in_bucket.insert(cell_type); cell_types_in_bucket.insert(cell_type);
@ -356,9 +356,9 @@ void archcheck_buckets(const Context *ctx)
// Make sure that all cell types in this bucket have at least one // Make sure that all cell types in this bucket have at least one
// BelId they can be placed at. // BelId they can be placed at.
std::unordered_set<IdString> cell_types_unused; pool<IdString> cell_types_unused;
std::unordered_set<BelId> bels_in_bucket; pool<BelId> bels_in_bucket;
for (BelId bel : ctx->getBelsInBucket(bucket)) { for (BelId bel : ctx->getBelsInBucket(bucket)) {
BelBucketId bucket2 = ctx->getBelBucketForBel(bel); BelBucketId bucket2 = ctx->getBelBucketForBel(bel);
log_assert(bucket == bucket2); log_assert(bucket == bucket2);

View File

@ -28,6 +28,7 @@
#include <boost/thread.hpp> #include <boost/thread.hpp>
#endif #endif
#include "hashlib.h"
#include "idstring.h" #include "idstring.h"
#include "nextpnr_namespaces.h" #include "nextpnr_namespaces.h"
#include "nextpnr_types.h" #include "nextpnr_types.h"

View File

@ -458,7 +458,7 @@ int CommandHandler::exec()
if (executeBeforeContext()) if (executeBeforeContext())
return 0; return 0;
std::unordered_map<std::string, Property> values; dict<std::string, Property> values;
std::unique_ptr<Context> ctx = createContext(values); std::unique_ptr<Context> ctx = createContext(values);
setupContext(ctx.get()); setupContext(ctx.get());
setupArchContext(ctx.get()); setupArchContext(ctx.get());
@ -475,7 +475,7 @@ int CommandHandler::exec()
std::unique_ptr<Context> CommandHandler::load_json(std::string filename) std::unique_ptr<Context> CommandHandler::load_json(std::string filename)
{ {
std::unordered_map<std::string, Property> values; dict<std::string, Property> values;
std::unique_ptr<Context> ctx = createContext(values); std::unique_ptr<Context> ctx = createContext(values);
setupContext(ctx.get()); setupContext(ctx.get());
setupArchContext(ctx.get()); setupArchContext(ctx.get());

View File

@ -42,7 +42,7 @@ class CommandHandler
protected: protected:
virtual void setupArchContext(Context *ctx) = 0; virtual void setupArchContext(Context *ctx) = 0;
virtual std::unique_ptr<Context> createContext(std::unordered_map<std::string, Property> &values) = 0; virtual std::unique_ptr<Context> createContext(dict<std::string, Property> &values) = 0;
virtual po::options_description getArchOptions() = 0; virtual po::options_description getArchOptions() = 0;
virtual void validate(){}; virtual void validate(){};
virtual void customAfterLoad(Context *ctx){}; virtual void customAfterLoad(Context *ctx){};

View File

@ -21,11 +21,11 @@
#define CONSTRAINTS_H #define CONSTRAINTS_H
#include <cstdint> #include <cstdint>
#include <unordered_map>
#include <vector> #include <vector>
#include "archdefs.h" #include "archdefs.h"
#include "exclusive_state_groups.h" #include "exclusive_state_groups.h"
#include "hashlib.h"
#include "idstring.h" #include "idstring.h"
#include "nextpnr_namespaces.h" #include "nextpnr_namespaces.h"
@ -53,7 +53,7 @@ template <std::size_t StateCount, typename StateType = int8_t, typename CountTyp
}; };
typedef ExclusiveStateGroup<StateCount, StateType, CountType> TagState; typedef ExclusiveStateGroup<StateCount, StateType, CountType> TagState;
std::unordered_map<uint32_t, std::vector<typename TagState::Definition>> definitions; dict<uint32_t, std::vector<typename TagState::Definition>> definitions;
template <typename ConstraintRange> void bindBel(TagState *tags, const ConstraintRange constraints); template <typename ConstraintRange> void bindBel(TagState *tags, const ConstraintRange constraints);

View File

@ -38,7 +38,7 @@ log_write_type log_write_function = nullptr;
std::string log_last_error; std::string log_last_error;
void (*log_error_atexit)() = NULL; void (*log_error_atexit)() = NULL;
std::unordered_map<LogLevel, int> message_count_by_level; dict<LogLevel, int, loglevel_hash_ops> message_count_by_level;
static int log_newline_count = 0; static int log_newline_count = 0;
bool had_nonfatal_error = false; bool had_nonfatal_error = false;

View File

@ -26,8 +26,8 @@
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <string> #include <string>
#include <unordered_map>
#include <vector> #include <vector>
#include "hashlib.h"
#include "nextpnr_namespaces.h" #include "nextpnr_namespaces.h"
NEXTPNR_NAMESPACE_BEGIN NEXTPNR_NAMESPACE_BEGIN
@ -51,13 +51,19 @@ enum class LogLevel
ALWAYS_MSG ALWAYS_MSG
}; };
struct loglevel_hash_ops
{
static inline bool cmp(LogLevel a, LogLevel b) { return a == b; }
static inline unsigned int hash(LogLevel a) { return unsigned(a); }
};
extern std::vector<std::pair<std::ostream *, LogLevel>> log_streams; extern std::vector<std::pair<std::ostream *, LogLevel>> log_streams;
extern log_write_type log_write_function; extern log_write_type log_write_function;
extern std::string log_last_error; extern std::string log_last_error;
extern void (*log_error_atexit)(); extern void (*log_error_atexit)();
extern bool had_nonfatal_error; extern bool had_nonfatal_error;
extern std::unordered_map<LogLevel, int> message_count_by_level; extern dict<LogLevel, int, loglevel_hash_ops> message_count_by_level;
std::string stringf(const char *fmt, ...); std::string stringf(const char *fmt, ...);
std::string vstringf(const char *fmt, va_list ap); std::string vstringf(const char *fmt, va_list ap);
@ -83,14 +89,4 @@ static inline void log_assert_worker(bool cond, const char *expr, const char *fi
NEXTPNR_NAMESPACE_END NEXTPNR_NAMESPACE_END
namespace std {
template <> struct hash<NEXTPNR_NAMESPACE_PREFIX LogLevel>
{
std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX LogLevel &loglevel) const noexcept
{
return std::hash<int>()((int)loglevel);
}
};
} // namespace std
#endif #endif

View File

@ -35,8 +35,6 @@
#include "timing.h" #include "timing.h"
#include "util.h" #include "util.h"
#include "hash_table.h"
NEXTPNR_NAMESPACE_BEGIN NEXTPNR_NAMESPACE_BEGIN
class TimingOptimiser class TimingOptimiser
@ -167,7 +165,7 @@ class TimingOptimiser
BelId curr = cell->bel; BelId curr = cell->bel;
Loc curr_loc = ctx->getBelLocation(curr); Loc curr_loc = ctx->getBelLocation(curr);
int found_count = 0; int found_count = 0;
cell_neighbour_bels[cell->name] = std::unordered_set<BelId>{}; cell_neighbour_bels[cell->name] = pool<BelId>{};
for (int dy = -d; dy <= d; dy++) { for (int dy = -d; dy <= d; dy++) {
for (int dx = -d; dx <= d; dx++) { for (int dx = -d; dx <= d; dx++) {
// Go through all the Bels at this location // Go through all the Bels at this location
@ -267,7 +265,7 @@ class TimingOptimiser
} }
NPNR_ASSERT_FALSE("port user not found on net"); NPNR_ASSERT_FALSE("port user not found on net");
}; };
std::unordered_set<PortRef *> used_ports; pool<PortRef *, hash_ptr_ops> used_ports;
for (auto crit_net : crit_nets) { for (auto crit_net : crit_nets) {
@ -439,10 +437,10 @@ class TimingOptimiser
} }
// Actual BFS path optimisation algorithm // Actual BFS path optimisation algorithm
std::unordered_map<IdString, std::unordered_map<BelId, delay_t>> cumul_costs; dict<IdString, dict<BelId, delay_t>> cumul_costs;
std::unordered_map<std::pair<IdString, BelId>, std::pair<IdString, BelId>, PairHash> backtrace; dict<std::pair<IdString, BelId>, std::pair<IdString, BelId>> backtrace;
std::queue<std::pair<int, BelId>> visit; std::queue<std::pair<int, BelId>> visit;
std::unordered_set<std::pair<int, BelId>, PairHash> to_visit; pool<std::pair<int, BelId>> to_visit;
for (auto startbel : cell_neighbour_bels[path_cells.front()]) { for (auto startbel : cell_neighbour_bels[path_cells.front()]) {
// Swap for legality check // Swap for legality check
@ -568,10 +566,10 @@ class TimingOptimiser
// Current candidate Bels for cells (linked in both direction> // Current candidate Bels for cells (linked in both direction>
std::vector<IdString> path_cells; std::vector<IdString> path_cells;
std::unordered_map<IdString, std::unordered_set<BelId>> cell_neighbour_bels; dict<IdString, pool<BelId>> cell_neighbour_bels;
std::unordered_map<BelId, std::unordered_set<IdString>> bel_candidate_cells; dict<BelId, pool<IdString>> bel_candidate_cells;
// Map cell ports to net delay limit // Map cell ports to net delay limit
std::unordered_map<std::pair<IdString, IdString>, delay_t, PairHash> max_net_delay; dict<std::pair<IdString, IdString>, delay_t> max_net_delay;
Context *ctx; Context *ctx;
TimingOptCfg cfg; TimingOptCfg cfg;
TimingAnalyser tmg; TimingAnalyser tmg;

View File

@ -29,7 +29,7 @@ struct TimingOptCfg
// The timing optimiser will *only* optimise cells of these types // The timing optimiser will *only* optimise cells of these types
// Normally these would only be logic cells (or tiles if applicable), the algorithm makes little sense // Normally these would only be logic cells (or tiles if applicable), the algorithm makes little sense
// for other cell types // for other cell types
std::unordered_set<IdString> cellTypes; pool<IdString> cellTypes;
}; };
extern bool timing_opt(Context *ctx, TimingOptCfg cfg); extern bool timing_opt(Context *ctx, TimingOptCfg cfg);

View File

@ -34,7 +34,7 @@ class ECP5CommandHandler : public CommandHandler
public: public:
ECP5CommandHandler(int argc, char **argv); ECP5CommandHandler(int argc, char **argv);
virtual ~ECP5CommandHandler(){}; virtual ~ECP5CommandHandler(){};
std::unique_ptr<Context> createContext(std::unordered_map<std::string, Property> &values) override; std::unique_ptr<Context> createContext(dict<std::string, Property> &values) override;
void setupArchContext(Context *ctx) override{}; void setupArchContext(Context *ctx) override{};
void customAfterLoad(Context *ctx) override; void customAfterLoad(Context *ctx) override;
void validate() override; void validate() override;
@ -132,7 +132,7 @@ static std::string speedString(ArchArgs::SpeedGrade speed)
return ""; return "";
} }
std::unique_ptr<Context> ECP5CommandHandler::createContext(std::unordered_map<std::string, Property> &values) std::unique_ptr<Context> ECP5CommandHandler::createContext(dict<std::string, Property> &values)
{ {
ArchArgs chipArgs; ArchArgs chipArgs;
chipArgs.type = ArchArgs::NONE; chipArgs.type = ArchArgs::NONE;

View File

@ -36,7 +36,7 @@ class FpgaInterchangeCommandHandler : public CommandHandler
public: public:
FpgaInterchangeCommandHandler(int argc, char **argv); FpgaInterchangeCommandHandler(int argc, char **argv);
virtual ~FpgaInterchangeCommandHandler(){}; virtual ~FpgaInterchangeCommandHandler(){};
std::unique_ptr<Context> createContext(std::unordered_map<std::string, Property> &values) override; std::unique_ptr<Context> createContext(dict<std::string, Property> &values) override;
void setupArchContext(Context *ctx) override{}; void setupArchContext(Context *ctx) override{};
void customBitstream(Context *ctx) override; void customBitstream(Context *ctx) override;
void customAfterLoad(Context *ctx) override; void customAfterLoad(Context *ctx) override;
@ -69,7 +69,7 @@ void FpgaInterchangeCommandHandler::customBitstream(Context *ctx)
} }
} }
std::unique_ptr<Context> FpgaInterchangeCommandHandler::createContext(std::unordered_map<std::string, Property> &values) std::unique_ptr<Context> FpgaInterchangeCommandHandler::createContext(dict<std::string, Property> &values)
{ {
auto start = std::chrono::high_resolution_clock::now(); auto start = std::chrono::high_resolution_clock::now();

View File

@ -32,7 +32,7 @@ class GenericCommandHandler : public CommandHandler
public: public:
GenericCommandHandler(int argc, char **argv); GenericCommandHandler(int argc, char **argv);
virtual ~GenericCommandHandler(){}; virtual ~GenericCommandHandler(){};
std::unique_ptr<Context> createContext(std::unordered_map<std::string, Property> &values) override; std::unique_ptr<Context> createContext(dict<std::string, Property> &values) override;
void setupArchContext(Context *ctx) override{}; void setupArchContext(Context *ctx) override{};
void customBitstream(Context *ctx) override; void customBitstream(Context *ctx) override;
@ -52,7 +52,7 @@ po::options_description GenericCommandHandler::getArchOptions()
void GenericCommandHandler::customBitstream(Context *ctx) {} void GenericCommandHandler::customBitstream(Context *ctx) {}
std::unique_ptr<Context> GenericCommandHandler::createContext(std::unordered_map<std::string, Property> &values) std::unique_ptr<Context> GenericCommandHandler::createContext(dict<std::string, Property> &values)
{ {
ArchArgs chipArgs; ArchArgs chipArgs;
if (values.find("arch.name") != values.end()) { if (values.find("arch.name") != values.end()) {

View File

@ -34,7 +34,7 @@ class GowinCommandHandler : public CommandHandler
public: public:
GowinCommandHandler(int argc, char **argv); GowinCommandHandler(int argc, char **argv);
virtual ~GowinCommandHandler(){}; virtual ~GowinCommandHandler(){};
std::unique_ptr<Context> createContext(std::unordered_map<std::string, Property> &values) override; std::unique_ptr<Context> createContext(dict<std::string, Property> &values) override;
void setupArchContext(Context *ctx) override{}; void setupArchContext(Context *ctx) override{};
void customAfterLoad(Context *ctx) override; void customAfterLoad(Context *ctx) override;
@ -52,7 +52,7 @@ po::options_description GowinCommandHandler::getArchOptions()
return specific; return specific;
} }
std::unique_ptr<Context> GowinCommandHandler::createContext(std::unordered_map<std::string, Property> &values) std::unique_ptr<Context> GowinCommandHandler::createContext(dict<std::string, Property> &values)
{ {
std::regex devicere = std::regex("GW1N([A-Z]*)-(LV|UV)([0-9])([A-Z]{2}[0-9]+)(C[0-9]/I[0-9])"); std::regex devicere = std::regex("GW1N([A-Z]*)-(LV|UV)([0-9])([A-Z]{2}[0-9]+)(C[0-9]/I[0-9])");
std::smatch match; std::smatch match;

View File

@ -58,7 +58,7 @@ void IdList::updateElements(Context *ctx, std::vector<IdStringList> elements)
bool changed = false; bool changed = false;
// For any elements that are not yet in managed_, created them. // For any elements that are not yet in managed_, created them.
std::unordered_set<IdStringList> element_set; pool<IdStringList> element_set;
for (auto elem : elements) { for (auto elem : elements) {
element_set.insert(elem); element_set.insert(elem);
auto existing = managed_.find(elem); auto existing = managed_.find(elem);

View File

@ -140,7 +140,7 @@ class IdList : public Item
private: private:
// Children that we manage the memory for, stored for quick lookup from // Children that we manage the memory for, stored for quick lookup from
// IdString to child. // IdString to child.
std::unordered_map<IdStringList, std::unique_ptr<IdStringItem>> managed_; dict<IdStringList, std::unique_ptr<IdStringItem>> managed_;
// Type of children that the list creates. // Type of children that the list creates.
ElementType child_type_; ElementType child_type_;
@ -184,7 +184,7 @@ template <typename ElementT> class ElementList : public Item
ElementGetter getter_; ElementGetter getter_;
// Children that we manage the memory for, stored for quick lookup from // Children that we manage the memory for, stored for quick lookup from
// IdString to child. // IdString to child.
std::unordered_map<IdStringList, std::unique_ptr<Item>> managed_; dict<IdStringList, std::unique_ptr<Item>> managed_;
// Type of children that he list creates. // Type of children that he list creates.
ElementType child_type_; ElementType child_type_;

View File

@ -35,7 +35,7 @@ class Ice40CommandHandler : public CommandHandler
public: public:
Ice40CommandHandler(int argc, char **argv); Ice40CommandHandler(int argc, char **argv);
virtual ~Ice40CommandHandler(){}; virtual ~Ice40CommandHandler(){};
std::unique_ptr<Context> createContext(std::unordered_map<std::string, Property> &values) override; std::unique_ptr<Context> createContext(dict<std::string, Property> &values) override;
void setupArchContext(Context *ctx) override; void setupArchContext(Context *ctx) override;
void validate() override; void validate() override;
void customAfterLoad(Context *ctx) override; void customAfterLoad(Context *ctx) override;
@ -129,7 +129,7 @@ void Ice40CommandHandler::setupArchContext(Context *ctx)
} }
} }
std::unique_ptr<Context> Ice40CommandHandler::createContext(std::unordered_map<std::string, Property> &values) std::unique_ptr<Context> Ice40CommandHandler::createContext(dict<std::string, Property> &values)
{ {
ArchArgs chipArgs; ArchArgs chipArgs;
chipArgs.type = ArchArgs::NONE; chipArgs.type = ArchArgs::NONE;

View File

@ -67,7 +67,7 @@ struct PortGroup
std::vector<PortGroup> group_ports(Context *ctx, const dict<IdString, PortInfo> &ports, bool is_cell = false) std::vector<PortGroup> group_ports(Context *ctx, const dict<IdString, PortInfo> &ports, bool is_cell = false)
{ {
std::vector<PortGroup> groups; std::vector<PortGroup> groups;
std::unordered_map<std::string, size_t> base_to_group; dict<std::string, size_t> base_to_group;
for (auto &pair : ports) { for (auto &pair : ports) {
std::string name = pair.second.name.str(ctx); std::string name = pair.second.name.str(ctx);
if ((name.back() != ']') || (name.find('[') == std::string::npos)) { if ((name.back() != ']') || (name.find('[') == std::string::npos)) {

View File

@ -34,7 +34,7 @@ class MachXO2CommandHandler : public CommandHandler
public: public:
MachXO2CommandHandler(int argc, char **argv); MachXO2CommandHandler(int argc, char **argv);
virtual ~MachXO2CommandHandler(){}; virtual ~MachXO2CommandHandler(){};
std::unique_ptr<Context> createContext(std::unordered_map<std::string, Property> &values) override; std::unique_ptr<Context> createContext(dict<std::string, Property> &values) override;
void setupArchContext(Context *ctx) override{}; void setupArchContext(Context *ctx) override{};
void customBitstream(Context *ctx) override; void customBitstream(Context *ctx) override;
@ -82,7 +82,7 @@ void MachXO2CommandHandler::customBitstream(Context *ctx)
write_bitstream(ctx, textcfg); write_bitstream(ctx, textcfg);
} }
std::unique_ptr<Context> MachXO2CommandHandler::createContext(std::unordered_map<std::string, Property> &values) std::unique_ptr<Context> MachXO2CommandHandler::createContext(dict<std::string, Property> &values)
{ {
ArchArgs chipArgs; ArchArgs chipArgs;
chipArgs.type = ArchArgs::NONE; chipArgs.type = ArchArgs::NONE;

View File

@ -33,7 +33,7 @@ class MistralCommandHandler : public CommandHandler
public: public:
MistralCommandHandler(int argc, char **argv); MistralCommandHandler(int argc, char **argv);
virtual ~MistralCommandHandler(){}; virtual ~MistralCommandHandler(){};
std::unique_ptr<Context> createContext(std::unordered_map<std::string, Property> &values) override; std::unique_ptr<Context> createContext(dict<std::string, Property> &values) override;
void setupArchContext(Context *ctx) override{}; void setupArchContext(Context *ctx) override{};
void customBitstream(Context *ctx) override; void customBitstream(Context *ctx) override;
void customAfterLoad(Context *ctx) override; void customAfterLoad(Context *ctx) override;
@ -71,7 +71,7 @@ void MistralCommandHandler::customBitstream(Context *ctx)
} }
} }
std::unique_ptr<Context> MistralCommandHandler::createContext(std::unordered_map<std::string, Property> &values) std::unique_ptr<Context> MistralCommandHandler::createContext(dict<std::string, Property> &values)
{ {
ArchArgs chipArgs; ArchArgs chipArgs;
if (!vm.count("mistral")) { if (!vm.count("mistral")) {

View File

@ -33,7 +33,7 @@ class NexusCommandHandler : public CommandHandler
public: public:
NexusCommandHandler(int argc, char **argv); NexusCommandHandler(int argc, char **argv);
virtual ~NexusCommandHandler(){}; virtual ~NexusCommandHandler(){};
std::unique_ptr<Context> createContext(std::unordered_map<std::string, Property> &values) override; std::unique_ptr<Context> createContext(dict<std::string, Property> &values) override;
void setupArchContext(Context *ctx) override{}; void setupArchContext(Context *ctx) override{};
void customBitstream(Context *ctx) override; void customBitstream(Context *ctx) override;
void customAfterLoad(Context *ctx) override; void customAfterLoad(Context *ctx) override;
@ -66,7 +66,7 @@ void NexusCommandHandler::customBitstream(Context *ctx)
} }
} }
std::unique_ptr<Context> NexusCommandHandler::createContext(std::unordered_map<std::string, Property> &values) std::unique_ptr<Context> NexusCommandHandler::createContext(dict<std::string, Property> &values)
{ {
ArchArgs chipArgs; ArchArgs chipArgs;
if (!vm.count("device")) { if (!vm.count("device")) {