Skip to content

Commit 72f7de6

Browse files
committed
More clean-up of the PR.
- The recorded true data properties are stored to the file specified by --properties-file-path (not always to "properties.json"). - Slight polishing of the code for data property recording and insertion.
1 parent 394fef7 commit 72f7de6

File tree

6 files changed

+74
-95
lines changed

6 files changed

+74
-95
lines changed

src/api/internal/daphne_internal.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -741,7 +741,7 @@ int startDAPHNE(int argc, const char **argv, DaphneLibResult *daphneLibRes, int
741741
Statistics::instance().dumpStatistics(KernelDispatchMapping::instance());
742742

743743
if (user_config.enable_property_recording)
744-
PropertyLogger::instance().savePropertiesAsJson("properties.json");
744+
PropertyLogger::instance().savePropertiesAsJson(user_config.properties_file_path);
745745

746746
// explicitly destroying the moduleOp here due to valgrind complaining about
747747
// a memory leak otherwise.

src/compiler/explanation/InsertPropertiesPass.cpp

Lines changed: 40 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,8 @@ using namespace mlir;
4343

4444
nlohmann::json readPropertiesFromFile(const std::string &filename) {
4545
std::ifstream file(filename);
46-
if (!file.is_open()) {
47-
throw std::runtime_error("Failed to open file: " + filename);
48-
}
46+
if (!file.is_open())
47+
throw std::runtime_error("failed to open file: '" + filename + "'");
4948

5049
nlohmann::json properties;
5150
file >> properties;
@@ -60,6 +59,10 @@ struct PropertyEntry {
6059
};
6160

6261
namespace {
62+
/**
63+
* @brief Inserts the true data properties of each matrix-typed intermediate result (with certain exceptions) recorded
64+
* in a previous run of DAPHNE into the IR by inserting `mlir::daphne::CastOp`s that add these data properties.
65+
*/
6366
struct InsertPropertiesPass : public impl::InsertPropertiesPassBase<InsertPropertiesPass> {
6467
InsertPropertiesPass() = default;
6568

@@ -89,7 +92,7 @@ void InsertPropertiesPass::runOnOperation() {
8992

9093
auto insertRecordedProperties = [&](Operation *op) {
9194
size_t numResults = op->getNumResults();
92-
for (unsigned i = 0; i < numResults && propertyIndex < properties.size(); ++i) {
95+
for (size_t i = 0; i < numResults && propertyIndex < properties.size(); ++i) {
9396
Value res = op->getResult(i);
9497
nlohmann::json &prop = properties[propertyIndex].properties;
9598
auto it = prop.begin();
@@ -98,49 +101,42 @@ void InsertPropertiesPass::runOnOperation() {
98101
const nlohmann::json &value = it.value();
99102
if (key == "sparsity") {
100103
if (value.is_null()) {
101-
llvm::errs() << "Error: 'sparsity' is null for property index " << propertyIndex << "\n";
104+
llvm::errs() << "error: 'sparsity' is null for property index " << propertyIndex << "\n";
102105
++it;
103106
continue;
104107
} else if (!value.is_number()) {
105-
llvm::errs() << "Error: 'sparsity' is not a number for property index " << propertyIndex
108+
llvm::errs() << "error: 'sparsity' is not a number for property index " << propertyIndex
106109
<< "\n";
107110
++it;
108111
continue;
109112
}
110113

111-
if (res.getType().isa<daphne::MatrixType>()) {
112-
auto mt = res.getType().dyn_cast<daphne::MatrixType>();
114+
if (auto mt = res.getType().dyn_cast<daphne::MatrixType>()) {
113115
double sparsity = value.get<double>();
114-
if (mt) {
115-
if ((llvm::isa<scf::ForOp>(op) || llvm::isa<scf::WhileOp>(op) ||
116-
llvm::isa<scf::IfOp>(op))) {
117-
builder.setInsertionPointAfter(op);
118-
builder.create<daphne::CastOp>(op->getLoc(), mt.withSparsity(sparsity), res);
119-
}
120-
121-
else {
122-
for (auto &use : res.getUses()) {
123-
Operation *userOp = use.getOwner();
124-
if (isa<scf::ForOp>(userOp) || isa<scf::IfOp>(userOp) ||
125-
isa<scf::WhileOp>(userOp)) {
126-
auto key = std::make_pair(res, userOp);
127-
128-
Value castOpValue;
129-
if (castOpMap.count(key)) {
130-
castOpValue = castOpMap[key];
131-
} else {
132-
builder.setInsertionPoint(userOp);
133-
castOpValue = builder.create<daphne::CastOp>(op->getLoc(), mt, res);
134-
castOpMap[key] = castOpValue;
135-
}
136-
137-
userOp->setOperand(use.getOperandNumber(), castOpValue);
116+
if ((llvm::isa<scf::ForOp>(op) || llvm::isa<scf::WhileOp>(op) || llvm::isa<scf::IfOp>(op))) {
117+
builder.setInsertionPointAfter(op);
118+
builder.create<daphne::CastOp>(op->getLoc(), mt.withSparsity(sparsity), res);
119+
} else {
120+
for (auto &use : res.getUses()) {
121+
Operation *userOp = use.getOwner();
122+
if (isa<scf::ForOp>(userOp) || isa<scf::IfOp>(userOp) || isa<scf::WhileOp>(userOp)) {
123+
auto key = std::make_pair(res, userOp);
124+
125+
Value castOpValue;
126+
if (castOpMap.count(key)) {
127+
castOpValue = castOpMap[key];
128+
} else {
129+
builder.setInsertionPoint(userOp);
130+
castOpValue = builder.create<daphne::CastOp>(op->getLoc(), mt, res);
131+
castOpMap[key] = castOpValue;
138132
}
133+
134+
userOp->setOperand(use.getOperandNumber(), castOpValue);
139135
}
140136
}
141-
142-
++propertyIndex;
143137
}
138+
139+
++propertyIndex;
144140
}
145141
}
146142
++it;
@@ -152,40 +148,33 @@ void InsertPropertiesPass::runOnOperation() {
152148
if (propertyIndex >= properties.size())
153149
return WalkResult::advance();
154150

155-
// Skip specific ops that should not be processed
151+
// Skip specific ops that should not be processed.
156152
if (isa<daphne::RecordPropertiesOp>(op) || op->hasAttr("daphne.value_ids"))
157153
return WalkResult::advance();
158-
159-
if (auto castOp = dyn_cast<daphne::CastOp>(op)) {
160-
if (castOp.isRemovePropertyCast()) {
154+
if (auto castOp = dyn_cast<daphne::CastOp>(op))
155+
if (castOp.isRemovePropertyCast())
161156
return WalkResult::advance();
162-
}
163-
}
164157

165-
// Handle loops (scf.for and scf.while) and If blocks as black boxes
158+
// Handle loops (scf.for and scf.while) and if-blocks as black boxes.
166159
if (isa<scf::ForOp>(op) || isa<scf::WhileOp>(op) || isa<scf::IfOp>(op)) {
167160
insertRecordedProperties(op);
168161
return WalkResult::skip();
169162
}
170163

164+
// Check if this is the @main function or a UDF.
171165
if (auto funcOp = llvm::dyn_cast<func::FuncOp>(op)) {
172-
// Check if this is the @main function or a UDF
173-
if (funcOp.getName() == "main") {
166+
if (funcOp.getName() == "main")
174167
return WalkResult::advance();
175-
} else {
176-
return WalkResult::skip();
177-
}
168+
return WalkResult::skip();
178169
}
179170

180-
// Process all other operations that output matrix types
171+
// Process other operations with matrix-typed results.
181172
insertRecordedProperties(op);
182173
return WalkResult::advance();
183174
});
184175

185-
if (propertyIndex < properties.size()) {
186-
llvm::errs() << "Warning: Not all properties were applied."
187-
<< "\n";
188-
}
176+
if (propertyIndex < properties.size())
177+
llvm::errs() << "warning: not all properties were applied\n";
189178
}
190179

191180
std::unique_ptr<OperationPass<func::FuncOp>> mlir::daphne::createInsertPropertiesPass(std::string propertiesFilePath) {

src/compiler/explanation/RecordPropertiesPass.cpp

Lines changed: 23 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -31,68 +31,63 @@ uint32_t generateUniqueID() {
3131
return currentID++;
3232
}
3333

34+
/**
35+
* @brief Inserts a `mlir::daphne::RecordPropertiesOp` for each matrix-typed intermediate result (with certain
36+
* exceptions) in order to record the true data properties at run-time.
37+
*/
3438
class RecordPropertiesPass : public PassWrapper<RecordPropertiesPass, OperationPass<func::FuncOp>> {
3539
public:
3640
RecordPropertiesPass() = default;
3741

3842
StringRef getArgument() const final { return "record-properties"; }
39-
StringRef getDescription() const final { return "Record properties of different operations"; }
43+
StringRef getDescription() const final {
44+
return "Inserts a `mlir::daphne::RecordPropertiesOp` for each matrix-typed intermediate result (with certain "
45+
"exceptions) in order to record the true data properties at run-time.";
46+
}
4047

4148
void runOnOperation() override {
4249
func::FuncOp func = getOperation();
4350
OpBuilder builder(func.getContext());
4451

4552
auto recordResults = [&](Operation *op) {
4653
SmallVector<Attribute, 4> valueIDs;
47-
for (Value result : op->getResults()) {
54+
for (Value result : op->getResults())
4855
if (result.getType().isa<daphne::MatrixType>()) {
4956
uint32_t id = generateUniqueID();
5057
valueIDs.push_back(builder.getUI32IntegerAttr(id));
51-
5258
builder.setInsertionPointAfter(op);
53-
54-
auto idConstant = builder.create<mlir::daphne::ConstantOp>(
55-
op->getLoc(), builder.getIntegerType(32, /*isSigned=*/false), builder.getUI32IntegerAttr(id));
56-
59+
auto idConstant = builder.create<daphne::ConstantOp>(op->getLoc(), id);
5760
builder.create<daphne::RecordPropertiesOp>(op->getLoc(), result, idConstant);
5861
}
59-
}
6062

61-
if (!valueIDs.empty()) {
63+
if (!valueIDs.empty())
6264
op->setAttr("daphne.value_ids", builder.getArrayAttr(valueIDs));
63-
}
6465
};
6566

6667
func.walk<WalkOrder::PreOrder>([&](Operation *op) -> WalkResult {
67-
// Skip specific ops that should not be processed
68+
// Skip specific ops that should not be processed.
6869
if (isa<daphne::RecordPropertiesOp>(op) || op->hasAttr("daphne.value_ids"))
6970
return WalkResult::advance();
70-
71-
if (auto castOp = dyn_cast<daphne::CastOp>(op)) {
72-
if (castOp.isRemovePropertyCast()) {
71+
if (auto castOp = dyn_cast<daphne::CastOp>(op))
72+
if (castOp.isRemovePropertyCast())
7373
return WalkResult::advance();
74-
}
75-
}
7674

77-
// Handle loops (scf.for and scf.while) and If blocks as black boxes
75+
// Handle loops (scf.for and scf.while) and if-blocks as black boxes.
7876
if (isa<scf::ForOp>(op) || isa<scf::WhileOp>(op) || isa<scf::IfOp>(op)) {
7977
recordResults(op);
8078
return WalkResult::skip();
8179
}
8280

83-
else if (auto funcOp = llvm::dyn_cast<func::FuncOp>(op)) {
84-
// Check if this is the @main function or a UDF
85-
if (funcOp.getName() == "main") {
81+
// Check if this is the @main function or a UDF.
82+
if (auto funcOp = llvm::dyn_cast<func::FuncOp>(op)) {
83+
if (funcOp.getName() == "main")
8684
return WalkResult::advance();
87-
} else {
88-
return WalkResult::skip();
89-
}
90-
}
91-
// Process other operations with Matrix Output type
92-
else {
93-
recordResults(op);
94-
return WalkResult::advance();
85+
return WalkResult::skip();
9586
}
87+
88+
// Process other operations with matrix-typed results.
89+
recordResults(op);
90+
return WalkResult::advance();
9691
});
9792
}
9893
};

src/ir/daphneir/DaphneOps.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2047,6 +2047,10 @@ def Daphne_ConstantOp : Daphne_Op<"constant", [ConstantLike, Pure]> {
20472047
Type t = $_builder.getIntegerType(64, true);
20482048
build($_builder, $_state, t, $_builder.getIntegerAttr(t, value));
20492049
}]>,
2050+
OpBuilder<(ins "uint32_t":$value), [{
2051+
Type t = $_builder.getIntegerType(32, false);
2052+
build($_builder, $_state, t, $_builder.getIntegerAttr(t, value));
2053+
}]>,
20502054
OpBuilder<(ins "uint64_t":$value), [{
20512055
Type t = $_builder.getIntegerType(64, false);
20522056
build($_builder, $_state, t, $_builder.getIntegerAttr(t, value));

src/ir/daphneir/Passes.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ std::unique_ptr<Pass> createSelectMatrixRepresentationsPass(const DaphneUserConf
7474
std::unique_ptr<Pass> createSpecializeGenericFunctionsPass(const DaphneUserConfig &cfg);
7575
std::unique_ptr<Pass> createTransposeOpLoweringPass();
7676
std::unique_ptr<Pass> createVectorizeComputationsPass();
77-
std::unique_ptr<Pass> createWhileLoopInvariantCodeMotionPass();
7877
#ifdef USE_CUDA
7978
std::unique_ptr<Pass> createMarkCUDAOpsPass(const DaphneUserConfig &cfg);
8079
#endif

src/util/PropertyLogger.cpp

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,38 +32,30 @@ void PropertyLogger::savePropertiesAsJson(const std::string &filename) const {
3232
nlohmann::json j;
3333
{
3434
std::lock_guard<std::mutex> lock(mutex);
35-
36-
if (properties.empty()) {
37-
}
38-
3935
for (const auto &opEntry : properties) {
4036
const uint32_t value_id = opEntry.first;
4137
const auto &propVec = opEntry.second;
4238

4339
nlohmann::json propJson;
44-
for (const auto &prop : propVec) {
40+
for (const auto &prop : propVec)
4541
prop->to_json(propJson);
46-
}
4742
j[std::to_string(value_id)] = propJson;
4843
}
4944
}
5045

5146
std::ofstream file(filename);
52-
if (file.is_open()) {
47+
if (file.is_open())
5348
file << j.dump(4);
54-
} else {
55-
throw std::runtime_error("Failed to open file: " + filename);
56-
}
49+
else
50+
throw std::runtime_error("failed to open file: '" + filename + "'");
5751
}
5852

5953
std::vector<const Property *> PropertyLogger::getProperties(uint32_t value_id) const {
6054
std::lock_guard<std::mutex> lock(mutex);
6155
std::vector<const Property *> result;
6256
auto it = properties.find(value_id);
63-
if (it != properties.end()) {
64-
for (const auto &prop : it->second) {
57+
if (it != properties.end())
58+
for (const auto &prop : it->second)
6559
result.push_back(prop.get());
66-
}
67-
}
6860
return result;
6961
}

0 commit comments

Comments
 (0)