| 
									
										
										
										
											2021-02-01 21:31:45 +09:00
										 |  |  | /* ******************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  |  * | 
					
						
							|  |  |  |  * 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.
 | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2021-02-01 21:31:45 +09:00
										 |  |  |  *  See the NOTICE file distributed with this work for additional | 
					
						
							|  |  |  |  *  information regarding copyright ownership. | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  |  * 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 | 
					
						
							|  |  |  |  ******************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // @author raver119@gmail.com
 | 
					
						
							|  |  |  | // @author Yurii Shyrma (iuriish@yahoo.com), created on 19.11.2018
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <types/types.h>
 | 
					
						
							| 
									
										
										
										
											2020-03-02 12:49:41 +03:00
										 |  |  | #include <system/op_boilerplate.h>
 | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  | #include <loops/reduce3.h>
 | 
					
						
							|  |  |  | #include <loops/legacy_ops.h>
 | 
					
						
							|  |  |  | #include <helpers/ConstantTadHelper.h>
 | 
					
						
							| 
									
										
										
										
											2020-03-02 12:49:41 +03:00
										 |  |  | #include <helpers/Loops.h>
 | 
					
						
							| 
									
										
										
										
											2019-11-13 17:15:18 +03:00
										 |  |  | #include <execution/Threads.h>
 | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | using namespace simdOps; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace functions { | 
					
						
							|  |  |  | namespace reduce3   { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | template <typename X, typename Z> | 
					
						
							|  |  |  | template<typename OpType> | 
					
						
							| 
									
										
										
										
											2020-05-09 08:06:14 +03:00
										 |  |  | void Reduce3<X,Z>::execScalar(const void *vx, const Nd4jLong *xShapeInfo, | 
					
						
							|  |  |  |                               void *vextraParams, | 
					
						
							|  |  |  |                               const void *vy, const Nd4jLong *yShapeInfo, | 
					
						
							|  |  |  |                               void *vz, const Nd4jLong *zShapeInfo) { | 
					
						
							| 
									
										
										
										
											2019-06-15 21:34:34 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-09 08:06:14 +03:00
										 |  |  |     auto x = reinterpret_cast<const X *>(vx); | 
					
						
							|  |  |  |     auto y = reinterpret_cast<const X *>(vy); | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  |     auto z = reinterpret_cast<Z *>(vz); | 
					
						
							|  |  |  |     auto extraParams = reinterpret_cast<Z *>(vextraParams); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto length = shape::length(xShapeInfo); | 
					
						
							|  |  |  |     auto xEws = shape::elementWiseStride(xShapeInfo); | 
					
						
							|  |  |  |     auto yEws = shape::elementWiseStride(yShapeInfo); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-02 12:49:41 +03:00
										 |  |  |     if(sd::ArrayOptions::arrayType(xShapeInfo) == sd::ArrayType::EMPTY || sd::ArrayOptions::arrayType(yShapeInfo) == sd::ArrayType::EMPTY) { | 
					
						
							|  |  |  |         if(sd::ArrayOptions::arrayType(zShapeInfo) == sd::ArrayType::EMPTY) | 
					
						
							| 
									
										
										
										
											2019-06-15 21:34:34 +10:00
										 |  |  |             return; | 
					
						
							|  |  |  |         const auto startingVal = OpType::startingValue(x); | 
					
						
							| 
									
										
										
										
											2019-11-13 17:15:18 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-26 20:12:19 +02:00
										 |  |  |         for (Nd4jLong i = 0; i < length; i++) | 
					
						
							| 
									
										
										
										
											2019-06-15 21:34:34 +10:00
										 |  |  |             z[i] = startingVal; | 
					
						
							| 
									
										
										
										
											2019-11-13 17:15:18 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-15 21:34:34 +10:00
										 |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  |     Z extraParamsVals[3] = {(Z) 0.0f, (Z) 0.0f, (Z) 0.0f}; | 
					
						
							| 
									
										
										
										
											2019-06-15 21:34:34 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  |     uint xShapeInfoCast[MAX_RANK]; | 
					
						
							| 
									
										
										
										
											2020-03-02 12:49:41 +03:00
										 |  |  |     const bool canCastX = sd::DataTypeUtils::castShapeInfo(xShapeInfo, xShapeInfoCast); | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Z startingVal = OpType::startingValue(x); | 
					
						
							| 
									
										
										
										
											2020-06-06 15:26:55 +03:00
										 |  |  |     int maxThreads = sd::math::nd4j_min<int>(64, sd::Environment::getInstance().maxThreads()); | 
					
						
							| 
									
										
										
										
											2019-11-13 17:15:18 +03:00
										 |  |  |     Z intermediate[64]; | 
					
						
							|  |  |  |     Z extraParamsLocal[3 * 64]; | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     PRAGMA_OMP_SIMD | 
					
						
							|  |  |  |     for (int e = 0; e < maxThreads; e++) | 
					
						
							|  |  |  |         intermediate[e] = startingVal; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-13 17:15:18 +03:00
										 |  |  |     memset(extraParamsLocal, 0, 3 * 64 * sizeof(Z)); | 
					
						
							|  |  |  |     if (extraParams != nullptr) { | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  |         PRAGMA_OMP_SIMD | 
					
						
							| 
									
										
										
										
											2019-11-13 17:15:18 +03:00
										 |  |  |         // mostly for future reference
 | 
					
						
							|  |  |  |         for (int e = 0; e < maxThreads; e++) { | 
					
						
							|  |  |  |             extraParamsLocal[3 * e] = extraParams[0]; | 
					
						
							|  |  |  |             extraParamsLocal[3 * e + 1] = extraParams[1]; | 
					
						
							|  |  |  |             extraParamsLocal[3 * e + 2] = extraParams[2]; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-02 12:49:41 +03:00
										 |  |  |     sd::LoopKind::Kind kindOfLoop = sd::LoopKind::deduceKindOfLoopXZ(xShapeInfo, yShapeInfo); | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-02 12:49:41 +03:00
										 |  |  |     if (kindOfLoop == sd::LoopKind::EWS1) { | 
					
						
							| 
									
										
										
										
											2019-11-13 17:15:18 +03:00
										 |  |  |         auto func = PRAGMA_THREADS_FOR { | 
					
						
							| 
									
										
										
										
											2020-02-20 11:43:26 +03:00
										 |  |  |             for (auto i = start; i < stop; i++) { | 
					
						
							| 
									
										
										
										
											2019-11-13 17:15:18 +03:00
										 |  |  |                 intermediate[thread_id] = OpType::update(intermediate[thread_id], OpType::op(x[i], y[i], extraParamsLocal + 3 * thread_id), extraParamsLocal + 3 * thread_id); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-09 08:22:49 +03:00
										 |  |  |         maxThreads = samediff::Threads::parallel_for(func, 0, length, 1, maxThreads); | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     } else if(shape::haveSameShapeAndStrides(xShapeInfo, yShapeInfo)) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-13 17:15:18 +03:00
										 |  |  |         auto func = PRAGMA_THREADS_FOR { | 
					
						
							| 
									
										
										
										
											2020-02-20 11:43:26 +03:00
										 |  |  |             for (auto i = start; i < stop; i++) { | 
					
						
							| 
									
										
										
										
											2019-11-13 17:15:18 +03:00
										 |  |  |                 auto offset = shape::indexOffset(i, xShapeInfo, xShapeInfoCast, canCastX); | 
					
						
							|  |  |  |                 intermediate[thread_id] = OpType::update(intermediate[thread_id], OpType::op(x[offset], y[offset], extraParamsLocal + 3 * thread_id), extraParamsLocal + 3 * thread_id); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-09 08:22:49 +03:00
										 |  |  |         maxThreads = samediff::Threads::parallel_for(func, 0, length, 1, maxThreads); | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  |     } else { | 
					
						
							|  |  |  |         uint yShapeInfoCast[MAX_RANK]; | 
					
						
							| 
									
										
										
										
											2020-03-02 12:49:41 +03:00
										 |  |  |         const bool canCastY = sd::DataTypeUtils::castShapeInfo(yShapeInfo, yShapeInfoCast); | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-13 17:15:18 +03:00
										 |  |  |         auto func = PRAGMA_THREADS_FOR { | 
					
						
							| 
									
										
										
										
											2020-02-20 11:43:26 +03:00
										 |  |  |             for (auto i = start; i < stop; i++) { | 
					
						
							| 
									
										
										
										
											2019-11-13 17:15:18 +03:00
										 |  |  |                 auto xOffset = shape::indexOffset(i, xShapeInfo, xShapeInfoCast, canCastX); | 
					
						
							|  |  |  |                 auto yOffset = shape::indexOffset(i, yShapeInfo, yShapeInfoCast, canCastY); | 
					
						
							|  |  |  |                 intermediate[thread_id] = OpType::update(intermediate[thread_id], OpType::op(x[xOffset], y[yOffset], extraParamsLocal + 3 * thread_id), extraParamsLocal + 3 * thread_id); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-09 08:22:49 +03:00
										 |  |  |         maxThreads = samediff::Threads::parallel_for(func, 0, length, 1, maxThreads); | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // merge step
 | 
					
						
							|  |  |  |     for (int e = 0; e < maxThreads; e++) | 
					
						
							|  |  |  |         OpType::aggregateExtraParams(extraParamsVals, extraParamsLocal + 3 * e); | 
					
						
							| 
									
										
										
										
											2019-11-13 17:15:18 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  |     for (int e = 0; e < maxThreads; e++) | 
					
						
							|  |  |  |         startingVal = OpType::update(startingVal, intermediate[e], extraParamsVals); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-13 17:15:18 +03:00
										 |  |  |     // writing out result
 | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  |     z[0] = OpType::postProcess(startingVal, length, extraParamsVals); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | template <typename X, typename Y> | 
					
						
							|  |  |  | void Reduce3<X,Y>::execScalar(const int opNum, | 
					
						
							| 
									
										
										
										
											2020-05-09 08:06:14 +03:00
										 |  |  |                               const void *vx, const Nd4jLong *xShapeInfo, | 
					
						
							|  |  |  |                               void *extraParamsVals, | 
					
						
							|  |  |  |                               const void *vy, const Nd4jLong *yShapeInfo, | 
					
						
							|  |  |  |                               void *vz, const Nd4jLong *zShapeInfo) { | 
					
						
							| 
									
										
										
										
											2019-06-15 21:34:34 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  |     DISPATCH_BY_OPNUM_TT(execScalar, PARAMS(vx, xShapeInfo, extraParamsVals, vy, yShapeInfo, vz, zShapeInfo), REDUCE3_OPS); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | template <typename X, typename Z> | 
					
						
							|  |  |  | template<typename OpType> | 
					
						
							| 
									
										
										
										
											2020-05-09 08:06:14 +03:00
										 |  |  | void Reduce3<X,Z>::exec(const void *vx, const Nd4jLong *xShapeInfo, | 
					
						
							|  |  |  |                         void *vextraParams, | 
					
						
							|  |  |  |                         const void *vy, const Nd4jLong *yShapeInfo, | 
					
						
							|  |  |  |                         void *vz, const Nd4jLong *zShapeInfo, | 
					
						
							|  |  |  |                         int *dimension, int dimensionLength, | 
					
						
							|  |  |  |                         int64_t start, int64_t stop) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto x = reinterpret_cast<const X*>(vx); | 
					
						
							|  |  |  |     auto y = reinterpret_cast<const X*>(vy); | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  |     auto z = reinterpret_cast<Z*>(vz); | 
					
						
							|  |  |  |     auto extraParams = reinterpret_cast<Z*>(vextraParams); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if(shape::isScalar(zShapeInfo)) { | 
					
						
							|  |  |  |         execScalar<OpType>(vx, xShapeInfo, vextraParams, vy, yShapeInfo, vz, zShapeInfo); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #ifdef INLINE_LOOPS
 | 
					
						
							| 
									
										
										
										
											2020-03-02 12:49:41 +03:00
										 |  |  |     sd::Reduction3Loops<X,Z>::template loopReduce3<OpType>(x, xShapeInfo, y, yShapeInfo, z, zShapeInfo, dimension, dimensionLength, extraParams, start, stop); | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2020-03-02 12:49:41 +03:00
										 |  |  |     sd::Reduction3Loops<X,Z>::template innerloopReduce3<OpType>(x, xShapeInfo, y, yShapeInfo, z, zShapeInfo, dimension, dimensionLength, extraParams, start, stop); | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | template <typename X, typename Z> | 
					
						
							|  |  |  | template<typename OpType> | 
					
						
							| 
									
										
										
										
											2020-05-09 08:06:14 +03:00
										 |  |  | void Reduce3<X,Z>::exec(const void *vx, const Nd4jLong *xShapeInfo, | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  |                         void *vextraParams, | 
					
						
							| 
									
										
										
										
											2020-05-09 08:06:14 +03:00
										 |  |  |                         const void *vy, const Nd4jLong *yShapeInfo, | 
					
						
							|  |  |  |                         void *vz, const Nd4jLong *zShapeInfo, | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  |                         int *dimension, int dimensionLength, | 
					
						
							| 
									
										
										
										
											2020-05-09 08:06:14 +03:00
										 |  |  |                         const Nd4jLong *tadShapeInfo, const Nd4jLong *tadOffsets, | 
					
						
							|  |  |  |                         int64_t start, int64_t stop) { | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-09 08:06:14 +03:00
										 |  |  |     auto x = reinterpret_cast<const X *>(vx); | 
					
						
							|  |  |  |     auto y = reinterpret_cast<const X *>(vy); | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  |     auto z = reinterpret_cast<Z *>(vz); | 
					
						
							|  |  |  |     auto extraParams = reinterpret_cast<Z *>(vextraParams); | 
					
						
							|  |  |  | #ifdef INLINE_LOOPS
 | 
					
						
							| 
									
										
										
										
											2020-03-02 12:49:41 +03:00
										 |  |  |     sd::Reduction3Loops<X,Z>::template loopReduce3<OpType>(x, xShapeInfo, y, yShapeInfo, z, zShapeInfo, dimension, dimensionLength, extraParams, start, stop); | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2020-03-02 12:49:41 +03:00
										 |  |  |     sd::Reduction3Loops<X,Z>::template innerloopReduce3<OpType>(x, xShapeInfo, y, yShapeInfo, z, zShapeInfo, dimension, dimensionLength, extraParams, start, stop); | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | template <typename X, typename Z> | 
					
						
							|  |  |  | template<typename OpType> | 
					
						
							| 
									
										
										
										
											2020-05-09 08:06:14 +03:00
										 |  |  | void Reduce3<X,Z>:: execAll(const void *vx, const Nd4jLong *xShapeInfo, | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  |                             void *vextraParams, | 
					
						
							| 
									
										
										
										
											2020-05-09 08:06:14 +03:00
										 |  |  |                             const void *vy, const Nd4jLong *yShapeInfo, | 
					
						
							|  |  |  |                             void *vz, const Nd4jLong *zShapeInfo, | 
					
						
							| 
									
										
										
										
											2019-06-15 21:34:34 +10:00
										 |  |  |                             int *dimension, int dimensionLength, | 
					
						
							| 
									
										
										
										
											2020-05-09 08:06:14 +03:00
										 |  |  |                             const Nd4jLong *xTadShapeInfo, const Nd4jLong *xOffsets, | 
					
						
							|  |  |  |                             const Nd4jLong *yTadShapeInfo, const Nd4jLong *yOffsets, | 
					
						
							|  |  |  |                             int64_t start, int64_t stop) { | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-09 08:06:14 +03:00
										 |  |  |     auto x = reinterpret_cast<const X *>(vx); | 
					
						
							|  |  |  |     auto y = reinterpret_cast<const X *>(vy); | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  |     auto z = reinterpret_cast<Z *>(vz); | 
					
						
							|  |  |  |     auto extraParams = reinterpret_cast<Z*>(vextraParams); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef INLINE_LOOPS
 | 
					
						
							| 
									
										
										
										
											2020-03-02 12:49:41 +03:00
										 |  |  |     sd::Reduction3Loops<X,Z>::template loopReduce3All<OpType>(x, xShapeInfo, y, yShapeInfo, z, zShapeInfo, xTadShapeInfo, xOffsets, yTadShapeInfo, yOffsets, extraParams, start, stop); | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2020-03-02 12:49:41 +03:00
										 |  |  |     sd::Reduction3Loops<X,Z>::template innerloopReduce3All<OpType>(x, xShapeInfo, y, yShapeInfo, z, zShapeInfo, xTadShapeInfo, xOffsets, yTadShapeInfo, yOffsets, extraParams, start, stop); | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | template <typename X, typename Y> | 
					
						
							| 
									
										
										
										
											2020-05-09 08:06:14 +03:00
										 |  |  | void Reduce3<X,Y>::exec(const int opNum, | 
					
						
							|  |  |  |                         const void *vx, const Nd4jLong *xShapeInfo, | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  |                         void *extraParamsVals, | 
					
						
							| 
									
										
										
										
											2020-05-09 08:06:14 +03:00
										 |  |  |                         const void *vy, const Nd4jLong *yShapeInfo, | 
					
						
							|  |  |  |                         void *vz, const Nd4jLong *zShapeInfo, | 
					
						
							|  |  |  |                         int *dimension, int dimensionLength, | 
					
						
							|  |  |  |                         int64_t start, int64_t stop) { | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-13 17:15:18 +03:00
										 |  |  |     DISPATCH_BY_OPNUM_TT(exec, PARAMS(vx, xShapeInfo, extraParamsVals, vy, yShapeInfo, vz, zShapeInfo, dimension, dimensionLength, start, stop), REDUCE3_OPS); | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | template <typename X, typename Y> | 
					
						
							| 
									
										
										
										
											2020-05-09 08:06:14 +03:00
										 |  |  | void Reduce3<X,Y>::exec(const int opNum, | 
					
						
							|  |  |  |                         const void *vx, const Nd4jLong *xShapeInfo, | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  |                         void *extraParamsVals, | 
					
						
							| 
									
										
										
										
											2020-05-09 08:06:14 +03:00
										 |  |  |                         const void *vy, const Nd4jLong *yShapeInfo, | 
					
						
							|  |  |  |                         void *vz, const Nd4jLong *zShapeInfo, | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  |                         int *dimension, int dimensionLength, | 
					
						
							| 
									
										
										
										
											2020-05-09 08:06:14 +03:00
										 |  |  |                         const Nd4jLong *tadShapeInfo, const Nd4jLong *tadOffsets, | 
					
						
							|  |  |  |                         int64_t start, int64_t stop) { | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-13 17:15:18 +03:00
										 |  |  |     DISPATCH_BY_OPNUM_TT(exec, PARAMS(vx,xShapeInfo,extraParamsVals,vy, yShapeInfo,vz,zShapeInfo, dimension, dimensionLength, tadShapeInfo, tadOffsets, start, stop), REDUCE3_OPS); | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | template <typename X, typename Y> | 
					
						
							|  |  |  | void Reduce3<X,Y>::execAll(const int opNum, | 
					
						
							| 
									
										
										
										
											2020-05-09 08:06:14 +03:00
										 |  |  |                            const void *vx, const Nd4jLong *xShapeInfo, | 
					
						
							|  |  |  |                            void *extraParamsVals, | 
					
						
							|  |  |  |                            const void *vy, const Nd4jLong *yShapeInfo, | 
					
						
							|  |  |  |                            void *vz, const Nd4jLong *zShapeInfo, | 
					
						
							|  |  |  |                            int *dimension, int dimensionLength, | 
					
						
							|  |  |  |                            const Nd4jLong *xTadShapeInfo, const Nd4jLong *xOffsets, | 
					
						
							|  |  |  |                            const Nd4jLong *yTadShapeInfo, const Nd4jLong *yOffsets, | 
					
						
							|  |  |  |                            int64_t start, int64_t stop) { | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-13 17:15:18 +03:00
										 |  |  |     DISPATCH_BY_OPNUM_TT(execAll, PARAMS(vx, xShapeInfo, extraParamsVals, vy, yShapeInfo, vz, zShapeInfo, dimension, dimensionLength, xTadShapeInfo, xOffsets, yTadShapeInfo, yOffsets, start, stop), REDUCE3_OPS); | 
					
						
							| 
									
										
										
										
											2019-06-06 15:21:15 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | } |