Loading [MathJax]/extensions/tex2jax.js
CIRCT 21.0.0git
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Problems.h
Go to the documentation of this file.
1//===- Problems.h - Modeling of scheduling problems -------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Static scheduling algorithms for use in HLS flows all solve similar problems.
10// The classes in this file serve as an interface between clients and algorithm
11// implementations, and model a basic scheduling problem and some commonly used
12// extensions (e.g. modulo scheduling). This includes problem-specific
13// verification methods.
14//
15//===----------------------------------------------------------------------===//
16
17#ifndef CIRCT_SCHEDULING_PROBLEMS_H
18#define CIRCT_SCHEDULING_PROBLEMS_H
19
21#include "circt/Support/LLVM.h"
22
23#include "mlir/IR/BuiltinAttributes.h"
24#include "llvm/ADT/DenseMap.h"
25#include "llvm/ADT/SetVector.h"
26
27#include <optional>
28
29namespace circt {
30namespace scheduling {
31
32/// This class models the most basic scheduling problem.
33///
34/// A problem instance is comprised of:
35///
36/// - *Operations*: The vertices in the data-flow graph to be scheduled.
37/// - *Dependences*: The edges in the data-flow graph to be scheduled, modeling
38/// a precedence relation between the involved operations.
39/// - *Operator types*: An abstraction of the characteristics of the target
40/// representation, e.g. modules in the HLS component library, available
41/// functional units, etc. -- operations are executed on instances/units of
42/// an operator type.
43///
44/// Operations and operator types are stored explicitly. The registered
45/// operations induce a subgraph of the SSA graph. We implicitly include the
46/// dependences corresponding to its *def-use* relationships in the problem,
47/// e.g. if operation *y*'s second operand uses the first result produced by
48/// *x*, we'd have a dependence `x:0 --> y:1`. Clients can additionally register
49/// explicit, *auxiliary* dependence between operations, e.g. to encode memory
50/// dependencies or other ordering constraints. Auxiliary dependences do not
51/// distinguish specific operands/results. The differences between the flavors
52/// are transparent to concrete algorithms.
53///
54/// All components of the problem (operations, dependences, operator types, as
55/// well as the instance itself) can be annotated with *properties*. In this
56/// basic problem, we model
57///
58/// - `linkedOperatorType` maps operations to their operator types.
59/// - `latency`, an operator type-property denoting the number of time steps
60/// after which the operator's result is available.
61/// - `startTime`, an operation-property for the time step in which an operation
62/// is started. Together, the start times for all operations represent the
63/// problem's solution, i.e. the schedule.
64///
65/// Subclasses, i.e. corresponding to more complex scheduling problems, can
66/// declare additional properties as needed.
67//
68/// The `check...` methods perform validity checks before scheduling, e.g. that
69/// all operations have an associated operator type, etc.
70///
71/// The `verify...` methods check the correctness of the solution determined by
72/// a concrete scheduling algorithm, e.g. that there are start times available
73/// for each registered operation, and the precedence constraints as modeled by
74/// the dependences are satisfied.
75class Problem {
76public:
77 static constexpr auto name = "Problem";
78
79 /// Construct an empty scheduling problem. \p containingOp is used for its
80 /// MLIRContext and to emit diagnostics.
81 explicit Problem(Operation *containingOp) : containingOp(containingOp) {}
82 virtual ~Problem() = default;
83
85
86protected:
87 Problem() = default;
88
89 //===--------------------------------------------------------------------===//
90 // Aliases for the problem components
91 //===--------------------------------------------------------------------===//
92public:
93 /// A thin wrapper to allow a uniform handling of def-use and auxiliary
94 /// dependences.
96
97 /// Operator types are distinguished by name (chosen by the client).
98 struct OperatorType {
99 mlir::StringAttr attr;
100
101 OperatorType() = default;
102 OperatorType(mlir::StringAttr attr) : attr(attr) {}
103
104 static OperatorType get(mlir::MLIRContext *ctx, llvm::StringRef name) {
105 return OperatorType{mlir::StringAttr::get(ctx, name)};
106 }
107
108 mlir::StringAttr getAttr() const { return attr; }
109
110 mlir::StringRef getValue() const { return attr.getValue(); }
111
112 std::string str() const { return attr.str(); }
113
114 friend bool operator==(const OperatorType &lhs, const OperatorType &rhs) {
115 return lhs.attr == rhs.attr;
116 }
117 };
118
119 /// Resource types are distinguished by name (chosen by the client).
121 mlir::StringAttr attr;
122
123 ResourceType() = default;
124 ResourceType(mlir::StringAttr attr) : attr(attr) {}
125
126 static ResourceType get(mlir::MLIRContext *ctx, llvm::StringRef name) {
127 return ResourceType{mlir::StringAttr::get(ctx, name)};
128 }
129
130 mlir::StringAttr getAttr() const { return attr; }
131
132 mlir::StringRef getValue() const { return attr.getValue(); }
133
134 std::string str() const { return attr.str(); }
135
136 friend bool operator==(const ResourceType &lhs, const ResourceType &rhs) {
137 return lhs.attr == rhs.attr;
138 }
139 bool operator!=(const ResourceType &rhs) const { return !(*this == rhs); }
140 };
141
142 //===--------------------------------------------------------------------===//
143 // Aliases for containers storing the problem components and properties
144 //===--------------------------------------------------------------------===//
145public:
146 using OperationSet = llvm::SetVector<Operation *>;
147 using DependenceRange = llvm::iterator_range<detail::DependenceIterator>;
148 using OperatorTypeSet = llvm::SetVector<OperatorType>;
149 using ResourceTypeSet = llvm::SetVector<ResourceType>;
150
151protected:
153 llvm::DenseMap<Operation *, llvm::SmallSetVector<Operation *, 4>>;
154
155 template <typename T>
156 using OperationProperty = llvm::DenseMap<Operation *, std::optional<T>>;
157 template <typename T>
158 using DependenceProperty = llvm::DenseMap<Dependence, std::optional<T>>;
159 template <typename T>
160 using OperatorTypeProperty = llvm::DenseMap<OperatorType, std::optional<T>>;
161 template <typename T>
162 using ResourceTypeProperty = llvm::DenseMap<ResourceType, std::optional<T>>;
163 template <typename T>
164 using InstanceProperty = std::optional<T>;
165
166 //===--------------------------------------------------------------------===//
167 // Containers for problem components and properties
168 //===--------------------------------------------------------------------===//
169private:
170 // Operation containing the ops for this scheduling problem. Used for its
171 // MLIRContext and to emit diagnostics.
172 Operation *containingOp;
173
174 // Problem components
179
180 // Operation properties
184
185 // Operator type properties
187
188 //===--------------------------------------------------------------------===//
189 // Problem construction
190 //===--------------------------------------------------------------------===//
191public:
192 /// Include \p op in this scheduling problem.
193 void insertOperation(Operation *op) { operations.insert(op); }
194
195 /// Include \p dep in the scheduling problem. Return failure if \p dep does
196 /// not represent a valid def-use or auxiliary dependence between operations.
197 /// The endpoints become registered operations w.r.t. the problem.
198 LogicalResult insertDependence(Dependence dep);
199
200 /// Include \p opr in this scheduling problem.
202
203 /// Include \p rsrc in this scheduling problem.
204 void insertResourceType(ResourceType rsrc) { resourceTypes.insert(rsrc); }
205
206 /// Retrieves the operator type identified by the client-specific \p name. The
207 /// operator type is automatically registered in the scheduling problem.
208 OperatorType getOrInsertOperatorType(StringRef name);
209
210 /// Retrieves the resource type identified by the client-specific \p name. The
211 /// resource type is automatically registered in the scheduling problem.
212 ResourceType getOrInsertResourceType(StringRef name);
213
214 //===--------------------------------------------------------------------===//
215 // Access to problem components
216 //===--------------------------------------------------------------------===//
217public:
218 /// Return the operation containing this problem, e.g. to emit diagnostics.
219 Operation *getContainingOp() { return containingOp; }
220 /// Set the operation containing this problem, e.g. to emit diagnostics.
221 void setContainingOp(Operation *op) { containingOp = op; }
222
223 /// Return true if \p op is part of this problem.
224 bool hasOperation(Operation *op) { return operations.contains(op); }
225 /// Return the set of operations.
227
228 /// Return a range object to transparently iterate over \p op's *incoming*
229 /// 1) implicit def-use dependences (backed by the SSA graph), and then
230 /// 2) explictly added auxiliary dependences.
231 ///
232 /// In other words, this yields dependences whose destination operation is
233 /// \p op, and whose source operations are \p op's predecessors in the problem
234 /// graph.
235 ///
236 /// To iterate over all of the scheduling problem's dependences, simply
237 /// process the ranges for all registered operations.
238 DependenceRange getDependences(Operation *op);
239
240 /// Return true if \p opr is part of this problem.
241 bool hasOperatorType(OperatorType opr) { return operatorTypes.contains(opr); }
242 /// Return the set of operator types.
244
245 /// Return true if \p rsrc is part of this problem.
247 return resourceTypes.contains(rsrc);
248 }
249 /// Return the set of resource types.
251 //===--------------------------------------------------------------------===//
252 // Access to properties
253 //===--------------------------------------------------------------------===//
254public:
255 /// The linked operator type provides the runtime characteristics for \p op.
256 std::optional<OperatorType> getLinkedOperatorType(Operation *op) {
257 return linkedOperatorType.lookup(op);
258 }
259 void setLinkedOperatorType(Operation *op, OperatorType opr) {
260 linkedOperatorType[op] = opr;
261 }
262
263 /// The linked resource type provides the available resources for \p op.
264 std::optional<SmallVector<ResourceType>>
265 getLinkedResourceTypes(Operation *op) {
266 return linkedResourceTypes.lookup(op);
267 }
268 void setLinkedResourceTypes(Operation *op, SmallVector<ResourceType> rsrc) {
269 linkedResourceTypes[op] = rsrc;
270 }
271
272 /// The latency is the number of cycles \p opr needs to compute its result.
273 std::optional<unsigned> getLatency(OperatorType opr) {
274 return latency.lookup(opr);
275 }
276 void setLatency(OperatorType opr, unsigned val) { latency[opr] = val; }
277
278 /// Return the start time for \p op, as computed by the scheduler.
279 /// These start times comprise the basic problem's solution, i.e. the
280 /// *schedule*.
281 std::optional<unsigned> getStartTime(Operation *op) {
282 return startTime.lookup(op);
283 }
284 void setStartTime(Operation *op, unsigned val) { startTime[op] = val; }
285
286 //===--------------------------------------------------------------------===//
287 // Access to derived properties
288 //===--------------------------------------------------------------------===//
289public:
290 /// Returns the end time for \p op, as computed by the scheduler.
291 /// This end time is derived from the start time and the operator type's
292 /// latency.
293 std::optional<unsigned> getEndTime(Operation *op);
294
295 //===--------------------------------------------------------------------===//
296 // Optional names (for exporting and debugging instances)
297 //===--------------------------------------------------------------------===//
298private:
301
302public:
303 StringAttr getInstanceName() { return instanceName; }
304 void setInstanceName(StringAttr name) { instanceName = name; }
305
306 StringAttr getLibraryName() { return libraryName; }
307 void setLibraryName(StringAttr name) { libraryName = name; }
308
309 StringAttr getRsrcLibraryName() { return rsrcLibraryName; }
311
312 StringAttr getOperationName(Operation *op) {
313 return operationNames.lookup(op);
314 }
315 void setOperationName(Operation *op, StringAttr name) {
316 operationNames[op] = name;
317 }
318
319 //===--------------------------------------------------------------------===//
320 // Properties as string key-value pairs (e.g. for DOT graphs)
321 //===--------------------------------------------------------------------===//
322public:
324 llvm::SmallVector<std::pair<std::string, std::string>, 2>;
325
326 virtual PropertyStringVector getProperties(Operation *op);
330
332 //===--------------------------------------------------------------------===//
333 // Property-specific validators
334 //===--------------------------------------------------------------------===//
335protected:
336 /// \p op is linked to a registered operator type.
337 virtual LogicalResult checkLinkedOperatorType(Operation *op);
338 /// \p op has a latency.
339 virtual LogicalResult checkLatency(Operation *op);
340 /// \p op has a start time.
341 virtual LogicalResult verifyStartTime(Operation *op);
342 /// \p dep's source operation is available before \p dep's destination
343 /// operation starts.
344 virtual LogicalResult verifyPrecedence(Dependence dep);
345
346 //===--------------------------------------------------------------------===//
347 // Client API for problem validation
348 //===--------------------------------------------------------------------===//
349public:
350 /// Return success if the constructed scheduling problem is valid.
351 virtual LogicalResult check();
352 /// Return success if the computed solution is valid.
353 virtual LogicalResult verify();
354};
355
356/// This class models a cyclic scheduling problem. Its solution can be used to
357/// construct a pipelined datapath with a fixed, integer initiation interval,
358/// in which the execution of multiple iterations/samples/etc. may overlap.
359class CyclicProblem : public virtual Problem {
360public:
361 static constexpr auto name = "CyclicProblem";
362 using Problem::Problem;
363
364protected:
365 CyclicProblem() = default;
366
367private:
370
371public:
372 /// The distance determines whether a dependence has to be satisfied in the
373 /// same iteration (distance=0 or not set), or distance-many iterations later.
374 std::optional<unsigned> getDistance(Dependence dep) {
375 return distance.lookup(dep);
376 }
377 void setDistance(Dependence dep, unsigned val) { distance[dep] = val; }
378
379 /// The initiation interval (II) is the number of time steps between
380 /// subsequent iterations, i.e. a new iteration is started every II time
381 /// steps. The best possible value is 1, meaning that a corresponding pipeline
382 /// accepts new data every cycle. This property is part of the cyclic
383 /// problem's solution.
384 std::optional<unsigned> getInitiationInterval() { return initiationInterval; }
385 void setInitiationInterval(unsigned val) { initiationInterval = val; }
386
387 virtual PropertyStringVector getProperties(Dependence dep) override;
388 virtual PropertyStringVector getProperties() override;
389
390protected:
391 /// \p dep's source operation is available before \p dep's destination
392 /// operation starts (\p dep's distance iterations later).
393 virtual LogicalResult verifyPrecedence(Dependence dep) override;
394 /// This problem has a non-zero II.
395 virtual LogicalResult verifyInitiationInterval();
396
397public:
398 virtual LogicalResult verify() override;
399};
400
401/// This class models the accumulation of physical propagation delays on
402/// combinational paths along SSA dependences.
403///
404/// Each operator type is annotated with estimated values for incoming and
405/// outgoing delays. Combinational operators (zero-latency, no internal
406/// registers) have only a single delay; this important special case is modeled
407/// by setting the incoming and outgoing delays to the same value.
408///
409/// A solution to this problem comprises per-operation start times in a
410/// continuous unit, e.g. in nanoseconds, inside the discrete time steps/cycles
411/// determined by the underlying scheduling problem.
412class ChainingProblem : public virtual Problem {
413public:
414 static constexpr auto name = "ChainingProblem";
415 using Problem::Problem;
416
417protected:
418 ChainingProblem() = default;
419
420private:
423
424public:
425 /// The incoming delay denotes the propagation time from the operand inputs to
426 /// either the result outputs (combinational operators) or the first internal
427 /// register stage.
428 std::optional<float> getIncomingDelay(OperatorType opr) {
429 return incomingDelay.lookup(opr);
430 }
431 void setIncomingDelay(OperatorType opr, float delay) {
432 incomingDelay[opr] = delay;
433 }
434
435 /// The outgoing delay denotes the propagation time from either the operand
436 /// inputs (combinational operators) or the last internal register stage to
437 /// the result outputs.
438 std::optional<float> getOutgoingDelay(OperatorType opr) {
439 return outgoingDelay.lookup(opr);
440 }
441 void setOutgoingDelay(OperatorType opr, float delay) {
442 outgoingDelay[opr] = delay;
443 }
444
445 /// Computed by the scheduler, this start time is relative to the beginning of
446 /// the cycle that \p op starts in.
447 std::optional<float> getStartTimeInCycle(Operation *op) {
448 return startTimeInCycle.lookup(op);
449 }
450 void setStartTimeInCycle(Operation *op, float time) {
451 startTimeInCycle[op] = time;
452 }
454
455 virtual PropertyStringVector getProperties(Operation *op) override;
456 virtual PropertyStringVector getProperties(OperatorType opr) override;
457
458protected:
459 /// Incoming/outgoing delays are set for \p opr and non-negative. The delays
460 /// are equal if \p opr is a zero-latency operator type.
461 virtual LogicalResult checkDelays(OperatorType opr);
462
463 /// \p op has a non-negative start time in its cycle.
464 virtual LogicalResult verifyStartTimeInCycle(Operation *op);
465 /// If \p dep is an SSA edge and its source operation finishes in the same
466 /// time step as the destination operation, the source's result is available
467 /// before the destination starts in that cycle.
468 virtual LogicalResult verifyPrecedenceInCycle(Dependence dep);
469
470public:
471 virtual LogicalResult check() override;
472 virtual LogicalResult verify() override;
473};
474
475/// This class models a resource-constrained scheduling problem. An optional,
476/// non-zero *limit* marks resource types to be *shared* by the operations using
477/// them. In an HLS setting, this corresponds to multiplexing multiple
478/// operations onto a pre-allocated number of operator instances. These
479/// instances are assumed to be *fully pipelined*, meaning each instance can
480/// accept new operands (coming from a distinct operation) in each time step.
481///
482/// A solution to this problem is feasible iff the number of operations that use
483/// a certain limited operator type, and start in the same time step, does not
484/// exceed the operator type's limit. These constraints do not apply to operator
485/// types without a limit (not set, or 0).
486class SharedOperatorsProblem : public virtual Problem {
487public:
488 static constexpr auto name = "SharedOperatorsProblem";
489 using Problem::Problem;
490
491protected:
493
494private:
496
497public:
498 /// The limit is the maximum number of operations using \p rsrc that are
499 /// available in the target hardware.
500 std::optional<unsigned> getLimit(ResourceType rsrc) {
501 return limit.lookup(rsrc);
502 }
503 void setLimit(ResourceType rsrc, unsigned val) { limit[rsrc] = val; }
504
505 virtual PropertyStringVector getProperties(ResourceType rsrc) override;
506
507protected:
508 /// If \p op is limited, it has a non-zero latency.
509 virtual LogicalResult checkLatency(Operation *op) override;
510 /// \p rsrc is not oversubscribed in any time step.
511 virtual LogicalResult verifyUtilization(ResourceType rsrc);
512
513public:
514 virtual LogicalResult verify() override;
515};
516
517/// This class models the modulo scheduling problem as the composition of the
518/// cyclic problem and the resource-constrained problem with fully-pipelined
519/// shared operators.
520///
521/// A solution to this problem comprises an integer II and integer start times
522/// for all registered operations, and is feasible iff:
523/// (1) The precedence constraints implied by the `CyclicProblem`'s dependence
524/// edges are satisfied, and
525/// (2) The number of operations that use a certain limited operator type,
526/// and start in the same congruence class (= start time *mod* II), does
527/// not exceed the operator type's limit.
528class ModuloProblem : public virtual CyclicProblem,
529 public virtual SharedOperatorsProblem {
530public:
531 static constexpr auto name = "ModuloProblem";
533
534protected:
535 ModuloProblem() = default;
536
537 /// \p opr is not oversubscribed in any congruence class modulo II.
538 virtual LogicalResult verifyUtilization(ResourceType rsrc) override;
539
540public:
541 virtual LogicalResult verify() override;
542};
543
544/// This class models the accumulation of physical propagation delays on
545/// combinational paths along SSA dependences on a cyclic scheduling problem.
546///
547/// Each operator type is annotated with estimated values for incoming and
548/// outgoing delays. Combinational operators (zero-latency, no internal
549/// registers) have only a single delay; this important special case is modeled
550/// by setting the incoming and outgoing delays to the same values.
551///
552/// A solution to this problem comprises per-operation start times in a
553/// continuous unit, e.g. in nanoseconds, inside the discrete time steps/cycles
554/// determined by the underlying scheduling problem. Its solution can be used to
555/// construct a pipelined datapath with a fixed, integer initiation interval,
556/// in which the execution of multiple iterations/samples/etc. may overlap.
558 public virtual CyclicProblem {
559public:
560 static constexpr auto name = "ChainingCyclicProblem";
562
563protected:
565
566public:
567 LogicalResult checkDefUse(Dependence dep);
568 LogicalResult check() override;
569 LogicalResult verify() override;
570};
571
572} // namespace scheduling
573} // namespace circt
574
575namespace llvm {
576
577template <>
599
600template <>
622
623} // namespace llvm
624
625#endif // CIRCT_SCHEDULING_PROBLEMS_H
This class models the accumulation of physical propagation delays on combinational paths along SSA de...
Definition Problems.h:558
LogicalResult verify() override
Return success if the computed solution is valid.
Definition Problems.cpp:478
LogicalResult checkDefUse(Dependence dep)
Definition Problems.cpp:458
LogicalResult check() override
Return success if the constructed scheduling problem is valid.
Definition Problems.cpp:466
This class models the accumulation of physical propagation delays on combinational paths along SSA de...
Definition Problems.h:412
std::optional< float > getOutgoingDelay(OperatorType opr)
The outgoing delay denotes the propagation time from either the operand inputs (combinational operato...
Definition Problems.h:438
void setStartTimeInCycle(Operation *op, float time)
Definition Problems.h:450
void setIncomingDelay(OperatorType opr, float delay)
Definition Problems.h:431
OperationProperty< float > startTimeInCycle
Definition Problems.h:422
virtual LogicalResult check() override
Return success if the constructed scheduling problem is valid.
Definition Problems.cpp:305
virtual LogicalResult verifyPrecedenceInCycle(Dependence dep)
If dep is an SSA edge and its source operation finishes in the same time step as the destination oper...
Definition Problems.cpp:270
std::optional< float > getIncomingDelay(OperatorType opr)
The incoming delay denotes the propagation time from the operand inputs to either the result outputs ...
Definition Problems.h:428
OperatorTypeProperty< float > incomingDelay
Definition Problems.h:421
static constexpr auto name
Definition Problems.h:414
void setOutgoingDelay(OperatorType opr, float delay)
Definition Problems.h:441
virtual LogicalResult verify() override
Return success if the computed solution is valid.
Definition Problems.cpp:316
OperatorTypeProperty< float > outgoingDelay
Definition Problems.h:421
virtual LogicalResult verifyStartTimeInCycle(Operation *op)
op has a non-negative start time in its cycle.
Definition Problems.cpp:263
virtual LogicalResult checkDelays(OperatorType opr)
Incoming/outgoing delays are set for opr and non-negative.
Definition Problems.cpp:239
std::optional< float > getStartTimeInCycle(Operation *op)
Computed by the scheduler, this start time is relative to the beginning of the cycle that op starts i...
Definition Problems.h:447
This class models a cyclic scheduling problem.
Definition Problems.h:359
void setDistance(Dependence dep, unsigned val)
Definition Problems.h:377
virtual LogicalResult verifyInitiationInterval()
This problem has a non-zero II.
Definition Problems.cpp:207
virtual PropertyStringVector getProperties() override
Definition Problems.cpp:179
virtual LogicalResult verifyPrecedence(Dependence dep) override
dep's source operation is available before dep's destination operation starts (dep's distance iterati...
Definition Problems.cpp:186
std::optional< unsigned > getDistance(Dependence dep)
The distance determines whether a dependence has to be satisfied in the same iteration (distance=0 or...
Definition Problems.h:374
void setInitiationInterval(unsigned val)
Definition Problems.h:385
InstanceProperty< unsigned > initiationInterval
Definition Problems.h:369
static constexpr auto name
Definition Problems.h:361
virtual LogicalResult verify() override
Return success if the computed solution is valid.
Definition Problems.cpp:213
DependenceProperty< unsigned > distance
Definition Problems.h:368
std::optional< unsigned > getInitiationInterval()
The initiation interval (II) is the number of time steps between subsequent iterations,...
Definition Problems.h:384
This class models the modulo scheduling problem as the composition of the cyclic problem and the reso...
Definition Problems.h:529
virtual LogicalResult verify() override
Return success if the computed solution is valid.
Definition Problems.cpp:441
static constexpr auto name
Definition Problems.h:531
virtual LogicalResult verifyUtilization(ResourceType rsrc) override
opr is not oversubscribed in any congruence class modulo II.
Definition Problems.cpp:411
This class models the most basic scheduling problem.
Definition Problems.h:75
void setLatency(OperatorType opr, unsigned val)
Definition Problems.h:276
llvm::DenseMap< Operation *, llvm::SmallSetVector< Operation *, 4 > > AuxDependenceMap
Definition Problems.h:153
void insertResourceType(ResourceType rsrc)
Include rsrc in this scheduling problem.
Definition Problems.h:204
llvm::SetVector< Operation * > OperationSet
Definition Problems.h:146
llvm::SetVector< OperatorType > OperatorTypeSet
Definition Problems.h:148
virtual LogicalResult verify()
Return success if the computed solution is valid.
Definition Problems.cpp:147
StringAttr getInstanceName()
Definition Problems.h:303
virtual LogicalResult check()
Return success if the constructed scheduling problem is valid.
Definition Problems.cpp:111
std::optional< unsigned > getLatency(OperatorType opr)
The latency is the number of cycles opr needs to compute its result.
Definition Problems.h:273
virtual PropertyStringVector getProperties()
Definition Problems.cpp:84
void insertOperation(Operation *op)
Include op in this scheduling problem.
Definition Problems.h:193
llvm::iterator_range< detail::DependenceIterator > DependenceRange
Definition Problems.h:147
bool hasOperation(Operation *op)
Return true if op is part of this problem.
Definition Problems.h:224
StringAttr getLibraryName()
Definition Problems.h:306
std::optional< SmallVector< ResourceType > > getLinkedResourceTypes(Operation *op)
The linked resource type provides the available resources for op.
Definition Problems.h:265
LogicalResult insertDependence(Dependence dep)
Include dep in the scheduling problem.
Definition Problems.cpp:26
std::optional< unsigned > getEndTime(Operation *op)
Returns the end time for op, as computed by the scheduler.
Definition Problems.cpp:160
OperationProperty< OperatorType > linkedOperatorType
Definition Problems.h:181
OperationProperty< unsigned > startTime
Definition Problems.h:183
void setLinkedResourceTypes(Operation *op, SmallVector< ResourceType > rsrc)
Definition Problems.h:268
StringAttr getRsrcLibraryName()
Definition Problems.h:309
void setRsrcLibraryName(StringAttr name)
Definition Problems.h:310
std::optional< T > InstanceProperty
Definition Problems.h:164
std::optional< OperatorType > getLinkedOperatorType(Operation *op)
The linked operator type provides the runtime characteristics for op.
Definition Problems.h:256
ResourceTypeSet resourceTypes
Definition Problems.h:178
void setStartTime(Operation *op, unsigned val)
Definition Problems.h:284
OperatorTypeProperty< unsigned > latency
Definition Problems.h:186
const ResourceTypeSet & getResourceTypes()
Return the set of resource types.
Definition Problems.h:250
SmallDenseMap< Operation *, StringAttr > operationNames
Definition Problems.h:300
llvm::DenseMap< Operation *, std::optional< T > > OperationProperty
Definition Problems.h:156
static constexpr auto name
Definition Problems.h:77
virtual ~Problem()=default
void setContainingOp(Operation *op)
Set the operation containing this problem, e.g. to emit diagnostics.
Definition Problems.h:221
const OperationSet & getOperations()
Return the set of operations.
Definition Problems.h:226
OperatorType getOrInsertOperatorType(StringRef name)
Retrieves the operator type identified by the client-specific name.
Definition Problems.cpp:47
AuxDependenceMap auxDependences
Definition Problems.h:176
std::optional< unsigned > getStartTime(Operation *op)
Return the start time for op, as computed by the scheduler.
Definition Problems.h:281
llvm::DenseMap< OperatorType, std::optional< T > > OperatorTypeProperty
Definition Problems.h:160
void setInstanceName(StringAttr name)
Definition Problems.h:304
OperatorTypeSet operatorTypes
Definition Problems.h:177
llvm::SmallVector< std::pair< std::string, std::string >, 2 > PropertyStringVector
Definition Problems.h:324
virtual LogicalResult verifyStartTime(Operation *op)
op has a start time.
Definition Problems.cpp:123
virtual LogicalResult checkLinkedOperatorType(Operation *op)
op is linked to a registered operator type.
Definition Problems.cpp:90
llvm::DenseMap< Dependence, std::optional< T > > DependenceProperty
Definition Problems.h:158
DependenceRange getDependences(Operation *op)
Return a range object to transparently iterate over op's incoming 1) implicit def-use dependences (ba...
Definition Problems.cpp:59
llvm::SetVector< ResourceType > ResourceTypeSet
Definition Problems.h:149
OperationProperty< SmallVector< ResourceType > > linkedResourceTypes
Definition Problems.h:182
bool hasOperatorType(OperatorType opr)
Return true if opr is part of this problem.
Definition Problems.h:241
virtual LogicalResult verifyPrecedence(Dependence dep)
dep's source operation is available before dep's destination operation starts.
Definition Problems.cpp:129
void setLibraryName(StringAttr name)
Definition Problems.h:307
void setLinkedOperatorType(Operation *op, OperatorType opr)
Definition Problems.h:259
Operation * getContainingOp()
Return the operation containing this problem, e.g. to emit diagnostics.
Definition Problems.h:219
void insertOperatorType(OperatorType opr)
Include opr in this scheduling problem.
Definition Problems.h:201
llvm::DenseMap< ResourceType, std::optional< T > > ResourceTypeProperty
Definition Problems.h:162
void setOperationName(Operation *op, StringAttr name)
Definition Problems.h:315
ResourceType getOrInsertResourceType(StringRef name)
Retrieves the resource type identified by the client-specific name.
Definition Problems.cpp:53
StringAttr getOperationName(Operation *op)
Definition Problems.h:312
virtual LogicalResult checkLatency(Operation *op)
op has a latency.
Definition Problems.cpp:98
Problem(Operation *containingOp)
Construct an empty scheduling problem.
Definition Problems.h:81
bool hasResourceType(ResourceType rsrc)
Return true if rsrc is part of this problem.
Definition Problems.h:246
const OperatorTypeSet & getOperatorTypes()
Return the set of operator types.
Definition Problems.h:243
This class models a resource-constrained scheduling problem.
Definition Problems.h:486
virtual LogicalResult verifyUtilization(ResourceType rsrc)
rsrc is not oversubscribed in any time step.
Definition Problems.cpp:367
void setLimit(ResourceType rsrc, unsigned val)
Definition Problems.h:503
virtual LogicalResult verify() override
Return success if the computed solution is valid.
Definition Problems.cpp:396
virtual LogicalResult checkLatency(Operation *op) override
If op is limited, it has a non-zero latency.
Definition Problems.cpp:344
ResourceTypeProperty< unsigned > limit
Definition Problems.h:495
std::optional< unsigned > getLimit(ResourceType rsrc)
The limit is the maximum number of operations using rsrc that are available in the target hardware.
Definition Problems.h:500
An iterator to transparently surface an operation's def-use dependences from the SSA subgraph (induce...
A wrapper class to uniformly handle def-use and auxiliary dependence edges.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Operator types are distinguished by name (chosen by the client).
Definition Problems.h:98
mlir::StringAttr getAttr() const
Definition Problems.h:108
static OperatorType get(mlir::MLIRContext *ctx, llvm::StringRef name)
Definition Problems.h:104
mlir::StringRef getValue() const
Definition Problems.h:110
OperatorType(mlir::StringAttr attr)
Definition Problems.h:102
friend bool operator==(const OperatorType &lhs, const OperatorType &rhs)
Definition Problems.h:114
Resource types are distinguished by name (chosen by the client).
Definition Problems.h:120
mlir::StringRef getValue() const
Definition Problems.h:132
ResourceType(mlir::StringAttr attr)
Definition Problems.h:124
static ResourceType get(mlir::MLIRContext *ctx, llvm::StringRef name)
Definition Problems.h:126
friend bool operator==(const ResourceType &lhs, const ResourceType &rhs)
Definition Problems.h:136
mlir::StringAttr getAttr() const
Definition Problems.h:130
bool operator!=(const ResourceType &rhs) const
Definition Problems.h:139
static circt::scheduling::Problem::OperatorType getTombstoneKey()
Definition Problems.h:584
static bool isEqual(const circt::scheduling::Problem::OperatorType &lhs, const circt::scheduling::Problem::OperatorType &rhs)
Definition Problems.h:594
static circt::scheduling::Problem::OperatorType getEmptyKey()
Definition Problems.h:579
static unsigned getHashValue(const circt::scheduling::Problem::OperatorType &val)
Definition Problems.h:590
static bool isEqual(const circt::scheduling::Problem::ResourceType &lhs, const circt::scheduling::Problem::ResourceType &rhs)
Definition Problems.h:617
static unsigned getHashValue(const circt::scheduling::Problem::ResourceType &val)
Definition Problems.h:613
static circt::scheduling::Problem::ResourceType getTombstoneKey()
Definition Problems.h:607
static circt::scheduling::Problem::ResourceType getEmptyKey()
Definition Problems.h:602