// This file is part of Eigen, a lightweight C++ template library // for linear algebra. // // Copyright (C) 2014 Benoit Steiner // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_CXX11_TENSOR_TENSOR_DEVICE_H #define EIGEN_CXX11_TENSOR_TENSOR_DEVICE_H namespace Eigen { /** \class TensorDevice * \ingroup CXX11_Tensor_Module * * \brief Pseudo expression providing an operator = that will evaluate its argument * on the specified computing 'device' (GPU, thread pool, ...) * * Example: * C.device(EIGEN_GPU) = A + B; * * Todo: operator *= and /=. */ template class TensorDevice { public: TensorDevice(const DeviceType& device, ExpressionType& expression) : m_device(device), m_expression(expression) {} EIGEN_DEFAULT_COPY_CONSTRUCTOR(TensorDevice) template EIGEN_STRONG_INLINE TensorDevice& operator=(const OtherDerived& other) { typedef TensorAssignOp Assign; Assign assign(m_expression, other); internal::TensorExecutor::run(assign, m_device); return *this; } template EIGEN_STRONG_INLINE TensorDevice& operator+=(const OtherDerived& other) { typedef typename OtherDerived::Scalar Scalar; typedef TensorCwiseBinaryOp, const ExpressionType, const OtherDerived> Sum; Sum sum(m_expression, other); typedef TensorAssignOp Assign; Assign assign(m_expression, sum); internal::TensorExecutor::run(assign, m_device); return *this; } template EIGEN_STRONG_INLINE TensorDevice& operator-=(const OtherDerived& other) { typedef typename OtherDerived::Scalar Scalar; typedef TensorCwiseBinaryOp, const ExpressionType, const OtherDerived> Difference; Difference difference(m_expression, other); typedef TensorAssignOp Assign; Assign assign(m_expression, difference); internal::TensorExecutor::run(assign, m_device); return *this; } protected: const DeviceType& m_device; ExpressionType& m_expression; }; /** \class TensorAsyncDevice * \ingroup CXX11_Tensor_Module * * \brief Pseudo expression providing an operator = that will evaluate its * argument asynchronously on the specified device. Currently only * ThreadPoolDevice implements proper asynchronous execution, while the default * and GPU devices just run the expression synchronously and call m_done() on * completion.. * * Example: * auto done = []() { ... expression evaluation done ... }; * C.device(thread_pool_device, std::move(done)) = A + B; */ template class TensorAsyncDevice { public: TensorAsyncDevice(const DeviceType& device, ExpressionType& expression, DoneCallback done) : m_device(device), m_expression(expression), m_done(std::move(done)) {} template EIGEN_STRONG_INLINE TensorAsyncDevice& operator=(const OtherDerived& other) { typedef TensorAssignOp Assign; typedef internal::TensorExecutor Executor; Assign assign(m_expression, other); Executor::run(assign, m_device); m_done(); return *this; } protected: const DeviceType& m_device; ExpressionType& m_expression; DoneCallback m_done; }; #ifdef EIGEN_USE_THREADS template class TensorAsyncDevice { public: TensorAsyncDevice(const ThreadPoolDevice& device, ExpressionType& expression, DoneCallback done) : m_device(device), m_expression(expression), m_done(std::move(done)) {} template EIGEN_STRONG_INLINE TensorAsyncDevice& operator=(const OtherDerived& other) { typedef TensorAssignOp Assign; typedef internal::TensorAsyncExecutor Executor; // WARNING: After assignment 'm_done' callback will be in undefined state. Assign assign(m_expression, other); Executor::runAsync(assign, m_device, std::move(m_done)); return *this; } protected: const ThreadPoolDevice& m_device; ExpressionType& m_expression; DoneCallback m_done; }; #endif } // end namespace Eigen #endif // EIGEN_CXX11_TENSOR_TENSOR_DEVICE_H