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

[FEA]: Expand thrust::complex to be usable at compile time #485

Open
1 task done
miscco opened this issue Sep 26, 2023 · 8 comments
Open
1 task done

[FEA]: Expand thrust::complex to be usable at compile time #485

miscco opened this issue Sep 26, 2023 · 8 comments
Labels
feature request New feature or request. good first issue Good for newcomers. help wanted Request for input or help from the community thrust For all items related to Thrust.

Comments

@miscco
Copy link
Collaborator

miscco commented Sep 26, 2023

Is this a duplicate?

Area

Thrust

Is your feature request related to a problem? Please describe.

With the rework of thrust::complex to be based upon cuda::std::complex we can leverage the later ones constexpr support

Describe the solution you'd like

We should expand existing operators / methods with the appropriate constexpr qualifier.

This would also require us to rework the way we internally test thrust::complex

Usually if there was a void test_something() function previously one would split it up into a constexpr bool test_something_impl() and then use

void test_something() {
    test_something_impl();

#if TEST_STD_VER >= 14
    static_assert(test_something_imple(), "");
#endif // TEST_STD_VER >= 14
}

Describe alternatives you've considered

No response

Additional context

No response

@miscco miscco added feature request New feature or request. good first issue Good for newcomers. thrust For all items related to Thrust. help wanted Request for input or help from the community labels Sep 26, 2023
@srinivasyadav18
Copy link
Contributor

Hi, this looks like a good first issue. I would like to help by contributing to this issue.

@miscco
Copy link
Collaborator Author

miscco commented Oct 10, 2023

@srinivasyadav18 that is awesome 🎉

If you have any questions feel free to poke here or on our discord server.

I am happy to give you a rundown of the required changes

@srinivasyadav18
Copy link
Contributor

@miscco Thanks for the quick response.

If my understanding is correct, we constexpr all the operators and methods in cccl/thrust/thrust/complex.h for thrust::complex. May I know if I have to use actual constexpr C++ keyword or something like _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 which is used in ::cuda::std::complex (cccl/libcudacxx/include/cuda/std/detail/libcxx/include/complex) .

I understand that testing here : NVIDIA/cccl/thrust/testing/complex.cu has to be update appropriately with the constexpr changes. Is that correct ?

Any further insights would highly appreciated. Thanks!

@miscco
Copy link
Collaborator Author

miscco commented Oct 10, 2023

If my understanding is correct, we constexpr all the operators and methods in cccl/thrust/thrust/complex.h for thrust::complex. May I know if I have to use actual constexpr C++ keyword or something like _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 which is used in ::cuda::std::complex (cccl/libcudacxx/include/cuda/std/detail/libcxx/include/complex) .

You are absolutely right, we cannot use plain constexpr here, as we technically still support C++11. I believe for now the easiest solution would be to just reuse _LIBCUDACXX_CONSTEXPR_AFTER_CXX11.

I have some ToDo items to unify our support macros, but that is a different topic

I understand that testing here : NVIDIA/cccl/thrust/testing/complex.cu has to be update appropriately with the constexpr changes. Is that correct ?

Yes those tests need to be changed. We are both lucky and unlucky here. Lets have a look at one of the tests:

template <typename T>
struct TestComplexConstructionAndAssignment
{
  void operator()()
  {
    thrust::host_vector<T> data = unittest::random_samples<T>(2);

    const T real = data[0];
    const T imag = data[1];

    {
      const thrust::complex<T> construct_from_real_and_imag(real, imag);
      ASSERT_EQUAL(real, construct_from_real_and_imag.real());
      ASSERT_EQUAL(imag, construct_from_real_and_imag.imag());
    }

    ....
 }
};

The basic stategy is to just make the test constexpr and let it return a boolean:

template <typename T>
struct TestComplexConstructionAndAssignment
{
  _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 bool operator()()
  {
    thrust::host_vector<T> data = unittest::random_samples<T>(2);

    const T real = data[0];
    const T imag = data[1];

    {
      const thrust::complex<T> construct_from_real_and_imag(real, imag);
      ASSERT_EQUAL(real, construct_from_real_and_imag.real());
      ASSERT_EQUAL(imag, construct_from_real_and_imag.imag());
    }

    ....

    return true;
 }
};

That way we can test both runtime and compile time via:

TestComplexConstructionAndAssignment test{};

test();
#if THRUST_CPP_DIALECT > 11
static_assert(test(), "");
#endif // THRUST_CPP_DIALECT > 11

The main problem we will face is that currently our helper class SimpleUnitTest does not support that pattern. So we would have to duplicate that class, e.g SimpleConstexprUnitTest and expand its functionality so that it runs the test both at runtime and compile time

@srinivasyadav18
Copy link
Contributor

@miscco Thanks! I will make the changes and test it out.

@srinivasyadav18
Copy link
Contributor

srinivasyadav18 commented Oct 21, 2023

@miscco I have constexpr'd all the constructors and operators for thrust::complex.
However for the tests I have a solution that looks something like this :

  template <typename T>
struct TestConstexprComplexConstructionAndAssignment
{
  void operator()(void)
  {
    {
      // fixed values, as random number generation is not compile time.
      constexpr T real = static_cast<T>(42);
      constexpr T imag = static_cast<T>(120);

      constexpr thrust::complex<T> construct_from_real_and_imag(real, imag);

      // compile time check
      static_assert(real == construct_from_real_and_imag.real());
      static_assert(imag == construct_from_real_and_imag.imag());
    }
  }
};
SimpleUnitTest<TestConstexprComplexConstructionAndAssignment, FloatingPointTypes>
  TestConstexprComplexConstructionAndAssignmentInstance;

This is may not be permanent fix, but this is just an idea that I got.
The reasons are :

  1. The function template that returns random_samples in form of thrust::host_vector ( thrust::host_vector<T> data = unittest::random_samples<T>(2); is not at compile time, because they are not constexpr. Since I have to construct the object at compilte time, for the real and imag values I have them fixed to some const values known at compile time.
  2. I used static_assert instead of ASSERT_EQUAL, because static_assert checks at compile time, where as ASSERT_EQUAL looks like it happens at runtime.
  3. Eliminates the need of a new unit test class (SimpleConstexprUnitTest), because both compile time and runtime checks needs just a different way to test the functionality. This test works with same SimpleUnitTest class, but with a different name for instantiation (TestConstexprComplexConstructionAndAssignment).

@miscco
Copy link
Collaborator Author

miscco commented Oct 21, 2023

We can go that route, but it would essentially duplicate all the test code which is suboptimal.

@senior-zero do we have a plan on when to rewrite the thrust tests to catch2?

@gevtushenko
Copy link
Collaborator

@senior-zero do we have a plan on when to rewrite the thrust tests to catch2?

We occasionally discuss this possibility, but even if we decide to, it won't happen soon.

elstehle pushed a commit to elstehle/cccl that referenced this issue Nov 16, 2023
* Add gcc-6 image

* Avoid build breaks due to gcc-6

* Disable failing libcxx tests for gcc-6

* Make tests pass with gcc-6 and c++14

* Make tests pass with gcc-6 and c++17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request New feature or request. good first issue Good for newcomers. help wanted Request for input or help from the community thrust For all items related to Thrust.
Projects
Status: Todo
Development

No branches or pull requests

3 participants