-
Notifications
You must be signed in to change notification settings - Fork 59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix passing str variable to readFrame/readMatrix #598
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -188,6 +188,7 @@ namespace { | |
std::multimap<std::string, func::FuncOp> specializedVersions; | ||
std::set<func::FuncOp> visited; | ||
std::set<func::FuncOp> called; | ||
std::set<func::FuncOp> templateFunctions; | ||
|
||
const DaphneUserConfig& userConfig; | ||
std::shared_ptr<spdlog::logger> logger; | ||
|
@@ -304,6 +305,7 @@ namespace { | |
calledFunction->getLoc().print(stream); | ||
logger->debug("calledFunction\n\tname: {}\n\tlocation: {}", calledFunction.getSymName().str(), s); | ||
} | ||
templateFunctions.insert(calledFunction); | ||
return specializedFunc; | ||
} | ||
|
||
|
@@ -417,7 +419,7 @@ void SpecializeGenericFunctionsPass::runOnOperation() { | |
entryFunctions.push_back(entry.second); | ||
} | ||
for(const auto &function : entryFunctions) { | ||
if(isFunctionTemplate(function) || visited.count(function)) | ||
if(isFunctionTemplate(function) || visited.count(function) || templateFunctions.count(function)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, the invocations of count() were there before, so doing it the same is quite alright and tbh I'm unsure if using empty() is just a matter of taste or if it would yield a (minor?) performance benefit. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The count actually makes sense here, as we're checking for that specific function in the set and not if there are any functions at all. |
||
continue; | ||
if(!inferTypesInFunction(function)) { | ||
return signalPassFailure(); | ||
|
@@ -431,7 +433,7 @@ void SpecializeGenericFunctionsPass::runOnOperation() { | |
continue; | ||
// Remove a function that was present before creating specializations, | ||
// if it is never called. | ||
if(!called.count(f.second)) | ||
if(!called.count(f.second) || templateFunctions.count(f.second)) | ||
f.second.erase(); | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -276,6 +276,60 @@ std::vector<Type> daphne::OrderOp::inferTypes() { | |
return {t}; | ||
} | ||
|
||
|
||
mlir::Type mlirTypeForCode(ValueTypeCode type, Builder builder) { | ||
switch(type) { | ||
case ValueTypeCode::SI8: return builder.getIntegerType(8, true); | ||
case ValueTypeCode::SI32: return builder.getIntegerType(32, true); | ||
case ValueTypeCode::SI64: return builder.getIntegerType(64, true); | ||
case ValueTypeCode::UI8: return builder.getIntegerType(8, false); | ||
case ValueTypeCode::UI32: return builder.getIntegerType(32, false); | ||
case ValueTypeCode::UI64: return builder.getIntegerType(64, false); | ||
case ValueTypeCode::F32: return builder.getF32Type(); | ||
case ValueTypeCode::F64: return builder.getF64Type(); | ||
default: throw std::runtime_error("mlirTypeForCode: unknown value type code"); | ||
} | ||
} | ||
|
||
std::vector<Type> daphne::ReadOp::inferTypes() { | ||
|
||
auto p = CompilerUtils::isConstant<std::string>(getFileName()); | ||
Builder builder(getContext()); | ||
if (auto resType = getRes().getType().dyn_cast<daphne::MatrixType>()) { | ||
// If an individual value type was specified per column | ||
// (fmd.isSingleValueType == false), then this silently uses the | ||
// type of the first column. | ||
Comment on lines
+299
to
+301
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment about isSingleValueType is not correct and can be removed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just moved it over, but I can also remove it alltogether. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The comment referred to reading a matrix from a file that has a schema defined. So it is not utterly wrong. You could move it a few lines up to the code that handles reading matrices. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done. |
||
// TODO: add sparsity information here already (if present), currently not possible as many other ops | ||
// just take input types as output types, which is incorrect for sparsity | ||
if (p.first) { | ||
FileMetaData fmd = CompilerUtils::getFileMetaData(getFileName()); | ||
mlir::Type valType = mlirTypeForCode(fmd.schema[0], builder); | ||
return {mlir::daphne::MatrixType::get(getContext(), valType)}; | ||
} else { | ||
return {mlir::daphne::MatrixType::get(getContext(), daphne::UnknownType::get(getContext()))}; | ||
} | ||
} | ||
else if (auto resType = getRes().getType().dyn_cast<daphne::FrameType>()) { | ||
if (p.first) { | ||
FileMetaData fmd = CompilerUtils::getFileMetaData(getFileName()); | ||
std::vector<mlir::Type> cts; | ||
if (fmd.isSingleValueType) { | ||
for (size_t i = 0; i < fmd.numCols; i++) { | ||
cts.push_back(mlirTypeForCode(fmd.schema[0], builder)); | ||
} | ||
} else { | ||
for (ValueTypeCode vtc : fmd.schema) { | ||
cts.push_back(mlirTypeForCode(vtc, builder)); | ||
} | ||
} | ||
return {mlir::daphne::FrameType::get(builder.getContext(), cts)}; | ||
} else { | ||
return {mlir::daphne::FrameType::get(builder.getContext(), {daphne::UnknownType::get(getContext())})}; | ||
} | ||
} | ||
return {daphne::UnknownType::get(getContext())}; | ||
} | ||
|
||
std::vector<Type> daphne::SliceColOp::inferTypes() { | ||
Type u = daphne::UnknownType::get(getContext()); | ||
Type srcTy = getSource().getType(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
-0.1,-0.2,0.1,0.2 | ||
3.14,5.41,6.22216,5 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"numRows": 2, | ||
"numCols": 4, | ||
"valueType": "f64", | ||
"numNonZeros": 0 | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Test reading from a file when the file path is not trivially constant (i.e., a parameter to a UDF) | ||
def readFrameFromCSV(path: str) { | ||
print(readFrame(path)); | ||
} | ||
|
||
readFrameFromCSV("test/api/cli/io/ReadCsv1.csv"); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
Frame(2x4, [col_0:double, col_1:double, col_2:double, col_3:double]) | ||
-0.1 -0.2 0.1 0.2 | ||
3.14 5.41 6.22216 5 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Test reading from a file when the file path is not trivially constant (i.e., a parameter to a UDF) | ||
def readMatrixFromCSV(path: str) { | ||
print(readMatrix(path)); | ||
} | ||
|
||
readMatrixFromCSV("test/api/cli/io/ReadCsv1.csv"); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
DenseMatrix(2x4, double) | ||
-0.1 -0.2 0.1 0.2 | ||
3.14 5.41 6.22216 5 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Test dynamic computation of string path -> does not yet work! | ||
i = 1; | ||
filename = "test/api/cli/io/ReadCsv" + i + ".csv"; | ||
m = readMatrix(filename); | ||
print(m); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This extra set for templateFunctions (and its unconditional use in line 299) is not clear to me right away (I did not test-run the code, maybe it would become clear then). Could you explain why this is needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initially, I thought the check
isFunctionTemplate
would already do the trick, but apparantely it does something else. I basically remove the "template function", which is specialized from considerations in later passes (i.e., doing a type inference on such a function doesn't make much sense imho). Template functions are those, which are specialized, that's why I add them unconditionally. According to the test suite this should be fine, but I feel this will require more thorough testing (independent from the reported bug).In general there are quite a few question marks in this pass. For example the constant parameter propagation leads to X functions with identical code (except for the constant parameter of course) when invoking the UDF X times.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've played around with the code a bit now and see what you mean. The generation of a separate function for each invocation (even if it is the same parameter) is a bit weird and could be improved.