Skip to content

Commit da1866d

Browse files
authored
Use hash maps wherever possible (#289)
* Implement legate::hash and change some of the caches to unordered_map * Use hash maps wherever applicable * Remove unused parameter * Fix for clang-tidy errors * Address review comments * Make the use of custom hashers explicit in definitions * Address review comments and turn some of the hashers to std::hash * Minor clean-up
1 parent 7ca1dd8 commit da1866d

35 files changed

Lines changed: 315 additions & 255 deletions

legate_core_cpp.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,7 @@ install(
565565
FILES src/core/utilities/debug.h
566566
src/core/utilities/debug.inl
567567
src/core/utilities/dispatch.h
568+
src/core/utilities/hash.h
568569
src/core/utilities/machine.h
569570
src/core/utilities/memory.h
570571
src/core/utilities/memory.inl

src/core/data/detail/logical_array.cc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ void BaseLogicalArray::record_scalar_reductions(AutoTask* task, Legion::Reductio
141141

142142
void BaseLogicalArray::generate_constraints(
143143
AutoTask* task,
144-
std::map<std::shared_ptr<LogicalStore>, const Variable*>& mapping,
144+
std::unordered_map<std::shared_ptr<LogicalStore>, const Variable*>& mapping,
145145
const Variable* partition_symbol) const
146146
{
147147
mapping.try_emplace(data_, partition_symbol);
@@ -155,7 +155,7 @@ void BaseLogicalArray::generate_constraints(
155155
}
156156

157157
std::unique_ptr<Analyzable> BaseLogicalArray::to_launcher_arg(
158-
const std::map<std::shared_ptr<LogicalStore>, const Variable*>& mapping,
158+
const std::unordered_map<std::shared_ptr<LogicalStore>, const Variable*>& mapping,
159159
const Strategy& strategy,
160160
const Domain& launch_domain,
161161
const std::optional<SymbolicPoint>& projection,
@@ -273,7 +273,7 @@ void ListLogicalArray::record_scalar_reductions(AutoTask* task, Legion::Reductio
273273

274274
void ListLogicalArray::generate_constraints(
275275
AutoTask* task,
276-
std::map<std::shared_ptr<LogicalStore>, const Variable*>& mapping,
276+
std::unordered_map<std::shared_ptr<LogicalStore>, const Variable*>& mapping,
277277
const Variable* partition_symbol) const
278278
{
279279
descriptor_->generate_constraints(task, mapping, partition_symbol);
@@ -285,7 +285,7 @@ void ListLogicalArray::generate_constraints(
285285
}
286286

287287
std::unique_ptr<Analyzable> ListLogicalArray::to_launcher_arg(
288-
const std::map<std::shared_ptr<LogicalStore>, const Variable*>& mapping,
288+
const std::unordered_map<std::shared_ptr<LogicalStore>, const Variable*>& mapping,
289289
const Strategy& strategy,
290290
const Domain& launch_domain,
291291
const std::optional<SymbolicPoint>& projection,
@@ -452,7 +452,7 @@ void StructLogicalArray::record_scalar_reductions(AutoTask* task, Legion::Reduct
452452

453453
void StructLogicalArray::generate_constraints(
454454
AutoTask* task,
455-
std::map<std::shared_ptr<LogicalStore>, const Variable*>& mapping,
455+
std::unordered_map<std::shared_ptr<LogicalStore>, const Variable*>& mapping,
456456
const Variable* partition_symbol) const
457457
{
458458
auto it = fields_.begin();
@@ -472,7 +472,7 @@ void StructLogicalArray::generate_constraints(
472472
}
473473

474474
std::unique_ptr<Analyzable> StructLogicalArray::to_launcher_arg(
475-
const std::map<std::shared_ptr<LogicalStore>, const Variable*>& mapping,
475+
const std::unordered_map<std::shared_ptr<LogicalStore>, const Variable*>& mapping,
476476
const Strategy& strategy,
477477
const Domain& launch_domain,
478478
const std::optional<SymbolicPoint>& projection,

src/core/data/detail/logical_array.h

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <map>
2121
#include <memory>
2222
#include <optional>
23+
#include <unordered_map>
2324
#include <vector>
2425

2526
namespace legate::detail {
@@ -68,11 +69,11 @@ struct LogicalArray {
6869

6970
virtual void generate_constraints(
7071
AutoTask* task,
71-
std::map<std::shared_ptr<LogicalStore>, const Variable*>& mapping,
72+
std::unordered_map<std::shared_ptr<LogicalStore>, const Variable*>& mapping,
7273
const Variable* partition_symbol) const = 0;
7374

7475
[[nodiscard]] virtual std::unique_ptr<Analyzable> to_launcher_arg(
75-
const std::map<std::shared_ptr<LogicalStore>, const Variable*>& mapping,
76+
const std::unordered_map<std::shared_ptr<LogicalStore>, const Variable*>& mapping,
7677
const Strategy& strategy,
7778
const Domain& launch_domain,
7879
const std::optional<SymbolicPoint>& projection,
@@ -119,12 +120,13 @@ class BaseLogicalArray final : public LogicalArray {
119120
void record_scalar_or_unbound_outputs(AutoTask* task) const override;
120121
void record_scalar_reductions(AutoTask* task, Legion::ReductionOpID redop) const override;
121122

122-
void generate_constraints(AutoTask* task,
123-
std::map<std::shared_ptr<LogicalStore>, const Variable*>& mapping,
124-
const Variable* partition_symbol) const override;
123+
void generate_constraints(
124+
AutoTask* task,
125+
std::unordered_map<std::shared_ptr<LogicalStore>, const Variable*>& mapping,
126+
const Variable* partition_symbol) const override;
125127

126128
[[nodiscard]] std::unique_ptr<Analyzable> to_launcher_arg(
127-
const std::map<std::shared_ptr<LogicalStore>, const Variable*>& mapping,
129+
const std::unordered_map<std::shared_ptr<LogicalStore>, const Variable*>& mapping,
128130
const Strategy& strategy,
129131
const Domain& launch_domain,
130132
const std::optional<SymbolicPoint>& projection,
@@ -173,12 +175,13 @@ class ListLogicalArray final : public LogicalArray {
173175
void record_scalar_or_unbound_outputs(AutoTask* task) const override;
174176
void record_scalar_reductions(AutoTask* task, Legion::ReductionOpID redop) const override;
175177

176-
void generate_constraints(AutoTask* task,
177-
std::map<std::shared_ptr<LogicalStore>, const Variable*>& mapping,
178-
const Variable* partition_symbol) const override;
178+
void generate_constraints(
179+
AutoTask* task,
180+
std::unordered_map<std::shared_ptr<LogicalStore>, const Variable*>& mapping,
181+
const Variable* partition_symbol) const override;
179182

180183
[[nodiscard]] std::unique_ptr<Analyzable> to_launcher_arg(
181-
const std::map<std::shared_ptr<LogicalStore>, const Variable*>& mapping,
184+
const std::unordered_map<std::shared_ptr<LogicalStore>, const Variable*>& mapping,
182185
const Strategy& strategy,
183186
const Domain& launch_domain,
184187
const std::optional<SymbolicPoint>& projection,
@@ -226,12 +229,13 @@ class StructLogicalArray final : public LogicalArray {
226229
void record_scalar_or_unbound_outputs(AutoTask* task) const override;
227230
void record_scalar_reductions(AutoTask* task, Legion::ReductionOpID redop) const override;
228231

229-
void generate_constraints(AutoTask* task,
230-
std::map<std::shared_ptr<LogicalStore>, const Variable*>& mapping,
231-
const Variable* partition_symbol) const override;
232+
void generate_constraints(
233+
AutoTask* task,
234+
std::unordered_map<std::shared_ptr<LogicalStore>, const Variable*>& mapping,
235+
const Variable* partition_symbol) const override;
232236

233237
[[nodiscard]] std::unique_ptr<Analyzable> to_launcher_arg(
234-
const std::map<std::shared_ptr<LogicalStore>, const Variable*>& mapping,
238+
const std::unordered_map<std::shared_ptr<LogicalStore>, const Variable*>& mapping,
235239
const Strategy& strategy,
236240
const Domain& launch_domain,
237241
const std::optional<SymbolicPoint>& projection,

src/core/mapping/detail/base_mapper.cc

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -487,8 +487,7 @@ void BaseMapper::map_task(Legion::Mapping::MapperContext ctx,
487487
map_unbound_stores(for_unbound_stores);
488488

489489
output.chosen_instances.resize(task.regions.size());
490-
std::map<const Legion::RegionRequirement*, std::vector<Legion::Mapping::PhysicalInstance>*>
491-
output_map;
490+
OutputMap output_map;
492491
for (uint32_t idx = 0; idx < task.regions.size(); ++idx) {
493492
output_map[&task.regions[idx]] = &output.chosen_instances[idx];
494493
}
@@ -1066,8 +1065,7 @@ void BaseMapper::map_inline(Legion::Mapping::MapperContext ctx,
10661065

10671066
mappings.push_back(StoreMapping::default_mapping(&store, store_target, false));
10681067

1069-
std::map<const Legion::RegionRequirement*, std::vector<Legion::Mapping::PhysicalInstance>*>
1070-
output_map;
1068+
OutputMap output_map;
10711069
auto&& reqs = mappings.front()->requirements();
10721070
for (auto* req : reqs) {
10731071
output_map[req] = &output.chosen_instances;
@@ -1146,8 +1144,7 @@ void BaseMapper::map_copy(Legion::Mapping::MapperContext ctx,
11461144

11471145
auto store_target = default_store_targets(target_proc.kind()).front();
11481146

1149-
std::map<const Legion::RegionRequirement*, std::vector<Legion::Mapping::PhysicalInstance>*>
1150-
output_map;
1147+
OutputMap output_map;
11511148
auto add_to_output_map = [&output_map](auto& reqs, auto& instances) {
11521149
instances.resize(reqs.size());
11531150
for (uint32_t idx = 0; idx < reqs.size(); ++idx) {
@@ -1339,8 +1336,7 @@ void BaseMapper::map_partition(Legion::Mapping::MapperContext ctx,
13391336
std::vector<std::unique_ptr<StoreMapping>> mappings;
13401337
mappings.push_back(StoreMapping::default_mapping(&store, store_target, false));
13411338

1342-
std::map<const Legion::RegionRequirement*, std::vector<Legion::Mapping::PhysicalInstance>*>
1343-
output_map;
1339+
OutputMap output_map;
13441340
auto&& reqs = mappings.front()->requirements();
13451341
for (auto* req : reqs) {
13461342
output_map[req] = &output.chosen_instances;

src/core/mapping/detail/base_mapper.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,16 @@
1616
#include "core/mapping/detail/machine.h"
1717
#include "core/mapping/detail/mapping.h"
1818
#include "core/runtime/detail/library.h"
19+
#include "core/utilities/detail/hash.h"
1920
#include "core/utilities/typedefs.h"
2021

2122
#include "legion.h"
2223

23-
#include <map>
2424
#include <memory>
2525
#include <optional>
2626
#include <set>
2727
#include <string>
28+
#include <unordered_map>
2829
#include <vector>
2930

3031
namespace legate::mapping::detail {
@@ -246,8 +247,8 @@ class BaseMapper final : public Legion::Mapping::Mapper, public MachineQueryInte
246247
const MapperTaskResult& result) override;
247248

248249
protected:
249-
using OutputMap =
250-
std::map<const Legion::RegionRequirement*, std::vector<Legion::Mapping::PhysicalInstance>*>;
250+
using OutputMap = std::unordered_map<const Legion::RegionRequirement*,
251+
std::vector<Legion::Mapping::PhysicalInstance>*>;
251252
void map_legate_stores(Legion::Mapping::MapperContext ctx,
252253
const Legion::Mappable& mappable,
253254
std::vector<std::unique_ptr<StoreMapping>>& mappings,
@@ -296,7 +297,8 @@ class BaseMapper final : public Legion::Mapping::Mapper, public MachineQueryInte
296297

297298
protected:
298299
using VariantCacheKey = std::pair<Legion::TaskID, Processor::Kind>;
299-
std::map<VariantCacheKey, std::optional<Legion::VariantID>> variants{};
300+
std::unordered_map<VariantCacheKey, std::optional<Legion::VariantID>, hasher<VariantCacheKey>>
301+
variants{};
300302

301303
InstanceManager* local_instances{};
302304
ReductionInstanceManager* reduction_instances{};

src/core/mapping/detail/instance_manager.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,10 @@ bool too_big(size_t union_volume, size_t my_volume, size_t group_volume, size_t
103103

104104
struct construct_overlapping_region_group_fn {
105105
template <int32_t DIM>
106-
RegionGroupP operator()(const InstanceSet::Region& region,
107-
const Domain& domain,
108-
const std::map<RegionGroup*, InstanceSet::InstanceSpec>& instances)
106+
RegionGroupP operator()(
107+
const InstanceSet::Region& region,
108+
const Domain& domain,
109+
const std::unordered_map<RegionGroup*, InstanceSet::InstanceSpec>& instances)
109110
{
110111
auto bound = domain.bounds<DIM, coord_t>();
111112
size_t bound_vol = bound.volume();

src/core/mapping/detail/instance_manager.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,14 @@
1313
#pragma once
1414

1515
#include "core/mapping/mapping.h"
16+
#include "core/utilities/detail/hash.h"
17+
#include "core/utilities/hash.h"
1618

1719
#include <iosfwd>
1820
#include <map>
1921
#include <memory>
2022
#include <set>
23+
#include <unordered_map>
2124
#include <vector>
2225

2326
namespace legate::mapping::detail {
@@ -36,7 +39,7 @@ struct RegionGroup {
3639

3740
std::set<Region> regions{};
3841
Domain bounding_box{};
39-
std::map<const RegionGroup*, bool> subsumption_cache{};
42+
std::unordered_map<const RegionGroup*, bool> subsumption_cache{};
4043
};
4144

4245
std::ostream& operator<<(std::ostream& os, const RegionGroup& region_group);
@@ -88,8 +91,8 @@ class InstanceSet { // NOLINT(bugprone-forward-declaration-namespace)
8891
private:
8992
void dump_and_sanity_check() const;
9093

91-
std::map<RegionGroup*, InstanceSpec> instances_{};
92-
std::map<Legion::LogicalRegion, RegionGroupP> groups_{};
94+
std::unordered_map<RegionGroup*, InstanceSpec> instances_{};
95+
std::unordered_map<Region, RegionGroupP> groups_{};
9396
};
9497

9598
class ReductionInstanceSet {
@@ -120,7 +123,7 @@ class ReductionInstanceSet {
120123
bool erase(const Instance& inst);
121124

122125
private:
123-
std::map<Region, ReductionInstanceSpec> instances_{};
126+
std::unordered_map<Region, ReductionInstanceSpec> instances_{};
124127
};
125128

126129
class BaseInstanceManager {
@@ -135,7 +138,7 @@ class BaseInstanceManager {
135138
FieldMemInfo(RegionTreeID t, FieldID f, Memory m);
136139

137140
bool operator==(const FieldMemInfo& rhs) const;
138-
bool operator<(const FieldMemInfo& rhs) const;
141+
[[nodiscard]] size_t hash() const noexcept;
139142

140143
RegionTreeID tid;
141144
FieldID fid;
@@ -174,7 +177,7 @@ class InstanceManager : public BaseInstanceManager {
174177
[[nodiscard]] std::map<Memory, size_t> aggregate_instance_sizes() const;
175178

176179
private:
177-
std::map<FieldMemInfo, InstanceSet> instance_sets_{};
180+
std::unordered_map<FieldMemInfo, InstanceSet, hasher<FieldMemInfo>> instance_sets_{};
178181
};
179182

180183
class ReductionInstanceManager : public BaseInstanceManager {
@@ -199,7 +202,7 @@ class ReductionInstanceManager : public BaseInstanceManager {
199202
[[nodiscard]] static ReductionInstanceManager* get_instance_manager();
200203

201204
private:
202-
std::map<FieldMemInfo, ReductionInstanceSet> instance_sets_{};
205+
std::unordered_map<FieldMemInfo, ReductionInstanceSet, hasher<FieldMemInfo>> instance_sets_{};
203206
};
204207

205208
} // namespace legate::mapping::detail

src/core/mapping/detail/instance_manager.inl

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -61,21 +61,9 @@ inline bool BaseInstanceManager::FieldMemInfo::operator==(const FieldMemInfo& rh
6161
return tid == rhs.tid && fid == rhs.fid && memory == rhs.memory;
6262
}
6363

64-
inline bool BaseInstanceManager::FieldMemInfo::operator<(const FieldMemInfo& rhs) const
64+
inline size_t BaseInstanceManager::FieldMemInfo::hash() const noexcept
6565
{
66-
if (tid < rhs.tid) {
67-
return true;
68-
}
69-
if (tid > rhs.tid) {
70-
return false;
71-
}
72-
if (fid < rhs.fid) {
73-
return true;
74-
}
75-
if (fid > rhs.fid) {
76-
return false;
77-
}
78-
return memory < rhs.memory;
66+
return hash_all(tid, fid, memory.id);
7967
}
8068

8169
inline Legion::Mapping::LocalLock& BaseInstanceManager::manager_lock() { return manager_lock_; }

src/core/mapping/machine.cc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@
1010
* its affiliates is strictly prohibited.
1111
*/
1212

13-
#include "core/mapping/detail/machine.h"
14-
1513
#include "core/mapping/machine.h"
1614

15+
#include "core/mapping/detail/machine.h"
16+
#include "core/utilities/hash.h"
17+
1718
#include <iostream>
1819
#include <sstream>
1920
#include <stdexcept>
@@ -73,6 +74,8 @@ bool ProcessorRange::operator<(const ProcessorRange& other) const noexcept
7374
return per_node_count < other.per_node_count;
7475
}
7576

77+
size_t ProcessorRange::hash() const noexcept { return hash_all(low, high, per_node_count); }
78+
7679
std::ostream& operator<<(std::ostream& stream, const ProcessorRange& range)
7780
{
7881
stream << range.to_string();

src/core/mapping/machine.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ struct ProcessorRange {
112112
bool operator==(const ProcessorRange& other) const noexcept;
113113
bool operator!=(const ProcessorRange& other) const noexcept;
114114
bool operator<(const ProcessorRange& other) const noexcept;
115+
[[nodiscard]] size_t hash() const noexcept;
115116
};
116117

117118
std::ostream& operator<<(std::ostream& stream, const ProcessorRange& range);

0 commit comments

Comments
 (0)