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

[Proposal] add swap subroutines: swap the values of two variables of the same type ? #462

Closed
zoziha opened this issue Jul 13, 2021 · 7 comments
Labels
idea Proposition of an idea and opening an issue to discuss it topic: utilities containers, strings, files, OS/environment integration, unit testing, assertions, logging, ...

Comments

@zoziha
Copy link
Contributor

zoziha commented Jul 13, 2021

Description

Does stdlib need simple swap routines as follows? (Wait for #449 )

interface swap
    ...
end interface swap

!! Swap the values of two variables of the same type.
!! `type & kind` description: logical, integer, real, complex, character, string_type
pure elemental subroutine swap_${t1[0]}$${k1}$(a, b)
	${t1}$, intent(inout) :: a, b
	${t1}$ :: c
	c = a
	a = b
	b = c
end subroutine swap_${t1[0]}$${k1}$

call [[stdlib_math(module):swap(interface)]](a, b)

The use of swap already in stdlib:

  1. Initial implementation of COO / CSR sparse format #189 (comment)
  2. https://github.com/fortran-lang/stdlib/blob/888b5d343e5579a392273755b66394404fd361f9/src/stdlib_sorting_sort.fypp#L216~L219
@zoziha zoziha added the idea Proposition of an idea and opening an issue to discuss it label Jul 13, 2021
@zoziha zoziha changed the title [Proposal] add swap subroutines: [Proposal] add swap subroutines: swap the values of two variables of the same type Jul 13, 2021
@zoziha zoziha changed the title [Proposal] add swap subroutines: swap the values of two variables of the same type [Proposal] add swap subroutines: swap the values of two variables of the same type ? Jul 13, 2021
@aman-godara
Copy link
Member

swap using move_alloc for string_type (or in combination with allocatable character (character(len=:), allocatable)) might be a useful addition.

@zoziha
Copy link
Contributor Author

zoziha commented Aug 7, 2021

swap using move_alloc for string_type (or in combination with allocatable character (character(len=:), allocatable)) might be a useful addition.

Hello @aman-godara , for string_type, is there any significant difference in efficiency when swap uses move_alloc or assignment(=)?

@aman-godara
Copy link
Member

aman-godara commented Aug 7, 2021

a = string_type( "... a very long string ..." )
b = string_type( "... another long string ..." )
Now if you want to swap a and b, using assignment operator your approach will be something like this:

c = a ! This will create a deep copy (since the underlying `raw` variable is `allocatable` and NOT `pointer`) of `a` and assign it to `c`)
a = b
b = c

Using move_alloc it will be like this:

move_alloc( a, c ) ! happens in O(1) time since no new copy has been created
move_alloc( b, a )
move_alloc( c, b )

So move_alloc is faster and takes O(1) extra space whereas assignment operator takes O(m) extra space and executes in O(m + n). Here m and n are the lengths of the input a and b

@zoziha
Copy link
Contributor Author

zoziha commented Aug 7, 2021

Thank you for your reply. I just tested it and found that string_type%raw is of a private attribute, so we can't directly access allocatable raw using move_alloc.

    type :: string_type
        ! Use the sequence statement below as a hack to prevent extending this type.
        ! It is not used for storage association.
        sequence
        private
        character(len=:), allocatable :: raw  !! Component 'raw' is a PRIVATE component of 'string_type'
    end type string_type

And move_alloc requires its arguments to be allocatable.

type(string_type) :: a, b !! They are not allocatable.
a = string_type( "... a very long string ..." )
b = string_type( "... another long string ..." )
call move_alloc( b, a )   !! Error: `move_alloc` requires its arguments to be `allocatable`.

I also found that move_alloc is indeed more efficient than assignment operation. 👍

@aman-godara
Copy link
Member

aman-godara commented Aug 7, 2021

you cannot access raw variable outside of stdlib_stringtype.f90 file.
Yes you are right move_alloc requires it arguments to be allocatable. Excuse me if I gave you wrong impression above. First we need to create a function which does equivalent of move_alloc for string_type and then use it in swap function.

In my comment above, by move_alloc( a, c ) I meant call a subroutine which does equivalent of move_alloc for string_type.
Look at this PR to know more.

@zoziha
Copy link
Contributor Author

zoziha commented Aug 7, 2021

Thank you very much!😘 Understood!

@awvwgk awvwgk added the topic: utilities containers, strings, files, OS/environment integration, unit testing, assertions, logging, ... label Sep 18, 2021
@zoziha
Copy link
Contributor Author

zoziha commented Mar 20, 2025

Completed in #869. Now closed.

@zoziha zoziha closed this as completed Mar 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
idea Proposition of an idea and opening an issue to discuss it topic: utilities containers, strings, files, OS/environment integration, unit testing, assertions, logging, ...
Projects
None yet
Development

No branches or pull requests

3 participants