Skip to content

Adding filter function#1951

Open
wostrie2 wants to merge 10 commits intoCEED:mainfrom
wostrie2:adding_filter_function
Open

Adding filter function#1951
wostrie2 wants to merge 10 commits intoCEED:mainfrom
wostrie2:adding_filter_function

Conversation

@wostrie2
Copy link
Copy Markdown

Purpose:

Add CeedVectorFilter function to filter or clip a CeedVector using a threshold value. Vector entries with absolute value less than threshold are clipped to 0.0.

This may be considered a WIP pull request.

Default implementation of the function and a test, t129-vector.c, are implemented.

GPU backends have NOT been implemented yet.

Addresses Issue #1830

LLM/GenAI Disclosure: Google AI mode was used to check syntax for the function, and its suggestion to use the CeedPragmaSIMD macro was adopted. Google AI mode was used to write piece of the test for this function, t129-vector.c

By submitting this PR, the author certifies to its contents as described by the Developer's Certificate of Origin.
Please follow the Contributing Guidelines for all PRs.

Comment thread tests/t129-vector.c Outdated
@jeremylt
Copy link
Copy Markdown
Member

This looks pretty good. The test is a rather different style than what we usually use, so I'll have some comments for you there soon. Let me know if you have questions as you keep working!

Copy link
Copy Markdown
Member

@jeremylt jeremylt left a comment

Choose a reason for hiding this comment

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

The bulk of this outside of t129-vector.c looks really good. Lemmie cook up a separate comment about what exactly I would do for the test though

Comment thread interface/ceed-vector.c Outdated
Comment thread interface/ceed-vector.c Outdated
@jeremylt
Copy link
Copy Markdown
Member

jeremylt commented Apr 16, 2026

Ok, here is what I would do for the tests.

You should think of the tests as an extension of the documentation. To that end, they should all have a similar look/feel so that it is easier for people to review the tests and see how specific functions work.

So, I would start with an existing test instead of making a brand new one.

Let's start with t123-vector.c, the CeedVectorScale() test.


/// @file
/// Test scaling a vector
/// \test Test scaling of a vector

//TESTARGS(name="length 10") {ceed_resource} 10
//TESTARGS(name="length 0") {ceed_resource} 0
#include <ceed.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
  Ceed       ceed;
  CeedVector x;
  CeedInt    len = 10;

  CeedInit(argv[1], &ceed);
  len = argc > 2 ? atoi(argv[2]) : len;

  CeedVectorCreate(ceed, len, &x);
  {
    CeedScalar array[len];

    for (CeedInt i = 0; i < len; i++) array[i] = 10 + i;
    CeedVectorSetArray(x, CEED_MEM_HOST, CEED_COPY_VALUES, array);
  }
  {
    // Sync memtype to device for GPU backends
    CeedMemType type = CEED_MEM_HOST;
    CeedGetPreferredMemType(ceed, &type);
    CeedVectorSyncArray(x, type);
  }
  CeedVectorScale(x, -0.5);

  {
    const CeedScalar *read_array;

    CeedVectorGetArrayRead(x, CEED_MEM_HOST, &read_array);
    for (CeedInt i = 0; i < len; i++) {
      if (fabs(read_array[i] + (10.0 + i) / 2) > 1e-14) {
        // LCOV_EXCL_START
        printf("Error in alpha x at index %" CeedInt_FMT ", computed: %f actual: %f\n", i, read_array[i], -(10.0 + i) / 2);
        // LCOV_EXCL_STOP
      }
    }
    CeedVectorRestoreArrayRead(x, &read_array);
  }

  CeedVectorDestroy(&x);
  CeedDestroy(&ceed);
  return 0;
}

I like to consider the edge cases here. Two come to mind immediately

  • positive vs negative values
  • less than vs equal to the threshold

The test file t123-vector.c suggests a third edge case

  • length 0 vectors

So that should guide our modification of this code to make a test for CeedVectorFilter.

If we change

    for (CeedInt i = 0; i < len; i++) array[i] = 10 + i;

into a different pattern, then we can build array contents that hit our edge case concerns.
Perhaps something like 2 + i * pow(-1, i)?

I would then replace the CeedVectorScale call with a CeedVectorFilter call (to do this, you probably want to create a tolerance variable?`

I would then replace the logic following CeedVectorGetArrayRead to ensure that the contents of read_array are the same as the pattern you picked above unless the value should be filtered out.

It may be worth doing this twice, the second time with a bigger value of threshold. That way you could check with a threshold value that is the same as one of the array entries and a threshold value that is in between two array entry values.

Does that all make sense?

wostrie2 and others added 3 commits April 16, 2026 13:45
Small documentation formatting change.

Co-authored-by: Jeremy L Thompson <jeremy@jeremylt.org>
Use CeedCall for call to backend implementation.

Co-authored-by: Jeremy L Thompson <jeremy@jeremylt.org>
Add empty line to end of file.

Co-authored-by: Jeremy L Thompson <jeremy@jeremylt.org>
@wostrie2
Copy link
Copy Markdown
Author

Thanks, Jeremey! I think that's all making sense. Ah, it makes sense how you are explaining the tests in general. I should have asked about the test for the Scale function.

Are you thinking of just making one vector and changing the threshold for the different test cases?

@jeremylt
Copy link
Copy Markdown
Member

Yeah, that is how I would do it. I don't see a reason why the vector itself would make a big difference, unless its of a special length (length 0 specifically).

CI has given the following style fix:

index 4abc4d6..d829c7a 100644
--- a/interface/ceed-vector.c
+++ b/interface/ceed-vector.c
@@ -789,8 +789,7 @@ int CeedVectorFilter(CeedVector x, CeedScalar threshold) {
   // Default implementation
   CeedCall(CeedVectorGetArray(x, CEED_MEM_HOST, &x_array));
   assert(x_array);
-  CeedPragmaSIMD
-  for (CeedSize i = 0; i < length; i++) {
+  CeedPragmaSIMD for (CeedSize i = 0; i < length; i++) {
     if (fabs(x_array[i]) <= threshold) x_array[i] = 0.0;
   }
   CeedCall(CeedVectorRestoreArray(x, &x_array));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants