template void NDArray::applyTriplewiseLambda(NDArray& second, NDArray& third, const std::function& func, NDArray& target) { if(dataType() != DataTypeUtils::fromT()) throw std::runtime_error("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 std::runtime_error("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)) { nd4j_printf("applyPairwiseLambda requires both operands to have the same shape\n",""); throw std::runtime_error("Shapes mismach"); } auto f = this->bufferAsT(); auto s = second.bufferAsT(); auto t = third.bufferAsT(); auto z = target.bufferAsT(); if (this->ordering() == second.ordering() && this->ordering() == third.ordering() && this->ordering() == target.ordering() && (this->ews() == 1 && target.ews() == 1) && this->ews() == second.ews() && this->ews() == third.ews()) { auto loop = PRAGMA_THREADS_FOR { for (auto e = start; e < stop; e += increment) z[e] = func(f[e], s[e], t[e]); }; samediff::Threads::parallel_for(loop, 0, _length); } else { if (f == z) { auto loop = PRAGMA_THREADS_FOR { for (auto e = start; e < stop; e += increment) { 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 += increment) { 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); } } } template void NDArray::applyTriplewiseLambda(NDArray& second, NDArray &third, const std::function& func, NDArray& target); template void NDArray::applyTriplewiseLambda(NDArray& second, NDArray &third, const std::function& func, NDArray& target); template void NDArray::applyTriplewiseLambda(NDArray& second, NDArray &third, const std::function& func, NDArray& target); template void NDArray::applyTriplewiseLambda(NDArray& second, NDArray &third, const std::function& func, NDArray& target); template void NDArray::applyTriplewiseLambda(NDArray& second, NDArray &third, const std::function& func, NDArray& target); template void NDArray::applyTriplewiseLambda(NDArray& second, NDArray &third, const std::function& func, NDArray& target); template void NDArray::applyTriplewiseLambda(NDArray& second, NDArray &third, const std::function& func, NDArray& target); template void NDArray::applyTriplewiseLambda(NDArray& second, NDArray &third, const std::function& func, NDArray& target); template void NDArray::applyTriplewiseLambda(NDArray& second, NDArray &third, const std::function& func, NDArray& target); template void NDArray::applyTriplewiseLambda(NDArray& second, NDArray &third, const std::function& func, NDArray& target); template void NDArray::applyTriplewiseLambda(NDArray& second, NDArray &third, const std::function& func, NDArray& target); template void NDArray::applyTriplewiseLambda(NDArray& second, NDArray &third, const std::function& func, NDArray& target); template void NDArray::applyTriplewiseLambda(NDArray& second, NDArray &third, const std::function& func, NDArray& target); ////////////////////////////////////////////////////////////////////////// template void NDArray::applyPairwiseLambda(const NDArray& other, const std::function& func, NDArray& target) { if(dataType() != DataTypeUtils::fromT()) throw std::runtime_error("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 std::runtime_error("NDArray::applyPairwiseLambda method: all three arrays (this, other, target) must have the same type !"); if (this->lengthOf() != other.lengthOf()) { nd4j_printf("applyPairwiseLambda requires both operands to have the same shape\n",""); throw std::runtime_error("Shapes mismach"); } auto f = this->bufferAsT(); auto s = other.bufferAsT(); auto z = target.bufferAsT(); if (this->ordering() == other.ordering() && this->ordering() == target.ordering() && (this->ews() == 1 && target.ews() == 1) && this->ews() == other.ews()) { auto loop = PRAGMA_THREADS_FOR { for (auto e = start; e < stop; e += increment) z[e] = func(f[e], s[e]); }; samediff::Threads::parallel_for(loop, 0, _length); } else { if (f == z) { auto loop = PRAGMA_THREADS_FOR { for (auto e = start; e < stop; e += increment) { 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 += increment) { 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); } } } template void NDArray::applyPairwiseLambda(const NDArray& other, const std::function& func, NDArray& target); template void NDArray::applyPairwiseLambda(const NDArray& other, const std::function& func, NDArray& target); template void NDArray::applyPairwiseLambda(const NDArray& other, const std::function& func, NDArray& target); template void NDArray::applyPairwiseLambda(const NDArray& other, const std::function& func, NDArray& target); template void NDArray::applyPairwiseLambda(const NDArray& other, const std::function& func, NDArray& target); template void NDArray::applyPairwiseLambda(const NDArray& other, const std::function& func, NDArray& target); template void NDArray::applyPairwiseLambda(const NDArray& other, const std::function& func, NDArray& target); template void NDArray::applyPairwiseLambda(const NDArray& other, const std::function& func, NDArray& target); template void NDArray::applyPairwiseLambda(const NDArray& other, const std::function& func, NDArray& target); template void NDArray::applyPairwiseLambda(const NDArray& other, const std::function& func, NDArray& target); template void NDArray::applyPairwiseLambda(const NDArray& other, const std::function& func, NDArray& target); template void NDArray::applyPairwiseLambda(const NDArray& other, const std::function& func, NDArray& target); template void NDArray::applyPairwiseLambda(const NDArray& other, const std::function& func, NDArray& target); ////////////////////////////////////////////////////////////////////////// template void NDArray::applyLambda(const std::function& func, NDArray& target) { if(dataType() != DataTypeUtils::fromT()) throw std::runtime_error("NDArray::applyLambda method: wrong template parameter T, its type should be the same as type of this array!"); if(dataType() != target.dataType()) throw std::runtime_error("NDArray::applyLambda 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 += increment) z[e] = func(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 += increment) { auto xOffset = this->getOffset(e); f[xOffset] = func(f[xOffset]); } }; samediff::Threads::parallel_for(loop, 0, _length); } 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); } } } template void NDArray::applyLambda(const std::function& func, NDArray& target); template void NDArray::applyLambda(const std::function& func, NDArray& target); template void NDArray::applyLambda(const std::function& func, NDArray& target); template void NDArray::applyLambda(const std::function& func, NDArray& target); template void NDArray::applyLambda(const std::function& func, NDArray& target); template void NDArray::applyLambda(const std::function& func, NDArray& target); template void NDArray::applyLambda(const std::function& func, NDArray& target); template void NDArray::applyLambda(const std::function& func, NDArray& target); template void NDArray::applyLambda(const std::function& func, NDArray& target); template void NDArray::applyLambda(const std::function& func, NDArray& target); template void NDArray::applyLambda(const std::function& func, NDArray& target); template void NDArray::applyLambda(const std::function& func, NDArray& target); template void NDArray::applyLambda(const std::function& func, NDArray& target); ////////////////////////////////////////////////////////////////////////// template void NDArray::applyIndexedLambda(const std::function& func, NDArray& target) { if(dataType() != DataTypeUtils::fromT()) throw std::runtime_error("NDArray::applyIndexedLambda method: wrong template parameter T, its type should be the same as type of this array!"); if(dataType() != target.dataType()) throw std::runtime_error("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 += increment) 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 += increment) { 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 += increment) { auto xOffset = this->getOffset(e); auto zOffset = target.getOffset(e); z[zOffset] = func(e, f[xOffset]); } }; samediff::Threads::parallel_for(loop, 0, _length); } } } template void NDArray::applyIndexedLambda(const std::function& func, NDArray& target); template void NDArray::applyIndexedLambda(const std::function& func, NDArray& target); template void NDArray::applyIndexedLambda(const std::function& func, NDArray& target); template void NDArray::applyIndexedLambda(const std::function& func, NDArray& target); template void NDArray::applyIndexedLambda(const std::function& func, NDArray& target); template void NDArray::applyIndexedLambda(const std::function& func, NDArray& target); template void NDArray::applyIndexedLambda(const std::function& func, NDArray& target); template void NDArray::applyIndexedLambda(const std::function& func, NDArray& target); template void NDArray::applyIndexedLambda(const std::function& func, NDArray& target); template void NDArray::applyIndexedLambda(const std::function& func, NDArray& target); template void NDArray::applyIndexedLambda(const std::function& func, NDArray& target); template void NDArray::applyIndexedLambda(const std::function& func, NDArray& target); template void NDArray::applyIndexedLambda(const std::function& func, NDArray& target); ////////////////////////////////////////////////////////////////////////// template void NDArray::applyIndexedPairwiseLambda(NDArray& other, const std::function& func, NDArray& target) { if(dataType() != DataTypeUtils::fromT()) throw std::runtime_error("NDArray::applyIndexedPairwiseLambda method: wrong template parameter T, its type should be the same as type of this array!"); if(dataType() != target.dataType()) throw std::runtime_error("NDArray::applyIndexedPairwiseLambda method: types of this and target array should match !"); if (this->lengthOf() != other.lengthOf()) { nd4j_printf("applyIndexedPairwiseLambda requires both operands to have the same shape\n",""); throw std::runtime_error("Shapes mismach"); } auto f = this->bufferAsT(); auto s = other.bufferAsT(); auto z = target.bufferAsT(); if (this->ordering() == other.ordering() && this->ordering() == target.ordering() && (this->ews() == 1 && target.ews() == 1) && this->ews() == other.ews()) { auto loop = PRAGMA_THREADS_FOR { for (auto e = start; e < stop; e += increment) z[e] = func((Nd4jLong) e, f[e], s[e]); }; samediff::Threads::parallel_for(loop, 0, _length); } else { if (f == z) { auto loop = PRAGMA_THREADS_FOR { for (auto e = start; e < stop; e += increment) { auto xOffset = this->getOffset(e); auto yOffset = other.getOffset(e); f[xOffset] = func((Nd4jLong) 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 += increment) { auto xOffset = this->getOffset(e); auto yOffset = other.getOffset(e); auto zOffset = target.getOffset(e); z[zOffset] = func((Nd4jLong) e, f[xOffset], s[yOffset]); } }; samediff::Threads::parallel_for(loop, 0, _length); } } } template void NDArray::applyIndexedPairwiseLambda(NDArray& other, const std::function& func, NDArray& target); template void NDArray::applyIndexedPairwiseLambda(NDArray& other, const std::function& func, NDArray& target); template void NDArray::applyIndexedPairwiseLambda(NDArray& other, const std::function& func, NDArray& target); template void NDArray::applyIndexedPairwiseLambda(NDArray& other, const std::function& func, NDArray& target); template void NDArray::applyIndexedPairwiseLambda(NDArray& other, const std::function& func, NDArray& target); template void NDArray::applyIndexedPairwiseLambda(NDArray& other, const std::function& func, NDArray& target); template void NDArray::applyIndexedPairwiseLambda(NDArray& other, const std::function& func, NDArray& target); template void NDArray::applyIndexedPairwiseLambda(NDArray& other, const std::function& func, NDArray& target); template void NDArray::applyIndexedPairwiseLambda(NDArray& other, const std::function& func, NDArray& target); template void NDArray::applyIndexedPairwiseLambda(NDArray& other, const std::function& func, NDArray& target); template void NDArray::applyIndexedPairwiseLambda(NDArray& other, const std::function& func, NDArray& target); template void NDArray::applyIndexedPairwiseLambda(NDArray& other, const std::function& func, NDArray& target); template void NDArray::applyIndexedPairwiseLambda(NDArray& other, const std::function& func, NDArray& target);