From 3c7f0a70bf0ff842d5180e7f03831378890814ac Mon Sep 17 00:00:00 2001 From: pciolkosz Date: Thu, 1 Jan 2026 16:50:57 -0800 Subject: [PATCH 1/5] Add some missing any_resource tests --- .../any_resource/any_resource.cu | 122 ++++++++++++++++- .../any_resource/any_synchronous_resource.cu | 128 ++++++++++++------ 2 files changed, 206 insertions(+), 44 deletions(-) diff --git a/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_resource.cu b/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_resource.cu index 5edb3cbb3c3..19f05c3d891 100644 --- a/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_resource.cu +++ b/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_resource.cu @@ -61,18 +61,30 @@ TEMPLATE_TEST_CASE_METHOD(test_fixture, "any_resource", "[container][resource]", ++expected.object_count; CHECK(this->counts == expected); CHECK(mr == mr2); - ++expected.equal_to_count; + CHECK(!(mr != mr2)); + expected.equal_to_count += 2; CHECK(this->counts == expected); auto mr3 = std::move(mr); expected.move_count += !is_big; // for big resources, move is a pointer swap CHECK(this->counts == expected); CHECK(mr2 == mr3); + CHECK(!(mr2 != mr3)); + expected.equal_to_count += 2; + CHECK(this->counts == expected); + + // Test inequality with different resource + cuda::mr::any_resource<::cuda::mr::host_accessible> mr4{TestResource{43, this}}; + expected.new_count += is_big; + ++expected.object_count; + ++expected.move_count; + CHECK(this->counts == expected); + CHECK(mr2 != mr4); ++expected.equal_to_count; CHECK(this->counts == expected); } - expected.delete_count += 2 * is_big; - expected.object_count -= 2; + expected.delete_count += 3 * is_big; + expected.object_count -= 3; CHECK(this->counts == expected); } @@ -165,6 +177,100 @@ TEMPLATE_TEST_CASE_METHOD(test_fixture, "any_resource", "[container][resource]", // Reset the counters: this->counts = Counts(); + SECTION("conversion to any_synchronous_resource") + { + Counts expected{}; + CHECK(this->counts == expected); + { + cuda::mr::any_resource<::cuda::mr::host_accessible> mr{TestResource{42, this}}; + expected.new_count += is_big; + ++expected.object_count; + ++expected.move_count; + CHECK(this->counts == expected); + + cuda::mr::any_synchronous_resource<::cuda::mr::host_accessible> sync_mr = std::move(mr); + // Move from any_resource to any_synchronous_resource + expected.move_count += 2 * !is_big; // for big resources, move is a pointer swap + CHECK(this->counts == expected); + + void* ptr = sync_mr.allocate_sync(this->bytes(100), this->align(8)); + CHECK(ptr == this); + ++expected.allocate_count; + CHECK(this->counts == expected); + sync_mr.deallocate_sync(ptr, this->bytes(100), this->align(8)); + ++expected.deallocate_count; + CHECK(this->counts == expected); + } + expected.delete_count += is_big; + --expected.object_count; + CHECK(this->counts == expected); + } + + // Reset the counters: + this->counts = Counts(); + + SECTION("self-assignment") + { + Counts expected{}; + CHECK(this->counts == expected); + { + cuda::mr::any_resource<::cuda::mr::host_accessible> mr{TestResource{42, this}}; + expected.new_count += is_big; + ++expected.object_count; + ++expected.move_count; + CHECK(this->counts == expected); + + mr = mr; // self copy assignment + CHECK(this->counts == expected); + + CHECK(mr == mr); + CHECK(!(mr != mr)); + expected.equal_to_count += 2; + CHECK(this->counts == expected); + } + expected.delete_count += is_big; + expected.object_count -= 1; + CHECK(this->counts == expected); + } + + // Reset the counters: + this->counts = Counts(); + + SECTION("conversion from resource_ref") + { + Counts expected{}; + CHECK(this->counts == expected); + { + TestResource test{42, this}; + ++expected.object_count; + CHECK(this->counts == expected); + + cuda::mr::resource_ref<::cuda::mr::host_accessible, get_data> ref{test}; + CHECK(this->counts == expected); + + cuda::mr::any_resource<::cuda::mr::host_accessible, get_data> mr = ref; + expected.new_count += is_big; + ++expected.object_count; + ++expected.copy_count; + CHECK(this->counts == expected); + + CHECK(get_property(mr, get_data{}) == 42); + void* ptr = mr.allocate(::cuda::stream_ref{cuda::stream{cuda::device_ref{0}}}, this->bytes(100), this->align(8)); + CHECK(ptr == this); + ++expected.allocate_async_count; + CHECK(this->counts == expected); + mr.deallocate(::cuda::stream_ref{cuda::stream{cuda::device_ref{0}}}, ptr, this->bytes(100), this->align(8)); + ++expected.deallocate_async_count; + CHECK(this->counts == expected); + } + expected.delete_count += is_big; + expected.object_count -= 2; + CHECK(this->counts == expected); + } + + // Reset the counters: + this->counts = Counts(); + SECTION("make_any_resource") { Counts expected{}; @@ -199,9 +305,17 @@ TEMPLATE_TEST_CASE_METHOD( CHECK(get_property(ref, get_data{}) == 43); cuda::mr::resource_ref<::cuda::mr::host_accessible, get_data, extra_property> ref3{mr}; - ref = ref3; + ref = ref3; // copy assignment with property narrowing CHECK(ref.allocate_sync(this->bytes(100), this->align(8)) == this); CHECK(get_property(ref, get_data{}) == 42); + + ref = std::move(ref2); // move assignment + CHECK(ref.allocate_sync(this->bytes(100), this->align(8)) == this); + CHECK(get_property(ref, get_data{}) == 43); + + ref = ref; // self copy assignment + CHECK(ref.allocate_sync(this->bytes(100), this->align(8)) == this); + CHECK(get_property(ref, get_data{}) == 43); } struct host_device_resource diff --git a/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_synchronous_resource.cu b/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_synchronous_resource.cu index 4ecba5790f9..356cd5ace58 100644 --- a/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_synchronous_resource.cu +++ b/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_synchronous_resource.cu @@ -68,18 +68,30 @@ TEMPLATE_TEST_CASE_METHOD( ++expected.object_count; CHECK(this->counts == expected); CHECK((mr == mr2)); - ++expected.equal_to_count; + CHECK(!(mr != mr2)); + expected.equal_to_count += 2; CHECK(this->counts == expected); auto mr3 = std::move(mr); expected.move_count += !is_big; // for big resources, move is a pointer swap CHECK(this->counts == expected); CHECK((mr2 == mr3)); + CHECK(!(mr2 != mr3)); + expected.equal_to_count += 2; + CHECK(this->counts == expected); + + // Test inequality with different resource + cuda::mr::any_synchronous_resource<::cuda::mr::host_accessible, get_data> mr4{TestResource{43, this}}; + expected.new_count += is_big; + ++expected.object_count; + ++expected.move_count; + CHECK(this->counts == expected); + CHECK(mr2 != mr4); ++expected.equal_to_count; CHECK(this->counts == expected); } - expected.delete_count += 2 * is_big; - expected.object_count -= 2; + expected.delete_count += 3 * is_big; + expected.object_count -= 3; CHECK(this->counts == expected); } @@ -120,10 +132,10 @@ TEMPLATE_TEST_CASE_METHOD( CHECK(this->counts == expected); { TestResource resource1{42, this}; - TestResource resource2{42, this}; + TestResource resource2{43, this}; expected.object_count += 2; CHECK(this->counts == expected); - CHECK(resource1 == resource2); + CHECK(!(resource1 == resource2)); ++expected.equal_to_count; CHECK(this->counts == expected); cuda::mr::any_synchronous_resource<::cuda::mr::host_accessible, get_data> mr{resource1}; @@ -132,6 +144,10 @@ TEMPLATE_TEST_CASE_METHOD( ++expected.copy_count; CHECK(this->counts == expected); CHECK(mr == resource1); + CHECK(!(mr != resource1)); + expected.equal_to_count += 2; + CHECK(this->counts == expected); + CHECK(mr != resource2); ++expected.equal_to_count; CHECK(this->counts == expected); } @@ -143,40 +159,6 @@ TEMPLATE_TEST_CASE_METHOD( // Reset the counters: this->counts = Counts(); - SECTION("conversion from any_synchronous_resource to " - "cuda::mr::synchronous_resource_ref") - { - Counts expected{}; - { - cuda::mr::any_synchronous_resource<::cuda::mr::host_accessible, get_data> mr{TestResource{42, this}}; - expected.new_count += is_big; - ++expected.object_count; - ++expected.move_count; - CHECK(this->counts == expected); - - // conversion from any_synchronous_resource to - // cuda::mr::synchronous_synchronous_resource_ref: - cuda::mr::synchronous_resource_ref<::cuda::mr::host_accessible, get_data> ref = mr; - - // conversion from any_synchronous_resource to - // cuda::mr::synchronous_synchronous_resource_ref with narrowing: - cuda::mr::synchronous_resource_ref ref2 = mr; - CHECK(get_property(ref2, get_data{}) == 42); - - CHECK(this->counts == expected); - auto* ptr = ref.allocate_sync(this->bytes(100), this->align(8)); - CHECK(ptr == this); - ++expected.allocate_count; - CHECK(this->counts == expected); - ref.deallocate_sync(ptr, this->bytes(0), this->align(0)); - ++expected.deallocate_count; - CHECK(this->counts == expected); - } - expected.delete_count += is_big; - --expected.object_count; - CHECK(this->counts == expected); - } - SECTION("conversion from any_synchronous_resource to " "cuda::mr::synchronous_resource_ref") { @@ -285,6 +267,68 @@ TEMPLATE_TEST_CASE_METHOD( // Reset the counters: this->counts = Counts(); + SECTION("self-assignment") + { + Counts expected{}; + CHECK(this->counts == expected); + { + cuda::mr::any_synchronous_resource<::cuda::mr::host_accessible, get_data> mr{TestResource{42, this}}; + expected.new_count += is_big; + ++expected.object_count; + ++expected.move_count; + CHECK(this->counts == expected); + + mr = mr; // self copy assignment + CHECK(this->counts == expected); + + CHECK(mr == mr); + CHECK(!(mr != mr)); + expected.equal_to_count += 2; + CHECK(this->counts == expected); + } + expected.delete_count += is_big; + expected.object_count -= 1; + CHECK(this->counts == expected); + } + + // Reset the counters: + this->counts = Counts(); + + SECTION("conversion from resource_ref") + { + Counts expected{}; + CHECK(this->counts == expected); + { + TestResource test{42, this}; + ++expected.object_count; + CHECK(this->counts == expected); + + cuda::mr::resource_ref<::cuda::mr::host_accessible, get_data> ref{test}; + CHECK(this->counts == expected); + + cuda::mr::any_synchronous_resource<::cuda::mr::host_accessible, get_data> mr = ref; + expected.new_count += is_big; + ++expected.object_count; + ++expected.copy_count; + CHECK(this->counts == expected); + + CHECK(get_property(mr, get_data{}) == 42); + void* ptr = mr.allocate_sync(this->bytes(100), this->align(8)); + CHECK(ptr == this); + ++expected.allocate_count; + CHECK(this->counts == expected); + mr.deallocate_sync(ptr, this->bytes(100), this->align(8)); + ++expected.deallocate_count; + CHECK(this->counts == expected); + } + expected.delete_count += is_big; + expected.object_count -= 2; + CHECK(this->counts == expected); + } + + // Reset the counters: + this->counts = Counts(); + SECTION("make_any_synchronous_resource") { Counts expected{}; @@ -319,9 +363,13 @@ TEMPLATE_TEST_CASE_METHOD( CHECK(get_property(ref, get_data{}) == 43); cuda::mr::synchronous_resource_ref<::cuda::mr::host_accessible, get_data, extra_property> ref3{mr}; - ref = ref3; + ref = ref3; // copy assignment with property narrowing CHECK(ref.allocate_sync(this->bytes(100), this->align(8)) == this); CHECK(get_property(ref, get_data{}) == 42); + + ref = std::move(ref2); // move assignment + CHECK(ref.allocate_sync(this->bytes(100), this->align(8)) == this); + CHECK(get_property(ref, get_data{}) == 43); } TEMPLATE_TEST_CASE_METHOD(test_fixture, "Empty property set", "[container][resource]", big_resource, small_resource) From f066647c40ada3ef3df14ab8047c9ee84e7dee9b Mon Sep 17 00:00:00 2001 From: pciolkosz Date: Mon, 5 Jan 2026 15:09:47 -0800 Subject: [PATCH 2/5] Wrap self-assignment --- libcudacxx/test/libcudacxx/cuda/ccclrt/common/utility.cuh | 2 +- .../cuda/memory_resource/any_resource/any_resource.cu | 4 ++-- .../memory_resource/any_resource/any_synchronous_resource.cu | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libcudacxx/test/libcudacxx/cuda/ccclrt/common/utility.cuh b/libcudacxx/test/libcudacxx/cuda/ccclrt/common/utility.cuh index ebd5a2c160f..904e81672de 100644 --- a/libcudacxx/test/libcudacxx/cuda/ccclrt/common/utility.cuh +++ b/libcudacxx/test/libcudacxx/cuda/ccclrt/common/utility.cuh @@ -52,7 +52,7 @@ namespace test template T1& assign(T1& t1, T2&& t2) { - t1 = std::forward(t2); + t1 = ::cuda::std::forward(t2); return t1; } diff --git a/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_resource.cu b/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_resource.cu index 19f05c3d891..2e1119ee481 100644 --- a/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_resource.cu +++ b/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_resource.cu @@ -220,7 +220,7 @@ TEMPLATE_TEST_CASE_METHOD(test_fixture, "any_resource", "[container][resource]", ++expected.move_count; CHECK(this->counts == expected); - mr = mr; // self copy assignment + test::assign(mr, mr); // self copy assignment CHECK(this->counts == expected); CHECK(mr == mr); @@ -313,7 +313,7 @@ TEMPLATE_TEST_CASE_METHOD( CHECK(ref.allocate_sync(this->bytes(100), this->align(8)) == this); CHECK(get_property(ref, get_data{}) == 43); - ref = ref; // self copy assignment + test::assign(ref, ref); // self copy assignment CHECK(ref.allocate_sync(this->bytes(100), this->align(8)) == this); CHECK(get_property(ref, get_data{}) == 43); } diff --git a/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_synchronous_resource.cu b/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_synchronous_resource.cu index 356cd5ace58..fec53749188 100644 --- a/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_synchronous_resource.cu +++ b/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_synchronous_resource.cu @@ -278,7 +278,7 @@ TEMPLATE_TEST_CASE_METHOD( ++expected.move_count; CHECK(this->counts == expected); - mr = mr; // self copy assignment + test::assign(mr, mr); // self copy assignment CHECK(this->counts == expected); CHECK(mr == mr); From a7ff7230e83068633c8af0a14c400747aaba9866 Mon Sep 17 00:00:00 2001 From: pciolkosz Date: Mon, 5 Jan 2026 16:56:36 -0800 Subject: [PATCH 3/5] parentheses around some comparisons --- .../memory_resource/any_resource/any_synchronous_resource.cu | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_synchronous_resource.cu b/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_synchronous_resource.cu index fec53749188..a24ec284701 100644 --- a/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_synchronous_resource.cu +++ b/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_synchronous_resource.cu @@ -86,7 +86,7 @@ TEMPLATE_TEST_CASE_METHOD( ++expected.object_count; ++expected.move_count; CHECK(this->counts == expected); - CHECK(mr2 != mr4); + CHECK((mr2 != mr4)); ++expected.equal_to_count; CHECK(this->counts == expected); } @@ -281,7 +281,7 @@ TEMPLATE_TEST_CASE_METHOD( test::assign(mr, mr); // self copy assignment CHECK(this->counts == expected); - CHECK(mr == mr); + CHECK((mr == mr)); CHECK(!(mr != mr)); expected.equal_to_count += 2; CHECK(this->counts == expected); From fbb43884f71f2ee1aa331b21704081c5f01f1148 Mon Sep 17 00:00:00 2001 From: Piotr Ciolkosz Date: Wed, 29 Apr 2026 17:30:20 -0700 Subject: [PATCH 4/5] Add any_resource -> resource_ref conversion test --- .../any_resource/any_resource.cu | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_resource.cu b/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_resource.cu index 2e1119ee481..0f33879ad93 100644 --- a/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_resource.cu +++ b/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_resource.cu @@ -177,6 +177,36 @@ TEMPLATE_TEST_CASE_METHOD(test_fixture, "any_resource", "[container][resource]", // Reset the counters: this->counts = Counts(); + SECTION("conversion to resource_ref") + { + Counts expected{}; + { + cuda::stream stream{cuda::device_ref{0}}; + cuda::mr::any_resource<::cuda::mr::host_accessible> mr{TestResource{42, this}}; + expected.new_count += is_big; + ++expected.object_count; + ++expected.move_count; + CHECK(this->counts == expected); + + cuda::mr::resource_ref<::cuda::mr::host_accessible> ref = mr; + + CHECK(this->counts == expected); + auto* ptr = ref.allocate(::cuda::stream_ref{stream}, this->bytes(100), this->align(8)); + CHECK(ptr == this); + ++expected.allocate_async_count; + CHECK(this->counts == expected); + ref.deallocate(::cuda::stream_ref{stream}, ptr, this->bytes(100), this->align(8)); + ++expected.deallocate_async_count; + CHECK(this->counts == expected); + } + expected.delete_count += is_big; + --expected.object_count; + CHECK(this->counts == expected); + } + + // Reset the counters: + this->counts = Counts(); + SECTION("conversion to any_synchronous_resource") { Counts expected{}; From 50047a38672fe1d5b65e3229a0c53af6214d3954 Mon Sep 17 00:00:00 2001 From: Piotr Ciolkosz Date: Fri, 1 May 2026 10:49:33 -0700 Subject: [PATCH 5/5] Supress clang-tidy --- .../cuda/memory_resource/any_resource/any_resource.cu | 2 +- .../memory_resource/any_resource/any_synchronous_resource.cu | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_resource.cu b/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_resource.cu index 0f33879ad93..6b62a353ddb 100644 --- a/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_resource.cu +++ b/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_resource.cu @@ -339,7 +339,7 @@ TEMPLATE_TEST_CASE_METHOD( CHECK(ref.allocate_sync(this->bytes(100), this->align(8)) == this); CHECK(get_property(ref, get_data{}) == 42); - ref = std::move(ref2); // move assignment + ref = std::move(ref2); // NOLINT(performance-move-const-arg) - test move assignment works CHECK(ref.allocate_sync(this->bytes(100), this->align(8)) == this); CHECK(get_property(ref, get_data{}) == 43); diff --git a/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_synchronous_resource.cu b/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_synchronous_resource.cu index a24ec284701..f50dc0247f4 100644 --- a/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_synchronous_resource.cu +++ b/libcudacxx/test/libcudacxx/cuda/memory_resource/any_resource/any_synchronous_resource.cu @@ -367,7 +367,7 @@ TEMPLATE_TEST_CASE_METHOD( CHECK(ref.allocate_sync(this->bytes(100), this->align(8)) == this); CHECK(get_property(ref, get_data{}) == 42); - ref = std::move(ref2); // move assignment + ref = std::move(ref2); // NOLINT(performance-move-const-arg) - test move assignment works CHECK(ref.allocate_sync(this->bytes(100), this->align(8)) == this); CHECK(get_property(ref, get_data{}) == 43); }