From 5f6af0b76149011e490a0f420a8ecc5bf1e583e7 Mon Sep 17 00:00:00 2001 From: Joe Todd Date: Wed, 16 Oct 2024 11:07:27 +0100 Subject: [PATCH] [SYCL][COMPAT] Move clashing functions into anonymous namespace (#15446) Some `syclcompat::` functions clash with global namespace (C-style) functions because of Argument Dependent Lookup. These are: - `memcpy` - `memset` - `free` - `fill` To prevent ADL from finding these functions, they have been moved into an anonymous namespace. --- sycl/include/syclcompat/memory.hpp | 20 +++++++++++++++++ sycl/test/syclcompat/memory_adl.cpp | 34 +++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 sycl/test/syclcompat/memory_adl.cpp diff --git a/sycl/include/syclcompat/memory.hpp b/sycl/include/syclcompat/memory.hpp index eb92d9bec51c..ccd7cab5fe17 100644 --- a/sycl/include/syclcompat/memory.hpp +++ b/sycl/include/syclcompat/memory.hpp @@ -644,6 +644,9 @@ static inline void wait_and_free(void *ptr, } } +// Anonymous namespace to disable ADL for functions which might clash (memcpy, +// memset, free) +namespace { /// Free the memory \p ptr on the default queue without synchronizing /// \param ptr Point to free. /// \returns no return value. @@ -652,6 +655,7 @@ static inline void free(void *ptr, sycl::queue q = get_default_queue()) { sycl::free(ptr, q); } } +} // namespace /// Enqueues the release of all pointers in /p pointers on the /p q. /// The command waits on all passed /p events and returns an event that @@ -677,6 +681,7 @@ inline sycl::event enqueue_free(const std::vector &pointers, return event; } +namespace { /// Synchronously copies \p size bytes from the address specified by \p from_ptr /// to the address specified by \p to_ptr. The function will /// return after the copy is completed. @@ -691,6 +696,8 @@ static void memcpy(void *to_ptr, const void *from_ptr, size_t size, detail::memcpy(q, to_ptr, from_ptr, size).wait(); } +} // namespace + /// Asynchronously copies \p size bytes from the address specified by \p /// from_ptr to the address specified by \p to_ptr. The return of the function /// does NOT guarantee the copy is completed. @@ -723,6 +730,7 @@ memcpy_async(type_identity_t *to_ptr, const type_identity_t *from_ptr, static_cast(from_ptr), count * sizeof(T)); } +namespace { /// Synchronously copies \p count T's from the address specified by \p from_ptr /// to the address specified by \p to_ptr. The function will /// return after the copy is completed. @@ -763,6 +771,8 @@ static inline void memcpy(void *to_ptr, size_t to_pitch, const void *from_ptr, detail::memcpy(q, to_ptr, from_ptr, to_pitch, from_pitch, x, y)); } +} // namespace + /// Asynchronously copies 2D matrix specified by \p x and \p y from the address /// specified by \p from_ptr to the address specified by \p to_ptr, while \p /// \p from_pitch and \p to_pitch are the range of dim x in bytes of the matrix @@ -785,6 +795,7 @@ static inline sycl::event memcpy_async(void *to_ptr, size_t to_pitch, return detail::combine_events(events, q); } +namespace { /// Synchronously copies a subset of a 3D matrix specified by \p to to another /// 3D matrix specified by \p from. The from and to position info are specified /// by \p from_pos and \p to_pos The copied matrix size is specified by \p size. @@ -803,6 +814,7 @@ static inline void memcpy(pitched_data to, sycl::id<3> to_pos, sycl::queue q = get_default_queue()) { sycl::event::wait(detail::memcpy(q, to, to_pos, from, from_pos, size)); } +} // namespace /// Asynchronously copies a subset of a 3D matrix specified by \p to to another /// 3D matrix specified by \p from. The from and to position info are specified @@ -824,6 +836,7 @@ static inline sycl::event memcpy_async(pitched_data to, sycl::id<3> to_pos, return detail::combine_events(events, q); } +namespace { /// Synchronously sets \p pattern to the first \p count elements starting from /// \p dev_ptr. The function will return after the fill operation is completed. /// @@ -838,6 +851,7 @@ static void inline fill(void *dev_ptr, const T &pattern, size_t count, sycl::queue q = get_default_queue()) { detail::fill(q, dev_ptr, pattern, count).wait(); } +} // namespace /// Asynchronously sets \p pattern to the first \p count elements starting from /// \p dev_ptr. @@ -882,6 +896,7 @@ static inline void memcpy_async(const memcpy_parameter ¶m, } } // namespace experimental +namespace { /// Synchronously sets \p value to the first \p size bytes starting from \p /// dev_ptr. The function will return after the memset operation is completed. /// @@ -894,6 +909,7 @@ static void memset(void *dev_ptr, int value, size_t size, sycl::queue q = get_default_queue()) { detail::memset(q, dev_ptr, value, size).wait(); } +} // namespace /// \brief Sets 2 bytes data \p value to the first \p size elements starting /// from \p dev_ptr in \p q synchronously. @@ -954,6 +970,7 @@ memset_d32_async(void *dev_ptr, unsigned int value, size_t size, return detail::fill(q, dev_ptr, value, size); } +namespace { /// \brief Sets 1 byte data \p val to the pitched 2D memory region pointed by \p /// ptr in \p q synchronously. /// \param [in] ptr Pointer to the virtual device memory. @@ -966,6 +983,7 @@ static inline void memset(void *ptr, size_t pitch, int val, size_t x, size_t y, sycl::queue q = get_default_queue()) { sycl::event::wait(detail::memset(q, ptr, pitch, val, x, y)); } +} // namespace /// \brief Sets 2 bytes data \p val to the pitched 2D memory region pointed by /// ptr in \p q synchronously. @@ -1044,6 +1062,7 @@ memset_d32_async(void *ptr, size_t pitch, unsigned int val, size_t x, size_t y, return detail::combine_events(events, q); } +namespace { /// Sets \p value to the 3D memory region specified by \p pitch in \p q. \p size /// specify the setted 3D memory size. The function will return after the /// memset operation is completed. @@ -1057,6 +1076,7 @@ static inline void memset(pitched_data pitch, int val, sycl::range<3> size, sycl::queue q = get_default_queue()) { sycl::event::wait(detail::memset(q, pitch, val, size)); } +} // namespace /// Sets \p value to the 3D memory region specified by \p pitch in \p q. \p size /// specify the setted 3D memory size. The return of the function does NOT diff --git a/sycl/test/syclcompat/memory_adl.cpp b/sycl/test/syclcompat/memory_adl.cpp new file mode 100644 index 000000000000..ac6d812d19f3 --- /dev/null +++ b/sycl/test/syclcompat/memory_adl.cpp @@ -0,0 +1,34 @@ +/*************************************************************************** + * + * Copyright (C) Codeplay Software Ltd. + * + * Part of the LLVM Project, under the Apache License v2.0 with LLVM + * Exceptions. See https://llvm.org/LICENSE.txt for license information. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + * + * 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. + * + * SYCLcompat API + * + * memory_adl.cpp + * + * Description: + * Tests to ensure global namespace functions don't clash via ADL + **************************************************************************/ + +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -fsyntax-only +// Test that no syclcompat:: functions clash with global namespace fns due to ADL +#include +#include + +int main(){ + syclcompat::device_info dummy_info; + syclcompat::device_info dummy_info_2; + memset(&dummy_info, 0, sizeof(syclcompat::device_info)); + memcpy(&dummy_info, &dummy_info_2, sizeof(syclcompat::device_info)); + free(&dummy_info); +}