Skip to content

Ability to bypass the kernel argument validity check + Eigen compatibility #725

Open
@ralwing

Description

@ralwing

Hi,
I'm getting back with some library incompatibility issue.
In my branch https://github.com/ralwing/cuda-api-wrappers/tree/eigen-compat, commit and ralwing@aed66ce
which has some custom changes (e.g by default it compiles as c++17) i test Eigen::Vector and cuda::std::span
The main problem I face here is the requirement:

 static assertion failed with "All kernel parameter types must be of a trivially copy-constructible (decayed) type."

which are already mentioned #551 and #642.

From my understanding of the argument passing documentation Eigen fullfils the requirement to be passed as a kernel argument, although it doesn't meet the std::is_trivially_copyconstructible trait.

So the main problem with this assertion is that it doesn't allow usage of the Eigen structures, as kernel vector. In my code i commented out the part that doesn't compile:

	   auto launch_config =
	       cuda::launch_config_builder().overall_size(1).block_size(256).build();
 
	   auto A = DataType{1.0, 2.0, 3.0};
	   auto B = DataType{4.0, 5.0, 6.0};
	   DataType result;
	   auto d_result =
	       cuda::memory::make_unique_region(device, 1 * sizeof(DataType));
 
	   auto sp_result = d_result.as_span<DataType>();
	   stream.enqueue.kernel_launch(vectorAddValue, launch_config, A, B,
	                                sp_result.data());
	   stream.enqueue.copy(h_result, d_result);
	   stream.synchronize();
	   print_result(A, B, result);

However, passing them as span, or pointer works perfectly fine, even though the code should also be asserted if such argument is forbidden.

I must admit I perfectly understand Your point of view: cuda-api-wrappers framework should make the cuda code safer, which means we should avoid any Undefined Behaviors, however assertion can be bypassed or disables the usage of commonly used library.

My idea here is to allow usage of custom traits for libraries which user can enable when
User code must ensure that this workflow does not affect program correctness.

This could be implemented like:

template<typename T>
struct is_gpu_compatible : std::is_trivially_copy_constructible<T> {};


static_assert(
    detail_::all_true< 
        ::is_gpu_compatible< detail_::kernel_parameter_decay_t<KernelParameters> >::value...
    >::value,
    "All kernel parameter types must be GPU-compatible."
);

And then I could use this trait in my code:

namespace my_library_traits {

template<>
struct is_gpu_compatible<Eigen::Matrix<float, 3, 1, 0, 3, 1>> : std::true_type {};

} // namespace my_library_traits

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions