/* * Copyright 2018 NVIDIA Corporation * * 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. */ #pragma once #include #include #if THRUST_CPP_DIALECT >= 2011 #include #include #include #include THRUST_NAMESPACE_BEGIN namespace detail { struct capture_as_dependency_fn { template auto operator()(Dependency&& dependency) const THRUST_DECLTYPE_RETURNS(capture_as_dependency(THRUST_FWD(dependency))) }; // Default implementation: universal forwarding. template auto capture_as_dependency(Dependency&& dependency) THRUST_DECLTYPE_RETURNS(THRUST_FWD(dependency)) template auto capture_as_dependency(std::tuple& dependencies) THRUST_DECLTYPE_RETURNS( tuple_for_each(THRUST_FWD(dependencies), capture_as_dependency_fn{}) ) template class BaseSystem, typename... Dependencies> struct execute_with_dependencies : BaseSystem> { private: using super_t = BaseSystem>; std::tuple...> dependencies; public: __host__ execute_with_dependencies(super_t const &super, Dependencies && ...dependencies) : super_t(super), dependencies(std::forward(dependencies)...) { } template __host__ execute_with_dependencies(super_t const &super, UDependencies && ...deps) : super_t(super), dependencies(THRUST_FWD(deps)...) { } template __host__ execute_with_dependencies(UDependencies && ...deps) : dependencies(THRUST_FWD(deps)...) { } template __host__ execute_with_dependencies(super_t const &super, std::tuple&& deps) : super_t(super), dependencies(std::move(deps)) { } template __host__ execute_with_dependencies(std::tuple&& deps) : dependencies(std::move(deps)) { } std::tuple...> __host__ extract_dependencies() { return std::move(dependencies); } // Rebinding. template __host__ execute_with_dependencies rebind_after(UDependencies&& ...udependencies) const { return { capture_as_dependency(THRUST_FWD(udependencies))... }; } // Rebinding. template __host__ execute_with_dependencies rebind_after(std::tuple& udependencies) const { return { capture_as_dependency(udependencies) }; } template __host__ execute_with_dependencies rebind_after(std::tuple&& udependencies) const { return { capture_as_dependency(std::move(udependencies)) }; } }; template< typename Allocator, template class BaseSystem, typename... Dependencies > struct execute_with_allocator_and_dependencies : BaseSystem< execute_with_allocator_and_dependencies< Allocator, BaseSystem, Dependencies... > > { private: using super_t = BaseSystem< execute_with_allocator_and_dependencies< Allocator, BaseSystem, Dependencies... > >; std::tuple...> dependencies; Allocator alloc; public: template __host__ execute_with_allocator_and_dependencies(super_t const &super, Allocator a, UDependencies && ...deps) : super_t(super), dependencies(THRUST_FWD(deps)...), alloc(a) { } template __host__ execute_with_allocator_and_dependencies(Allocator a, UDependencies && ...deps) : dependencies(THRUST_FWD(deps)...), alloc(a) { } template __host__ execute_with_allocator_and_dependencies(super_t const &super, Allocator a, std::tuple&& deps) : super_t(super), dependencies(std::move(deps)), alloc(a) { } template __host__ execute_with_allocator_and_dependencies(Allocator a, std::tuple&& deps) : dependencies(std::move(deps)), alloc(a) { } std::tuple...> __host__ extract_dependencies() { return std::move(dependencies); } __host__ typename std::add_lvalue_reference::type get_allocator() { return alloc; } // Rebinding. template __host__ execute_with_allocator_and_dependencies rebind_after(UDependencies&& ...udependencies) const { return { alloc, capture_as_dependency(THRUST_FWD(udependencies))... }; } // Rebinding. template __host__ execute_with_allocator_and_dependencies rebind_after(std::tuple& udependencies) const { return { alloc, capture_as_dependency(udependencies) }; } template __host__ execute_with_allocator_and_dependencies rebind_after(std::tuple&& udependencies) const { return { alloc, capture_as_dependency(std::move(udependencies)) }; } }; template class BaseSystem, typename ...Dependencies> __host__ std::tuple...> extract_dependencies(thrust::detail::execute_with_dependencies&& system) { return std::move(system).extract_dependencies(); } template class BaseSystem, typename ...Dependencies> __host__ std::tuple...> extract_dependencies(thrust::detail::execute_with_dependencies& system) { return std::move(system).extract_dependencies(); } template class BaseSystem, typename ...Dependencies> __host__ std::tuple...> extract_dependencies(thrust::detail::execute_with_allocator_and_dependencies&& system) { return std::move(system).extract_dependencies(); } template class BaseSystem, typename ...Dependencies> __host__ std::tuple...> extract_dependencies(thrust::detail::execute_with_allocator_and_dependencies& system) { return std::move(system).extract_dependencies(); } template __host__ std::tuple<> extract_dependencies(System &&) { return std::tuple<>{}; } } // end detail THRUST_NAMESPACE_END #endif // THRUST_CPP_DIALECT >= 2011