Skip to content

Implement unique function to stdlib_sorting - #1200

Open
Mahmood-Sinan wants to merge 10 commits into
fortran-lang:masterfrom
Mahmood-Sinan:unique_function
Open

Implement unique function to stdlib_sorting#1200
Mahmood-Sinan wants to merge 10 commits into
fortran-lang:masterfrom
Mahmood-Sinan:unique_function

Conversation

@Mahmood-Sinan

Copy link
Copy Markdown
Contributor

This PR adds a generic unique function to stdlib_sorting for extracting the distinct elements of rank-1 arrays.

  • Support integer and real arrays.
  • Support two modes of operation:
    • sorted output (sorted_output = .true.)
    • order of first occurrence (sorted_output = .false.)
  • Add an optional tolerance argument for real arrays when sorted_output = .true. to support approximate equality comparisons.

Limitations

@codecov

codecov Bot commented Jul 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 68.20%. Comparing base (4c8521d) to head (1dc7f08).
⚠️ Report is 46 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1200      +/-   ##
==========================================
- Coverage   68.81%   68.20%   -0.61%     
==========================================
  Files         408       19     -389     
  Lines       13726     2378   -11348     
  Branches     1552        0    -1552     
==========================================
- Hits         9446     1622    -7824     
+ Misses       4280      756    -3524     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@jalvesz
jalvesz requested a review from Copilot July 27, 2026 18:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.

Suppressed comments (11)

src/sorting/stdlib_sorting.fypp:536

  • This example uses b = unique(...) as if unique were a function, but unique is a subroutine in this module. The example as written won’t compile.
!!    b = unique(a, .true.)

src/sorting/stdlib_sorting.fypp:489

  • The module-level documentation describes unique as a function (output = unique(...)), but the public API implemented below is a generic subroutine (call unique(array, sorted_output, output[, tolerance])). This mismatch will mislead users and contradicts the rest of the module’s procedure docs.
!! The generic function implementing the `UNIQUE` algorithm to return the 
!! distinct elements of a rank-1 array. The result may either preserve the
!! order of first occurrence or be returned in sorted order.
!!
!! Its use has the syntax: 

src/sorting/stdlib_sorting.fypp:526

  • This example uses b = unique(...) as if unique were a function, but unique is a subroutine in this module. The example as written won’t compile.

This issue also appears on line 536 of the same file.

!!    b = unique(a, .false.)

src/sorting/stdlib_sorting.fypp:516

  • The inline markup for real(xdp) is malformed (real(xdp)), which breaks the rendered documentation.
!! **Note:** The unsorted (`sorted_output = .false.`) implementation is
!! currently unavailable for `real(`xdp`)` because hashing is
!! performed on the underlying binary representation, which is not
!! sufficiently portable for this kind.

src/sorting/stdlib_sorting_unique.fypp:53

  • For real overloads, tolerance is validated unconditionally, even when sorted_output is .false. (where tolerance is documented as not applicable). This means callers can get a tolerance-related error stop in unsorted mode, and passing a positive tolerance is silently ignored. Consider only reading/validating tolerance when sorted_output is .true., and rejecting present(tolerance) when sorted_output is .false..
        #:if t1.startswith('real')
        tolerance_ = optval(tolerance, 0.0_${name1}$)
        if(tolerance_ < 0.0_${name1}$) error stop "tolerance must be non-negative"
        #:endif
        allocate(temp, source=A)

src/sorting/stdlib_sorting_unique.fypp:11

  • use stdlib_constants is unused in this submodule (all referenced symbols come from host association / intrinsics). Keeping it forces an extra library dependency in the sorting CMake target.
    use stdlib_constants

src/sorting/stdlib_sorting_unique.fypp:93

  • output is allocated to size(temp) and then immediately assigned pack(temp, mask), whose size is typically smaller. With allocatable assignment, this triggers a deallocate/reallocate anyway, so the manual allocation block is redundant and can add overhead.
        if (.not. allocated(output)) then
            allocate(output(size(temp)))
        else if (size(output) < size(temp)) then
            deallocate(output)
            allocate(output(size(temp)))

src/sorting/stdlib_sorting_unique.fypp:130

  • Same as in *_sort_unique: output is allocated to size(temp) and then assigned pack(temp, mask), which will generally force reallocation. This allocation block can be removed to avoid extra allocate/deallocate churn.
        if (.not. allocated(output)) then
            allocate(output(size(temp)))
        else if (size(output) < size(temp)) then
            deallocate(output)
            allocate(output(size(temp)))

doc/specs/stdlib_sorting.md:30

  • The overview still says there are "four overloaded subroutines", but the list now contains five (ORD_SORT, SORT, RADIX_SORT, SORT_INDEX, UNIQUE).
The module `stdlib_sorting` defines several public entities, two
default integer parameters, `int_index` and `int_index_low`, and four overloaded
subroutines: `ORD_SORT`, `SORT`, `RADIX_SORT`, `SORT_INDEX` and `UNIQUE`.
The overloaded subroutines also each have several specific names for

test/sorting/test_sorting_unique.fypp:128

  • The real-kind tests exclude xdp entirely (#:if name1 != 'xdp'). Since the implementation only lacks the unsorted mode for xdp, this leaves the sorted unique path untested when WITH_XDP is enabled.
        #:for t1, t2, name1, cpp1 in REAL_TYPES_ALT_NAME
        #:if name1 != 'xdp'
        block

src/sorting/stdlib_sorting.fypp:491

  • The documented syntax line still shows the function form (output = unique(...)), but the implemented interface is call unique(array, sorted_output, output[, tolerance]).
!! Its use has the syntax: 
!!     output = unique(array, sorted_output[, tolerance] )
!!

Comment thread doc/specs/stdlib_sorting.md Outdated
Co-authored-by: José Alves <102541118+jalvesz@users.noreply.github.com>
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.

3 participants