-
Notifications
You must be signed in to change notification settings - Fork 16
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
Add lowering for the DOT_PRODUCT intrinsic #914
Add lowering for the DOT_PRODUCT intrinsic #914
Conversation
flang/lib/Lower/ReductionRuntime.cpp
Outdated
func = | ||
Fortran::lower::getRuntimeFunc<mkRTKey(DotProductReal8)>(loc, builder); | ||
|
||
// REQUIRES LONG_DOUBLE=80 |
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 got a bit confused here by https://github.com/flang-compiler/f18-llvm-project/blob/fir-dev/flang/runtime/dot-product.cpp#L141-L145. Should I just use #if LONG_DOUBLE == 80
? But then I won't be able to test this code-path.
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.
No. Take a look at "struct ForcedProductReal10", "struct ForcedProductReal16", "struct ForcedProductInteger16", "struct ForcedProductComplex10", and "struct ForcedProductComplex16" in ReductionRuntime.cpp. Also, see how those are used in the genProduct() function in the same file. That way, real*10, real*16, complex*10, complex*16, integer*16 will just work if/when they are supported by the target.
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.
Ah, thank you for pointing this out!
How can I test that it works? This is what I get for real(kind=10)
:
'fir.convert' op invalid type conversion
That's on an X86-64 machine. I would hope that we can force the frontend to generate this code regardless of whether the host systems supports extended real numbers.
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.
You should not get a fir error. The code should compile and link if the runtime routine is present for the target (although you may not get correct answers if the width is not supported natively by the target), or you should get a link time error. We have some regression tests in flang/test/Lower/intrinsic-procedures.f90 that use these higher precision data types (i.e., sum_test4 and product_test4 use complex(10), and spacing_test2 uses real*10). But we are just testing the fir in intrinsic-procedures.f90; not whether the code links and runs.
If you test something like real*16, you should get a link time error on X86-64 for the missing routine. For example, consider the following SUM code that operates on real*16. It compiles successfully but then you get a link time error.
program p
real*16:: x(2)
x(1) = 1.
x(2) = 9.
print *, sum(x)
end
When I compile it, I get the expected link time error on X86-64:
sum16.f90.o: In function _QQmain': /local/home/mleair/fir-dev/tests/sum/<stdin>:26: undefined reference to
_FortranASumReal16'
collect2: error: ld returned 1 exit status
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.
Thank you for confirming this and for all the references. There was a bug in my implementation - I was using incorrect function type in ForcedDotProductReal{N}
. This is now fixed and tested!
Thank you for taking a look @mleair ! I still would like to add tests for real10, real16 and integer*16. Lowering for I am also missing lowering for logical vectors. Are there any examples for these? |
I suggest taking a look at some of the implemented intrinsics that handle these data types. For example, sum and product both handle complex results. The results are handled in a result descriptor. You can see how it is handled in the genSum() and genProduct() routines in ReductionRuntime.cpp. The key is that they need a result descriptor while the other scalar data type versions do not. The function genProdOrSum() in IntrinsicCall.cpp creates this result descriptor when the result is Complex. |
@mleair, |
Fortan 95 is just a small incremental change to Fortran 90, so I don't think there's much benefit for making a split between these two languages. Maybe a split can happen when we start working on intrinsics that were introduced in Fortran 2003. @schweitzpgi and @jeanPerier might have some ideas here. |
My main rationale for splitting it would be the fact that it is so large. There are benefits to having fewer cases per test file:
There are good reasons to keep everything in one file too and a lot of it is just a matter of preference. The actual reason to bring this up in this patch is that I'm adding 244 lines of tests. That's quite a lot and personally I'd prefer to move it to a separate file. But that's nothing major and I'm happy to keep things as is. |
I agree with the points you are bringing, splitting it sounds reasonable to me. One test file per intrinsic may be a bit overkill, especially for the tiny ones. But I am not sure what would be the good split. I would like a split that is easy to reason about, so that it's clear for people where they must add their tests, and it is easy to audit which intrinsics have a test. The standard version split may be a bit annoying to follow and may still lead to big test files. |
It might make sense to split along some alphabetical order. For example, intrinsics that start with the letters 'A' through 'M' in one file and 'N' through 'Z' in another file. Or depending on the number of intrinsics per letter, split into more than two files. |
It would be nice to have the same file structure (as much as practical) across all of the tests -- semantics, lowering, runtime. Is there an intern who might be willing to take this on? |
I think that having one file per intrinsic would be the most intuitive approach. There are multiple precedents for that in llvm-project (e.g. SVE intrinsics in Clang). This approach makes triaging failures very easy. It also speeds-up testing (LIT will run tests in parallel). It's not too much work to implement: #927. By the way, shall we move this discussion to #927 ? I've created that PR to make it easier for us to see the possible options. Please reject it if you don't like my suggestion. As for |
@@ -120,6 +120,12 @@ mlir::Value genProduct(Fortran::lower::FirOpBuilder &builder, | |||
mlir::Location loc, mlir::Value arrayBox, | |||
mlir::Value maskBox, mlir::Value resultBox); | |||
|
|||
/// Generate call to Product intrinsic runtime routine. This is the version |
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.
Nit: Product -> DotProduct
auto sourceLine = | ||
Fortran::lower::locationToLineNo(builder, loc, fTy.getInput(3)); | ||
auto args = Fortran::lower::createArguments( | ||
builder, loc, fTy, vectorABox, vectorBBox, sourceFile, sourceLine); |
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 see the same in genSum and genProd, but why is the resultBox not included here?
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.
In this case, it's similar for product
: https://github.com/flang-compiler/f18-llvm-project/blob/fir-dev/flang/lib/Lower/ReductionRuntime.cpp#L712-L713. resultBox
is included when if (fir::isa_complex(eleTy))
returns true
(L863).
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.
Correct. resultBox is only used with the complex case in these functions.
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.
Looks good. Please address Kiran's nit and squash your commits before merging. Thanks!
Rabased, squashed, [nit] addressed. |
All tests from flang/test/Lower/intrinsic-procedures.f90 are moved to dedicated files (with the exception of `lge`, `lgt`, `lle` and `llt`). With this change, every filename clearly defines which intrinsic procedure is being tested. After the initial split, we discovered that some tests were invalid (e.g. `! CHECK` was used instead of `! CHECK:`). These tests are now fixed. Some tests are additionally hardened (e.g. some `CHECK-DAG` directives was replaced with `CHECK`). Some tests are updated with checks generated with mlir/utils/generate-test-checks.py. In other words, this patch _moves_ and _reformats_ the tests. The documentation is updated accordingly (with some extra clarifications, as suggested by the reviewers). Please see the following PRs for a complete discussion: * #927 * #914
All tests from flang/test/Lower/intrinsic-procedures.f90 are moved to dedicated files (with the exception of `lge`, `lgt`, `lle` and `llt`). With this change, every filename clearly defines which intrinsic procedure is being tested. After the initial split, we discovered that some tests were invalid (e.g. `! CHECK` was used instead of `! CHECK:`). These tests are now fixed. Some tests are additionally hardened (e.g. some `CHECK-DAG` directives was replaced with `CHECK`). Some tests are updated with checks generated with mlir/utils/generate-test-checks.py. In other words, this patch _moves_ and _reformats_ the tests. The documentation is updated accordingly (with some extra clarifications, as suggested by the reviewers). Please see the following PRs for a complete discussion: * #927 * #914
Hi, I still have a few cases left to implement in
Fortran::lower::genDotProduct
. Any pointers would be much appreciated!I'm sending this for early feedback to make sure that this is the right approach.