// This file is part of Eigen, a lightweight C++ template library // for linear algebra. // // Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.com> // // 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/.
EIGEN_DEVICE_FUNC const Dimensions& dimensions() const
{ // The dimensions of the lhs and the rhs tensors should be equal to prevent // overflows and ensure the result is fully initialized. // TODO: use left impl instead if right impl dimensions are known at compile time. return m_rightImpl.dimensions();
}
EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(EvaluatorPointerType) {
eigen_assert(dimensions_match(m_leftImpl.dimensions(), m_rightImpl.dimensions()));
m_leftImpl.evalSubExprsIfNeeded(NULL); // If the lhs provides raw access to its storage area (i.e. if m_leftImpl.data() returns a non // null value), attempt to evaluate the rhs expression in place. Returns true iff in place // evaluation isn't supported and the caller still needs to manually assign the values generated // by the rhs to the lhs. return m_rightImpl.evalSubExprsIfNeeded(m_leftImpl.data());
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorOpCost
costPerCoeff(bool vectorized) const { // We assume that evalPacket or evalScalar is called to perform the // assignment and account for the cost of the write here, but reduce left // cost by one load because we are using m_leftImpl.coeffRef.
TensorOpCost left = m_leftImpl.costPerCoeff(vectorized); return m_rightImpl.costPerCoeff(vectorized) +
TensorOpCost(
numext::maxi(0.0, left.bytes_loaded() - sizeof(CoeffReturnType)),
left.bytes_stored(), left.compute_cycles()) +
TensorOpCost(0, sizeof(CoeffReturnType), 0, vectorized, PacketSize);
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalBlock(
TensorBlockDesc& desc, TensorBlockScratch& scratch) { if (TensorEvaluator<LeftArgType, Device>::RawAccess &&
m_leftImpl.data() != NULL) { // If destination has raw data access, we pass it as a potential // destination for a block descriptor evaluation.
desc.template AddDestinationBuffer<Layout>( /*dst_base=*/m_leftImpl.data() + desc.offset(), /*dst_strides=*/internal::strides<Layout>(m_leftImpl.dimensions()));
}
RightTensorBlock block = m_rightImpl.block(desc, scratch, /*root_of_expr_ast=*/true); // If block was evaluated into a destination, there is no need to do assignment. if (block.kind() != internal::TensorBlockKind::kMaterializedInOutput) {
m_leftImpl.writeBlock(desc, block);
}
block.cleanup();
}
#ifdef EIGEN_USE_SYCL // binding placeholder accessors to a command group handler for SYCL
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void bind(cl::sycl::handler &cgh) const {
m_leftImpl.bind(cgh);
m_rightImpl.bind(cgh);
} #endif
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.