cavis/libnd4j/include/ops/declarable/impl/LegacyReduceLongOp.cpp
Samuel Audet 029b84e2b7
Development updates (#9053)
* RL4J: Add generic update rule (#502)

Signed-off-by: Alexandre Boulanger <aboulang2002@yahoo.com>

* Shyrma reduce (#481)

* - start working on improving of cpu legacy code for reduce ops

Signed-off-by: Yurii <iuriish@yahoo.com>

* - further work on improving legacy loops

Signed-off-by: Yurii <iuriish@yahoo.com>

* - still working on improving reduce ops

Signed-off-by: Yurii <iuriish@yahoo.com>

* - further work on improving reduce ops

Signed-off-by: Yurii <iuriish@yahoo.com>

* - testing speed run of new reduce op

Signed-off-by: Yurii <iuriish@yahoo.com>

* - working on improvement of default loop for reduce op

Signed-off-by: Yurii <iuriish@yahoo.com>

* - update signatures of stuff which calls reduce ops

Signed-off-by: Yurii <iuriish@yahoo.com>

* - make corrections in cuda reduce kernels

Signed-off-by: Yurii <iuriish@yahoo.com>

* - change loop for default case in broadcast legacy ops

Signed-off-by: Yurii <iuriish@yahoo.com>

* - comment some shape stuff

Signed-off-by: Yurii <iuriish@yahoo.com>

* - comment unnecessary prints in RNGtests

Signed-off-by: Yurii <iuriish@yahoo.com>

* - finish to resolve conflicts after master has been merged

Signed-off-by: Yurii <iuriish@yahoo.com>

* - get rid of some compilation mistakes of cuda stuff

Signed-off-by: Yurii <iuriish@yahoo.com>

* - minor changes

Signed-off-by: Yurii <iuriish@yahoo.com>

* - further search for bug causing crash on java test

Signed-off-by: Yurii <iuriish@yahoo.com>

* - add scalar case in reduce_ ... exec stuff

Signed-off-by: Yurii <iuriish@yahoo.com>

* - minor corrections in NAtiveOps.cu

Signed-off-by: Yurii <iuriish@yahoo.com>

* - add switch to scalar case execReduceXD functions

Signed-off-by: Yurii <iuriish@yahoo.com>

* - add support for vectors old shape in ConstantShapeHelper::createShapeInfoWithNoUnitiesForReduce

Signed-off-by: Yurii <iuriish@yahoo.com>

* - correct cuda mirrorPad

Signed-off-by: Yurii <iuriish@yahoo.com>

* - add support for vectors old shape in cuda createShapeInfoWithNoUnitiesForReduce

Signed-off-by: Yurii <iuriish@yahoo.com>

Co-authored-by: raver119 <raver119@gmail.com>

* Add support for CUDA 11.0 (#492)

* Add support for CUDA 11.0

* libnd4j tweaks for CUDA 11

Signed-off-by: raver119@gmail.com <raver119@gmail.com>

* bindings update, again?

Signed-off-by: raver119@gmail.com <raver119@gmail.com>

* * Update versions of JavaCPP Presets for FFmpeg, OpenBLAS, and NumPy

* update API to match CUDA 8

Signed-off-by: raver119@gmail.com <raver119@gmail.com>

* * Update version of JavaCPP Presets for CPython

* C++ updated for cuDNN 8.0

Signed-off-by: raver119@gmail.com <raver119@gmail.com>

* one more test

Signed-off-by: raver119@gmail.com <raver119@gmail.com>

* one more test

Signed-off-by: raver119@gmail.com <raver119@gmail.com>

* one more test

Signed-off-by: raver119@gmail.com <raver119@gmail.com>

* 128-bit alignment for workspaces

Signed-off-by: raver119@gmail.com <raver119@gmail.com>

* change seed in 1 test

Signed-off-by: raver119@gmail.com <raver119@gmail.com>

* Fix dependecy duplication in python4j-parent pom

* Fix group id for in python4j-numpy

* few tests tweaked

Signed-off-by: raver119@gmail.com <raver119@gmail.com>

* Remove macosx-x86_64-gpu from nd4j-tests-tensorflow

* few minor tweaks for IndexReduce

Signed-off-by: raver119@gmail.com <raver119@gmail.com>

* one test removed

Signed-off-by: raver119@gmail.com <raver119@gmail.com>

Co-authored-by: raver119@gmail.com <raver119@gmail.com>
Co-authored-by: Serhii Shepel <9946053+sshepel@users.noreply.github.com>

* RL4J: Add SyncTrainer and AgentLearnerBuilder for a few algorithms (#504)

Signed-off-by: Alexandre Boulanger <aboulang2002@yahoo.com>

Co-authored-by: Alexandre Boulanger <44292157+aboulang2002@users.noreply.github.com>
Co-authored-by: Yurii Shyrma <iuriish@yahoo.com>
Co-authored-by: raver119 <raver119@gmail.com>
Co-authored-by: Serhii Shepel <9946053+sshepel@users.noreply.github.com>
2020-07-26 21:59:27 +09:00

177 lines
8.9 KiB
C++

/*******************************************************************************
* Copyright (c) 2015-2018 Skymind, Inc.
*
* 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.
*
* 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
******************************************************************************/
//
// Created by raver119 on 16.10.2017.
//
#include <ops/declarable/LegacyReduceLongOp.h>
#include <helpers/TAD.h>
#include <helpers/ShapeUtils.h>
#include <graph/Status.h>
#include <helpers/ConstantTadHelper.h>
#include <array/DataTypeUtils.h>
namespace sd {
namespace ops {
LegacyReduceLongOp::LegacyReduceLongOp() : LegacyOp::LegacyOp(1) {
//
}
LegacyReduceLongOp::LegacyReduceLongOp(int opNum) : LegacyOp::LegacyOp(1, opNum) {
//this->_opNum = opNum;
}
LegacyOp* LegacyReduceLongOp::clone() {
return new LegacyReduceLongOp(this->_opNum);
}
Nd4jStatus LegacyReduceLongOp::validateAndExecute(Context &block) {
auto x = INPUT_VARIABLE(0);
auto z = OUTPUT_VARIABLE(0);
NDArray::prepareSpecialUse({z}, {x});
int opNum = block.opNum() < 0 ? this->_opNum : block.opNum();
nd4j_debug("Executing LegacyReduceFloatOp: [%i]\n", opNum);
auto axis = *block.getAxis();
bool allAxes = false;
ExtraArguments extras(*block.getTArguments());
PointersManager manager(block.launchContext(),"LegacyReduceLongOp");
if (block.width() == 1) {
if (axis.size() == x->rankOf())
allAxes = true;
if ((axis.empty()) ||
(axis.size() == 1 && axis[0] == sd::DataTypeUtils::max<int>()) || allAxes) {
// scalar
NativeOpExecutioner::execReduceLongScalar(block.launchContext(), opNum, x->buffer(), x->shapeInfo(), x->specialBuffer(), x->specialShapeInfo(),
extras.argumentsAsT(x->dataType()), z->buffer(), z->shapeInfo(), z->specialBuffer(), z->specialShapeInfo());
} else {
// TAD
std::vector<int> dims(axis);
for (int e = 0; e < dims.size(); e++)
if (dims[e] < 0)
dims[e] += x->rankOf();
if (dims.size() > 1)
std::sort(dims.begin(), dims.end());
REQUIRE_TRUE(dims.size() > 0, 0, "Some dimensions required for reduction!");
const Nd4jLong* zShapeInfoH = z->shapeInfo();
const Nd4jLong* zShapeInfoD = z->specialShapeInfo();
if(x->rankOf() - dims.size() != z->rankOf()) {
auto zPack = ConstantShapeHelper::getInstance().createShapeInfoWithNoUnitiesForReduce(z->shapeInfo(), dims, z->getContext()->getWorkspace());
zShapeInfoH = reinterpret_cast<Nd4jLong const*>(zPack.primary());
zShapeInfoD = reinterpret_cast<Nd4jLong const*>(zPack.special());
}
std::vector<int> dims2 = ShapeUtils::evalDimsForReduceOp(x->rankOf(), dims);
NativeOpExecutioner::execReduceLong(block.launchContext(), opNum, x->buffer(), x->shapeInfo(), x->specialBuffer(), x->specialShapeInfo(), nullptr, z->buffer(), zShapeInfoH, z->specialBuffer(), zShapeInfoD, dims2.data(), dims2.size());
// auto packX = sd::ConstantTadHelper::getInstance().tadForDimensions(x->shapeInfo(), dims);
// auto pTadShape = Environment::getInstance().isCPU() ? packX.primaryShapeInfo() : packX.specialShapeInfo(); //(Nd4jLong *) manager.replicatePointer(tad.tadOnlyShapeInfo, shape::shapeInfoByteLength(tad.tadOnlyShapeInfo));
// auto pTadOffsets = Environment::getInstance().isCPU() ? packX.primaryOffsets() : packX.specialOffsets(); //(Nd4jLong *) manager.replicatePointer(tad.tadOffsets, tad.numTads * sizeof(Nd4jLong));
// NativeOpExecutioner::execReduceLong(block.launchContext(), opNum, x->buffer(), x->shapeInfo(), x->specialBuffer(), x->specialShapeInfo(),
// extras.argumentsAsT(x->dataType()),
// z->buffer(), z->shapeInfo(), z->specialBuffer(), z->specialShapeInfo(),
// dims.data(), (int) dims.size(), pTadShape, pTadOffsets);
}
STORE_RESULT(*z);
} else {
auto indices = INPUT_VARIABLE(1);
if (indices->lengthOf() == x->rankOf())
allAxes = true;
//indices->printIndexedBuffer("indices");
std::vector<int> dims(indices->lengthOf());
for (int e = 0; e < indices->lengthOf(); e++) {
// lol otherwise we segfault on macOS
int f = indices->e<int>(e);
dims[e] = f >= 0 ? f : f += x->rankOf();
}
if ((block.getIArguments()->size() == 1 && INT_ARG(0) == sd::DataTypeUtils::max<int>()) || allAxes) {
// scalar
NativeOpExecutioner::execReduceLongScalar(block.launchContext(), opNum, x->buffer(), x->shapeInfo(), x->specialBuffer(), x->specialShapeInfo(), extras.argumentsAsT(x->dataType()), z->buffer(), z->shapeInfo(), z->specialBuffer(), z->specialShapeInfo());
} else {
// TAD
REQUIRE_TRUE(dims.size() > 0, 0, "Some dimensions required for reduction!");
const Nd4jLong* zShapeInfoH = z->shapeInfo();
const Nd4jLong* zShapeInfoD = z->specialShapeInfo();
if(x->rankOf() - dims.size() != z->rankOf()) {
auto zPack = ConstantShapeHelper::getInstance().createShapeInfoWithNoUnitiesForReduce(z->shapeInfo(), dims, z->getContext()->getWorkspace());
zShapeInfoH = reinterpret_cast<Nd4jLong const*>(zPack.primary());
zShapeInfoD = reinterpret_cast<Nd4jLong const*>(zPack.special());
}
std::vector<int> dims2 = ShapeUtils::evalDimsForReduceOp(x->rankOf(), dims);
NativeOpExecutioner::execReduceLong(block.launchContext(), opNum, x->buffer(), x->shapeInfo(), x->specialBuffer(), x->specialShapeInfo(), nullptr, z->buffer(), zShapeInfoH, z->specialBuffer(), zShapeInfoD, dims2.data(), dims2.size());
// auto packX = sd::ConstantTadHelper::getInstance().tadForDimensions(x->shapeInfo(), dims);
// auto pTadShape = Environment::getInstance().isCPU() ? packX.primaryShapeInfo() : packX.specialShapeInfo(); //(Nd4jLong *) manager.replicatePointer(tad.tadOnlyShapeInfo, shape::shapeInfoByteLength(tad.tadOnlyShapeInfo));
// auto pTadOffsets = Environment::getInstance().isCPU() ? packX.primaryOffsets() : packX.specialOffsets(); //(Nd4jLong *) manager.replicatePointer(tad.tadOffsets, tad.numTads * sizeof(Nd4jLong));
// NativeOpExecutioner::execReduceLong(block.launchContext(), opNum, x->buffer(), x->shapeInfo(), x->specialBuffer(), x->specialShapeInfo(), extras.argumentsAsT(x->dataType()),
// z->buffer(), z->shapeInfo(), z->specialBuffer(), z->specialShapeInfo(), dims.data(), (int) dims.size(), pTadShape, pTadOffsets);
}
}
manager.synchronize();
return Status::OK();
}
/**
* For all reductions rules are simple: either you return scalar, or you return reduced NDArray.
* It solely depends on input shape, and requested dimensions
*/
ShapeList *LegacyReduceLongOp::calculateOutputShape(ShapeList *inputShape, sd::graph::Context &block) {
auto inShape = inputShape->at(0);
Nd4jLong *newShape;
bool allAxes = false;
auto keepDims = block.numB() > 0 ? B_ARG(0) : false;
auto newFormat = block.numB() > 1 ? B_ARG(1) : true;
auto axis = block.width() > 1 ? INPUT_VARIABLE(1)->asVectorT<int>() : *block.getAxis();
if (axis.size() == shape::rank(inShape))
allAxes = true;
// in this case we're building proper shape for reduction
return SHAPELIST(ShapeUtils::evalReduceShapeInfo(shape::order(inShape), axis, inShape, DataType::INT64, keepDims, !newFormat, block.workspace()));
}
}
}