/* * Copyright 2008-2013 NVIDIA Corporation * Modifications Copyright© 2019-2025 Advanced Micro Devices, Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include #include #include "test_param_fixtures.hpp" #include "test_real_assertions.hpp" #include "test_utils.hpp" TESTS_DEFINE(CopyNTests, FullTestsParams); TESTS_DEFINE(CopyNPrimitiveTests, NumericalTestsParams); TYPED_TEST(CopyNPrimitiveTests, TestCopyNFromConstIterator) { using T = typename TestFixture::input_type; SCOPED_TRACE(testing::Message() << "with device_id= " << test::set_device_from_ctest()); std::vector v{0, 1, 2, 3, 4}; typename std::vector::const_iterator begin = v.begin(); // copy to host_vector thrust::host_vector h(5, (T) 10); typename thrust::host_vector::iterator h_result = thrust::copy_n(begin, h.size(), h.begin()); ASSERT_EQ_QUIET(h_result, h.end()); // copy to device_vector thrust::device_vector d(5, (T) 10); typename thrust::device_vector::iterator d_result = thrust::copy_n(begin, d.size(), d.begin()); thrust::device_vector dref{0, 1, 2, 3, 4}; ASSERT_EQ(d, dref); ASSERT_EQ_QUIET(d_result, d.end()); } TYPED_TEST(CopyNPrimitiveTests, TestCopyNToDiscardIterator) { using T = typename TestFixture::input_type; SCOPED_TRACE(testing::Message() << "with device_id= " << test::set_device_from_ctest()); thrust::host_vector h_input(5, 1); thrust::device_vector d_input = h_input; // copy from host_vector thrust::discard_iterator<> h_result = thrust::copy_n(h_input.begin(), h_input.size(), thrust::make_discard_iterator()); // copy from device_vector thrust::discard_iterator<> d_result = thrust::copy_n(d_input.begin(), d_input.size(), thrust::make_discard_iterator()); thrust::discard_iterator<> reference(5); ASSERT_EQ_QUIET(reference, h_result); ASSERT_EQ_QUIET(reference, d_result); } TYPED_TEST(CopyNTests, TestCopyNMatchingTypes) { using Vector = typename TestFixture::input_type; using T = typename Vector::value_type; SCOPED_TRACE(testing::Message() << "with device_id= " << test::set_device_from_ctest()); Vector v{0, 1, 2, 3, 4}; // copy to host_vector thrust::host_vector h(5, (T) 10); typename thrust::host_vector::iterator h_result = thrust::copy_n(v.begin(), v.size(), h.begin()); thrust::host_vector href{0, 1, 2, 3, 4}; ASSERT_EQ(h, href); ASSERT_EQ_QUIET(h_result, h.end()); // copy to device_vector thrust::device_vector d(5, (T) 10); typename thrust::device_vector::iterator d_result = thrust::copy_n(v.begin(), v.size(), d.begin()); thrust::device_vector dref{0, 1, 2, 3, 4}; ASSERT_EQ(d, dref); ASSERT_EQ_QUIET(d_result, d.end()); } THRUST_DIAG_PUSH THRUST_DIAG_SUPPRESS_MSVC(4244) // '=': conversion from 'int' to '_Ty', possible loss of data TYPED_TEST(CopyNTests, TestCopyNMixedTypes) { using Vector = typename TestFixture::input_type; SCOPED_TRACE(testing::Message() << "with device_id= " << test::set_device_from_ctest()); Vector v{0, 1, 2, 3, 4}; // copy to host_vector with different type thrust::host_vector h(5, (float) 10); typename thrust::host_vector::iterator h_result = thrust::copy_n(v.begin(), v.size(), h.begin()); thrust::host_vector href{0, 1, 2, 3, 4}; ASSERT_EQ(h, href); ASSERT_EQ_QUIET(h_result, h.end()); // copy to device_vector with different type thrust::device_vector d(5, (float) 10); typename thrust::device_vector::iterator d_result = thrust::copy_n(v.begin(), v.size(), d.begin()); thrust::device_vector dref{0, 1, 2, 3, 4}; ASSERT_EQ(d, dref); ASSERT_EQ_QUIET(d_result, d.end()); } THRUST_DIAG_POP TEST(CopyNTests, TestCopyNVectorBool) { SCOPED_TRACE(testing::Message() << "with device_id= " << test::set_device_from_ctest()); std::vector v{true, false, true}; thrust::host_vector h(3); thrust::device_vector d(3); thrust::copy_n(v.begin(), v.size(), h.begin()); thrust::copy_n(v.begin(), v.size(), d.begin()); thrust::host_vector href{true, false, true}; ASSERT_EQ(h, href); thrust::device_vector dref{true, false, true}; ASSERT_EQ(d, dref); ASSERT_EQ(d, dref); } TYPED_TEST(CopyNTests, TestCopyNListTo) { using Vector = typename TestFixture::input_type; using T = typename Vector::value_type; SCOPED_TRACE(testing::Message() << "with device_id= " << test::set_device_from_ctest()); // copy from list to Vector std::list l{0, 1, 2, 3, 4}; Vector v(l.size()); typename Vector::iterator v_result = thrust::copy_n(l.begin(), l.size(), v.begin()); Vector ref{0, 1, 2, 3, 4}; ASSERT_EQ(v, ref); ASSERT_EQ_QUIET(v_result, v.end()); l.clear(); thrust::copy_n(v.begin(), v.size(), std::back_insert_iterator>(l)); ASSERT_EQ(l.size(), 5lu); typename std::list::const_iterator iter = l.begin(); ASSERT_EQ(*iter, T(0)); iter++; ASSERT_EQ(*iter, T(1)); iter++; ASSERT_EQ(*iter, T(2)); iter++; ASSERT_EQ(*iter, T(3)); iter++; ASSERT_EQ(*iter, T(4)); iter++; } TYPED_TEST(CopyNTests, TestCopyNCountingIterator) { using Vector = typename TestFixture::input_type; using T = typename Vector::value_type; SCOPED_TRACE(testing::Message() << "with device_id= " << test::set_device_from_ctest()); thrust::counting_iterator iter(1); Vector vec(4); thrust::copy_n(iter, 4, vec.begin()); Vector ref{1, 2, 3, 4}; ASSERT_EQ(vec, ref); } TYPED_TEST(CopyNTests, TestCopyNZipIterator) { using Vector = typename TestFixture::input_type; using T = typename Vector::value_type; SCOPED_TRACE(testing::Message() << "with device_id= " << test::set_device_from_ctest()); Vector v1{1, 2, 3, 4}; Vector v2{4, 5, 6, 7}; Vector v3(4, T(0)); Vector v4(4, T(0)); thrust::copy_n(thrust::make_zip_iterator(thrust::make_tuple(v1.begin(), v2.begin())), 4, thrust::make_zip_iterator(thrust::make_tuple(v3.begin(), v4.begin()))); ASSERT_EQ(v1, v3); ASSERT_EQ(v2, v4); } TYPED_TEST(CopyNTests, TestCopyNConstantIteratorToZipIterator) { using Vector = typename TestFixture::input_type; using T = typename Vector::value_type; SCOPED_TRACE(testing::Message() << "with device_id= " << test::set_device_from_ctest()); Vector v1(4, T(0)); Vector v2(4, T(0)); thrust::copy_n(thrust::make_constant_iterator(thrust::tuple(4, 7)), v1.size(), thrust::make_zip_iterator(thrust::make_tuple(v1.begin(), v2.begin()))); Vector ref1(4, 4); Vector ref2(4, 7); ASSERT_EQ(v1, ref1); ASSERT_EQ(v2, ref2); } template OutputIterator copy_n(my_system& system, InputIterator, Size, OutputIterator result) { system.validate_dispatch(); return result; } TEST(CopyNTests, TestCopyNDispatchExplicit) { SCOPED_TRACE(testing::Message() << "with device_id= " << test::set_device_from_ctest()); thrust::device_vector vec(1); my_system sys(0); thrust::copy_n(sys, vec.begin(), 1, vec.begin()); ASSERT_EQ(true, sys.is_valid()); } template OutputIterator copy_n(my_tag, InputIterator, Size, OutputIterator result) { *result = 13; return result; } TEST(CopyNTests, TestCopyNDispatchImplicit) { SCOPED_TRACE(testing::Message() << "with device_id= " << test::set_device_from_ctest()); thrust::device_vector vec(1); thrust::copy_n(thrust::retag(vec.begin()), 1, thrust::retag(vec.begin())); ASSERT_EQ(13, vec.front()); }