Skip to content
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

[stdlib_linalg] Update eye function. #481

Merged
merged 6 commits into from
Aug 23, 2021
Merged

[stdlib_linalg] Update eye function. #481

merged 6 commits into from
Aug 23, 2021

Conversation

zoziha
Copy link
Contributor

@zoziha zoziha commented Aug 1, 2021

  • Update eye function, add support that matrix is not square.
  • Based on storage considerations, integer(int8) will used as the return value type.
  • allocation or automatic: allocation because of optional dim2!(see [stdlib_linalg] Update eye function. #481 (comment))

Description

That eye creates a non-square matrix would be a nice update.

Notes

More routines to do, not this PR
see #476.

@jvdp1 jvdp1 added the reviewers needed This patch requires extra eyes label Aug 1, 2021
@jvdp1 jvdp1 requested a review from ivan-pi August 1, 2021 15:35
@Jim-215-Fisher
Copy link
Contributor

I will review this one.

doc/specs/stdlib_linalg.md Outdated Show resolved Hide resolved
doc/specs/stdlib_linalg.md Outdated Show resolved Hide resolved
src/stdlib_linalg.fypp Outdated Show resolved Hide resolved
Copy link
Member

@awvwgk awvwgk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for sharing, @zoziha. Thanks for reviewing @Jim-215-Fisher. Looks good to me, except for one issue with merge.

1. `merge` -> `optval` inside.
Copy link
Contributor

@nshaffer nshaffer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made a few suggestions, but mostly seems good to me. Let me know if you have any questions about my review.

doc/specs/stdlib_linalg.md Outdated Show resolved Hide resolved
doc/specs/stdlib_linalg.md Outdated Show resolved Hide resolved
doc/specs/stdlib_linalg.md Outdated Show resolved Hide resolved
src/tests/linalg/test_linalg.f90 Outdated Show resolved Hide resolved
Copy link
Member

@jvdp1 jvdp1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this PR. I have a few suggestions/comments/questions.

doc/specs/stdlib_linalg.md Outdated Show resolved Hide resolved

integer, intent(in) :: dim1
integer, intent(in), optional :: dim2
integer, allocatable :: result(:, :)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you avoid the allocatable status, like for other functions in stdlib?

Copy link
Contributor Author

@zoziha zoziha Aug 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(see #478 (comment), #477 (comment), and https://community.intel.com/t5/Intel-Fortran-Compiler/how-to-set-the-stack-size/td-p/933530)
It seems that ifort places the automatic array in the heap by default, which leads to a stack overflow when the dimension of the automatic array is large. Or is there any disadvantage of the allocatable array, need to avoid it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My comment was based on @certik and @milancurcic 's comments (this comment and following ones).

Furthermore, the rules for stack vs heap can be different between compilers/OS, and can be also changed within a compiler through a compiler option (e.g., using Gfortran with -Ofast will imply -fstack-arrays, that will put all arrays of unknown size and temporary arrays onto stack memory, which can create issues for very large arrays).

Therefore, I am in favor to always use automatic arrays when possible.

@certik @milancurcic @awvwgk @ivan-pi Any comments on that topic?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may indeed be a big controversy, it seems to be: @awvwgk agrees with allocation array, @jvdp1 agrees with automatic array.
By default, ifort's automatic array solution faces large-scale arrays, it is easier to report an error: stack overflow. (see #478 (comment), #477 (comment), and https://community.intel.com/t5/Intel-Fortran-Compiler/how-to-set-the-stack-size/td-p/933530)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I suggest using automatic array wherever possible, and allocatable otherwise. In this case, it seems like you need to make it allocatable because the second dimension depends on the presence of the optional dummy argument.

However, if you re-write this to be two specific procedures under one generic name, instead of using the optional argument, then I think you don't need allocatable for the result.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I'm not a fan of automatic arrays, since usage with ifort will lead to stack overflows. The option to allocate automatic arrays on the heap rather than on the stack is there, for ifort it happens to be buggy (heap allocation is not always freed). gfortran is doing a little better here, but it is an issue as well.

So far automatic array usage has resulted in a significant amount of support request from users for me. Setting the system stack with ulimit -s unlimited works, still this is something the user has to remember.

Copy link
Member

@milancurcic milancurcic Aug 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@awvwgk I don't think that's a good reason to avoid a language feature. If a feature (and a very old one) doesn't work with a compiler, let's report it. Avoiding it only helps permeate the bug with the compiler. I've been using this with ifort since 2010 and haven't seen an issue. It's possible that I didn't notice it.

The downside to the allocatable approach is that it's always on the heap. The user doesn't have the choice and always gets the less-performant implementation. Also, in the optional argument approach, it's possible (but I'm not sure) that the compiler would evaluate the branch inside the function at run-time rather than compile-time. If at run-time, that would be another performance penalty. It's possible that performance is less important for eye, I don't know. And the advantage to the allocatable approach is, of course, that it's always on the heap. :)

@zoziha When resolving conversations as a GitHub feature, I suggest to leave a comment about what you decided, otherwise discussions get hidden but aren't really resolved. Maybe we should document this in the Code Review guide.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @milancurcic: issues with some compilers/options/OS/... are not good reasons to avoid a feature of the language.
Futhermore, because it is a small function that would be most often (I guess) used in expressions (e.g., arr1 = eye(5) * scalar), I am also in favor to apply @milancurcic suggestion (i.e., to have 2 specific procedures under one generic name)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jvdp1 okay if we do it in a separate PR and merge this one first? We could evaluate the performance difference too.

@zoziha
Copy link
Contributor Author

zoziha commented Aug 22, 2021

@milancurcic Ok, got it.

  1. I changed the return value type of the eye function to integer(int8);
  2. allocatable is used because of the existence of optional dim2 argument.

At present, the questions raised by @jvdp1 , I think they are answered and resolved.

@milancurcic
Copy link
Member

Okay, thanks. If needed we can revisit the allocatable result later. If there are no objections let's merge this tomorrow.

@jvdp1
Copy link
Member

jvdp1 commented Aug 22, 2021 via email

@milancurcic milancurcic merged commit d3b45ed into fortran-lang:master Aug 23, 2021
@zoziha zoziha deleted the update_eye branch August 25, 2021 02:52
@awvwgk awvwgk removed the reviewers needed This patch requires extra eyes label Sep 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants