/* * ****************************************************************************** * * * * * * This program and the accompanying materials are made available under the * * terms of the Apache License, Version 2.0 which is available at * * https://www.apache.org/licenses/LICENSE-2.0. * * * * See the NOTICE file distributed with this work for additional * * information regarding copyright ownership. * * 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. * * * * SPDX-License-Identifier: Apache-2.0 * ***************************************************************************** */ template SD_LIB_HIDDEN void NDArray::applyTriplewiseLambda(NDArray* second, NDArray* third, std::function& func, NDArray* target) { if (dataType() != DataTypeUtils::fromT()) THROW_EXCEPTION( "NDArray::applyTriplewiseLambda method: wrong template parameter T, its type should be the same as type of " "this array!"); if (dataType() != second->dataType() || dataType() != third->dataType() || dataType() != target->dataType()) THROW_EXCEPTION( "NDArray::applyTriplewiseLambda method: bother four arrays (this, second, third, target) should have the " "same type !"); if (this->lengthOf() != second->lengthOf() || this->lengthOf() != third->lengthOf() || !this->isSameShape(second) || !this->isSameShape(third)) { std::string errorMessage; errorMessage += "applyTriplewiseLambda requires all operands to have the same shape\n"; errorMessage += "this shape: " + ShapeUtils::shapeAsString(this->shapeInfo()) + "\n"; errorMessage += "second shape: " + ShapeUtils::shapeAsString(second->shapeInfo()) + "\n"; errorMessage += "third shape: " + ShapeUtils::shapeAsString(third->shapeInfo()) + "\n"; errorMessage += "target shape: " + ShapeUtils::shapeAsString(target->shapeInfo()) + "\n"; THROW_EXCEPTION(errorMessage.c_str()); } auto f = this->bufferAsT(); auto s = second->bufferAsT(); auto t = third->bufferAsT(); auto z = target->bufferAsT(); if (f == z) { auto loop = PRAGMA_THREADS_FOR { for (auto e = start; e < stop; e++) { auto tOffset = this->getOffset(e); auto uOffset = second->getOffset(e); auto vOffset = third->getOffset(e); f[tOffset] = func(f[tOffset], s[uOffset], t[vOffset]); } }; samediff::Threads::parallel_for(loop, 0, _length); } else { auto loop = PRAGMA_THREADS_FOR { for (auto e = start; e < stop; e++) { auto tOffset = this->getOffset(e); auto uOffset = second->getOffset(e); auto vOffset = third->getOffset(e); auto zOffset = target->getOffset(e); z[zOffset] = func(f[tOffset], s[uOffset], t[vOffset]); } }; samediff::Threads::parallel_for(loop, 0, _length); } } #if defined(HAS_DOUBLE) template SD_LIB_HIDDEN void NDArray::applyTriplewiseLambda(NDArray* second, NDArray* third, std::function& func, NDArray* target); #endif #if defined(HAS_FLOAT32) template SD_LIB_HIDDEN void NDArray::applyTriplewiseLambda(NDArray* second, NDArray* third, std::function& func, NDArray* target); #endif #if defined(HAS_FLOAT16) template SD_LIB_HIDDEN void NDArray::applyTriplewiseLambda( NDArray* second, NDArray* third, std::function& func, NDArray* target); #endif #if defined(HAS_BFLOAT16) template SD_LIB_HIDDEN void NDArray::applyTriplewiseLambda( NDArray* second, NDArray* third, std::function& func, NDArray* target); #endif #if defined(HAS_INT64) template SD_LIB_HIDDEN void NDArray::applyTriplewiseLambda( NDArray* second, NDArray* third, std::function& func, NDArray* target); template SD_LIB_HIDDEN void NDArray::applyTriplewiseLambda( NDArray* second, NDArray* third, std::function& func, NDArray* target); #endif #if defined(HAS_INT32) template SD_LIB_HIDDEN void NDArray::applyTriplewiseLambda(NDArray* second, NDArray* third, std::function& func, NDArray* target); #endif #if defined(HAS_INT16) template SD_LIB_HIDDEN void NDArray::applyTriplewiseLambda( NDArray* second, NDArray* third, std::function& func, NDArray* target); #endif #if defined(HAS_INT8) template SD_LIB_HIDDEN void NDArray::applyTriplewiseLambda( NDArray* second, NDArray* third, std::function& func, NDArray* target); template SD_LIB_HIDDEN void NDArray::applyTriplewiseLambda( NDArray* second, NDArray* third, std::function& func, NDArray* target); #endif #if defined(HAS_UINT8) template SD_LIB_HIDDEN void NDArray::applyTriplewiseLambda( NDArray* second, NDArray* third, std::function& func, NDArray* target); #endif #if defined(HAS_UINT16) template SD_LIB_HIDDEN void NDArray::applyTriplewiseLambda( NDArray* second, NDArray* third, std::function& func, NDArray* target); #endif #if defined(HAS_UINT32) template SD_LIB_HIDDEN void NDArray::applyTriplewiseLambda( NDArray* second, NDArray* third, std::function& func, NDArray* target); #endif #if defined(HAS_UINT64) template SD_LIB_HIDDEN void NDArray::applyTriplewiseLambda( NDArray* second, NDArray* third, std::function& func, NDArray* target); #endif ////////////////////////////////////////////////////////////////////////// template SD_LIB_HIDDEN void NDArray::applyPairwiseLambda(NDArray* other, std::function& func, NDArray* target) { if (dataType() != DataTypeUtils::fromT()) THROW_EXCEPTION( "NDArray::applyPairwiseLambda method: wrong template parameter T, its type should be the same as type of " "this array!"); if (dataType() != other->dataType() || dataType() != target->dataType()) THROW_EXCEPTION( "NDArray::applyPairwiseLambda method: all three arrays (this, other, target) must have the same type !"); // scalar is broadcastable if (this->lengthOf() != other->lengthOf() && !this->isScalar() && !other->isScalar()) { THROW_EXCEPTION("applyPairwiseLambda requires both operands to have the same shape"); } auto f = this->bufferAsT(); auto s = other->bufferAsT(); auto z = target->bufferAsT(); auto isTargetOrderEws = !isView() && !target->isView() && this->ordering() == target->ordering() && (this->ews() == 1 && target->ews() == 1); if (other->isScalar()) { auto otherVal = s[other->getOffset(0)]; if (isTargetOrderEws) { auto loop = PRAGMA_THREADS_FOR { for (auto e = start; e < stop; e++) z[e] = func(f[e], otherVal); }; samediff::Threads::parallel_for(loop, 0, _length); } else { if (f == z) { auto loop = PRAGMA_THREADS_FOR { for (auto e = start; e < stop; e++) { auto xOffset = this->getOffset(e); f[xOffset] = func(f[xOffset], otherVal); } }; samediff::Threads::parallel_for(loop, 0, _length); } else { auto loop = PRAGMA_THREADS_FOR { for (auto e = start; e < stop; e++) { auto xOffset = this->getOffset(e); auto zOffset = target->getOffset(e); z[zOffset] = func(f[xOffset], otherVal); } }; samediff::Threads::parallel_for(loop, 0, _length); } } } if (f == z && !this->isView() && !other->isView() && this->ordering() == other->ordering()) { auto loop = PRAGMA_THREADS_FOR { for (auto e = start; e < stop; e++) { auto xOffset = this->getOffset(e); auto yOffset = other->getOffset(e); f[xOffset] = func(f[xOffset], s[yOffset]); } }; samediff::Threads::parallel_for(loop, 0, _length); } else { auto loop = PRAGMA_THREADS_FOR { for (auto e = start; e < stop; e++) { auto xOffset = this->getOffset(e); auto yOffset = other->getOffset(e); auto zOffset = target->getOffset(e); z[zOffset] = func(f[xOffset], s[yOffset]); } }; samediff::Threads::parallel_for(loop, 0, _length); } } #if defined(HAS_DOUBLE) template SD_LIB_HIDDEN void NDArray::applyPairwiseLambda(NDArray* other, std::function& func, NDArray* target); #endif #if defined(HAS_FLOAT32) template SD_LIB_HIDDEN void NDArray::applyPairwiseLambda(NDArray* other, std::function& func, NDArray* target); #endif #if defined(HAS_FLOAT16) template SD_LIB_HIDDEN void NDArray::applyPairwiseLambda(NDArray* other, std::function& func, NDArray* target); #endif #if defined(HAS_BFLOAT16) template SD_LIB_HIDDEN void NDArray::applyPairwiseLambda(NDArray* other, std::function& func, NDArray* target); #endif #if defined(HAS_INT64) template SD_LIB_HIDDEN void NDArray::applyPairwiseLambda( NDArray* other, std::function& func, NDArray* target); template SD_LIB_HIDDEN void NDArray::applyPairwiseLambda( NDArray* other, std::function& func, NDArray* target); #endif #if defined(HAS_INT32) template SD_LIB_HIDDEN void NDArray::applyPairwiseLambda(NDArray* other, std::function& func, NDArray* target); #endif #if defined(HAS_INT16) template SD_LIB_HIDDEN void NDArray::applyPairwiseLambda(NDArray* other, std::function& func, NDArray* target); #endif #if defined(HAS_UINT8) template SD_LIB_HIDDEN void NDArray::applyPairwiseLambda(NDArray* other, std::function& func, NDArray* target); #endif #if defined(HAS_UINT16) template SD_LIB_HIDDEN void NDArray::applyPairwiseLambda(NDArray* other, std::function& func, NDArray* target); #endif #if defined(HAS_UINT32) template SD_LIB_HIDDEN void NDArray::applyPairwiseLambda(NDArray* other, std::function& func, NDArray* target); #endif #if defined(HAS_UNSIGNEDLONG) template SD_LIB_HIDDEN void NDArray::applyPairwiseLambda(NDArray* other, std::function& func, NDArray* target); #endif #if defined(HAS_INT8) template SD_LIB_HIDDEN void NDArray::applyPairwiseLambda(NDArray* other, std::function& func, NDArray* target); template SD_LIB_HIDDEN void NDArray::applyPairwiseLambda(NDArray* other, std::function& func, NDArray* target); template SD_LIB_HIDDEN void NDArray::applyPairwiseLambda(NDArray* other, std::function& func, NDArray* target); #endif #if defined(HAS_BOOL) template SD_LIB_HIDDEN void NDArray::applyPairwiseLambda(NDArray* other, std::function& func, NDArray* target); #endif ////////////////////////////////////////////////////////////////////////// template SD_LIB_HIDDEN void NDArray::applyLambda(std::function& func, NDArray* target) { if (dataType() != DataTypeUtils::fromT()) THROW_EXCEPTION( "NDArray::applyLambda method: wrong template parameter T, its type should be the same as type of this " "array!"); if (dataType() != target->dataType()) THROW_EXCEPTION("NDArray::applyLambda method: types of this and target array should match !"); auto f = this->bufferAsT(); auto z = target->bufferAsT(); if (f == z) { auto loop = PRAGMA_THREADS_FOR { for (auto e = start; e < stop; e+= increment) { auto xOffset = this->getOffset(e); f[xOffset] = func(f[xOffset]); } }; samediff::Threads::parallel_for(loop, 0, _length,1); } else { auto loop = PRAGMA_THREADS_FOR { for (auto e = start; e < stop; e+= increment) { auto xOffset = this->getOffset(e); auto zOffset = target->getOffset(e); z[zOffset] = func(f[xOffset]); } }; samediff::Threads::parallel_for(loop, 0, _length,1); } } #if defined(HAS_DOUBLE) template SD_LIB_HIDDEN void NDArray::applyLambda(std::function& func, NDArray* target); #endif #if defined(HAS_FLOAT32) template SD_LIB_HIDDEN void NDArray::applyLambda(std::function& func, NDArray* target); #endif #if defined(HAS_FLOAT16) template SD_LIB_HIDDEN void NDArray::applyLambda(std::function& func, NDArray* target); #endif #if defined(HAS_BFLOAT16) template SD_LIB_HIDDEN void NDArray::applyLambda(std::function& func, NDArray* target); #endif #if defined(HAS_INT64) template SD_LIB_HIDDEN void NDArray::applyLambda(std::function& func, NDArray* target); #endif #if defined(HAS_INT16) template SD_LIB_HIDDEN void NDArray::applyLambda(std::function& func, NDArray* target); #endif #if defined(HAS_INT32) template SD_LIB_HIDDEN void NDArray::applyLambda(std::function& func, NDArray* target); #endif #if defined(HAS_UINT8) template SD_LIB_HIDDEN void NDArray::applyLambda(std::function& func, NDArray* target); #endif #if defined(HAS_UINT16) template SD_LIB_HIDDEN void NDArray::applyLambda(std::function& func, NDArray* target); #endif #if defined(HAS_UINT32) template SD_LIB_HIDDEN void NDArray::applyLambda(std::function& func, NDArray* target); #endif #if defined(HAS_UNSIGNEDLONG) template SD_LIB_HIDDEN void NDArray::applyLambda(std::function& func, NDArray* target); #endif #if defined(HAS_INT8) template SD_LIB_HIDDEN void NDArray::applyLambda(std::function& func, NDArray* target); #endif #if defined(HAS_BOOL) template SD_LIB_HIDDEN void NDArray::applyLambda(std::function& func, NDArray* target); #endif ////////////////////////////////////////////////////////////////////////// template SD_LIB_HIDDEN void NDArray::applyIndexedLambda(std::function& func, NDArray* target) { if (dataType() != DataTypeUtils::fromT()) THROW_EXCEPTION( "NDArray::applyIndexedLambda method: wrong template parameter T, its type should be the same as type of " "this array!"); if (dataType() != target->dataType()) THROW_EXCEPTION("NDArray::applyIndexedLambda method: types of this and target array should match !"); auto f = this->bufferAsT(); auto z = target->bufferAsT(); if (this->ordering() == target->ordering() && (this->ews() == 1 && target->ews() == 1)) { auto loop = PRAGMA_THREADS_FOR { for (auto e = start; e < stop; e++) z[e] = func(e, f[e]); }; samediff::Threads::parallel_for(loop, 0, _length); } else { if (f == z) { auto loop = PRAGMA_THREADS_FOR { for (auto e = start; e < stop; e++) { auto xOffset = this->getOffset(e); f[xOffset] = func(e, f[xOffset]); } }; samediff::Threads::parallel_for(loop, 0, _length); } else { auto loop = PRAGMA_THREADS_FOR { for (auto e = start; e < stop; e++) { auto xOffset = this->getOffset(e); auto zOffset = target->getOffset(e); z[zOffset] = func(e, f[xOffset]); } }; samediff::Threads::parallel_for(loop, 0, _length); } } } #if defined(HAS_DOUBLE) template SD_LIB_HIDDEN void NDArray::applyIndexedLambda(std::function& func, NDArray* target); #endif #if defined(HAS_FLOAT32) template SD_LIB_HIDDEN void NDArray::applyIndexedLambda(std::function& func, NDArray* target); #endif #if defined(HAS_FLOAT16) template SD_LIB_HIDDEN void NDArray::applyIndexedLambda(std::function& func, NDArray* target); #endif #if defined(HAS_BFLOAT16) template SD_LIB_HIDDEN void NDArray::applyIndexedLambda(std::function& func, NDArray* target); #endif #if defined(HAS_INT64) template SD_LIB_HIDDEN void NDArray::applyIndexedLambda( std::function& func, NDArray* target); #endif #if defined(HAS_INT32) template SD_LIB_HIDDEN void NDArray::applyIndexedLambda(std::function& func, NDArray* target); #endif #if defined(HAS_INT16) template SD_LIB_HIDDEN void NDArray::applyIndexedLambda(std::function& func, NDArray* target); #endif #if defined(HAS_UINT8) template SD_LIB_HIDDEN void NDArray::applyIndexedLambda(std::function& func, NDArray* target); #endif #if defined(HAS_UINT16) template SD_LIB_HIDDEN void NDArray::applyIndexedLambda(std::function& func, NDArray* target); #endif #if defined(HAS_UINT32) template SD_LIB_HIDDEN void NDArray::applyIndexedLambda(std::function& func, NDArray* target); #endif #if defined(HAS_UNSIGNEDLONG) template SD_LIB_HIDDEN void NDArray::applyIndexedLambda(std::function& func, NDArray* target); #endif #if defined(HAS_INT8) template SD_LIB_HIDDEN void NDArray::applyIndexedLambda(std::function& func, NDArray* target); #endif #if defined(HAS_BOOL) template SD_LIB_HIDDEN void NDArray::applyIndexedLambda(std::function& func, NDArray* target); #endif ////////////////////////////////////////////////////////////////////////// template SD_LIB_HIDDEN void NDArray::applyIndexedPairwiseLambda(NDArray* other, std::function& func, NDArray* target) { if (dataType() != DataTypeUtils::fromT()) THROW_EXCEPTION( "NDArray::applyIndexedPairwiseLambda method: wrong template parameter T, its type should be the same as " "type of this array!"); if (dataType() != target->dataType()) THROW_EXCEPTION( "NDArray::applyIndexedPairwiseLambda method: types of this and target array should match !"); if (this->lengthOf() != other->lengthOf()) { sd_printf("applyIndexedPairwiseLambda requires both operands to have the same shape\n", ""); THROW_EXCEPTION("Shapes mismatch"); } auto f = this->bufferAsT(); auto s = other->bufferAsT(); auto z = target->bufferAsT(); if (f == z) { auto loop = PRAGMA_THREADS_FOR { for (auto e = start; e < stop; e++) { auto xOffset = this->getOffset(e); auto yOffset = other->getOffset(e); f[xOffset] = func((sd::LongType)e, f[xOffset], s[yOffset]); } }; samediff::Threads::parallel_for(loop, 0, _length); } else { auto loop = PRAGMA_THREADS_FOR { for (auto e = start; e < stop; e++) { auto xOffset = this->getOffset(e); auto yOffset = other->getOffset(e); auto zOffset = target->getOffset(e); z[zOffset] = func((sd::LongType)e, f[xOffset], s[yOffset]); } }; samediff::Threads::parallel_for(loop, 0, _length); } } #if defined(HAS_DOUBLE) template SD_LIB_HIDDEN void NDArray::applyIndexedPairwiseLambda( NDArray* other, std::function& func, NDArray* target); #endif #if defined(HAS_FLOAT32) template SD_LIB_HIDDEN void NDArray::applyIndexedPairwiseLambda( NDArray* other, std::function& func, NDArray* target); #endif #if defined(HAS_FLOAT16) template SD_LIB_HIDDEN void NDArray::applyIndexedPairwiseLambda( NDArray* other, std::function& func, NDArray* target); #endif #if defined(HAS_BFLOAT16) template SD_LIB_HIDDEN void NDArray::applyIndexedPairwiseLambda( NDArray* other, std::function& func, NDArray* target); #endif #if defined(HAS_INT64) template SD_LIB_HIDDEN void NDArray::applyIndexedPairwiseLambda( NDArray* other, std::function& func, NDArray* target); #endif #if defined(HAS_INT32) template SD_LIB_HIDDEN void NDArray::applyIndexedPairwiseLambda(NDArray* other, std::function& func, NDArray* target); #endif #if defined(HAS_INT16) template SD_LIB_HIDDEN void NDArray::applyIndexedPairwiseLambda( NDArray* other, std::function& func, NDArray* target); #endif #if defined(HAS_UINT8) template SD_LIB_HIDDEN void NDArray::applyIndexedPairwiseLambda( NDArray* other, std::function& func, NDArray* target); #endif #if defined(HAS_UINT16) template SD_LIB_HIDDEN void NDArray::applyIndexedPairwiseLambda( NDArray* other, std::function& func, NDArray* target); #endif #if defined(HAS_UINT32) template SD_LIB_HIDDEN void NDArray::applyIndexedPairwiseLambda( NDArray* other, std::function& func, NDArray* target); #endif #if defined(HAS_UNSIGNEDLONG) template SD_LIB_HIDDEN void NDArray::applyIndexedPairwiseLambda( NDArray* other, std::function& func, NDArray* target); #endif #if defined(HAS_INT8) template SD_LIB_HIDDEN void NDArray::applyIndexedPairwiseLambda( NDArray* other, std::function& func, NDArray* target); #endif #if defined(HAS_BOOL) template SD_LIB_HIDDEN void NDArray::applyIndexedPairwiseLambda( NDArray* other, std::function& func, NDArray* target); #endif