Skip to content

Commit 43273a3

Browse files
agibsoncccCopilot
andauthored
Fixes reshape relates segfaults, convert more tad pack related functions to use normal pointers to avoid java related deallocation isssues (deeplearning4j#10206)
* decrease usage of longshapedescriptor C++: still WIP. Still diagnosing crash and datatype issue with argmax. * fix shape buffer related segfaults * fix commented deletes * Update libnd4j/include/helpers/DirectShapeTrie.h Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * remove debugging delete comments * more delete comment removals * missed delete comments * more removals * Add calculator destructor --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 2516a8b commit 43273a3

File tree

120 files changed

+1616
-1116
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

120 files changed

+1616
-1116
lines changed

deeplearning4j/deeplearning4j-nn/src/main/java/org/deeplearning4j/nn/layers/convolution/subsampling/SubsamplingLayer.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.nd4j.linalg.api.buffer.DataType;
3737
import org.nd4j.linalg.api.ndarray.INDArray;
3838
import org.nd4j.linalg.api.ops.DynamicCustomOp;
39+
import org.nd4j.linalg.api.shape.Shape;
3940
import org.nd4j.linalg.factory.Nd4j;
4041

4142
import java.util.Arrays;
@@ -194,7 +195,7 @@ public INDArray activate(boolean training, LayerWorkspaceMgr workspaceMgr) {
194195
layerConf().getCnn2dDataFormat() == CNN2DFormat.NCHW ? 0 : 1); //0: NCHW, 1=NHWC
195196

196197
DynamicCustomOp build = b.build();
197-
long[] shape = build.calculateOutputShape().get(0).getShape();
198+
long[] shape = Shape.shape(build.calculateOutputShape().get(0).asLong());
198199

199200
INDArray output = workspaceMgr.createUninitialized(ArrayType.ACTIVATIONS, input.dataType(), shape, 'c');
200201
build.addOutputArgument(output);

deeplearning4j/deeplearning4j-nn/src/main/java/org/deeplearning4j/nn/layers/samediff/DL4JSameDiffMemoryMgr.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,13 @@
2222

2323
import org.nd4j.autodiff.samediff.internal.memory.AbstractMemoryMgr;
2424
import org.nd4j.common.base.Preconditions;
25+
import org.nd4j.linalg.api.buffer.DataBuffer;
2526
import org.nd4j.linalg.api.buffer.DataType;
2627
import org.nd4j.linalg.api.memory.MemoryWorkspace;
2728
import org.nd4j.linalg.api.memory.conf.WorkspaceConfiguration;
2829
import org.nd4j.linalg.api.ndarray.INDArray;
2930
import org.nd4j.linalg.api.shape.LongShapeDescriptor;
31+
import org.nd4j.linalg.api.shape.Shape;
3032
import org.nd4j.linalg.factory.Nd4j;
3133

3234
public class DL4JSameDiffMemoryMgr extends AbstractMemoryMgr {
@@ -87,4 +89,26 @@ public void release(INDArray array) {
8789
public void close() {
8890
//No-op - DL4J workspaces handles this
8991
}
92+
93+
@Override
94+
public INDArray allocateFromDescriptor(boolean detached, DataBuffer dataBuffer) {
95+
long[] shapeInfo = dataBuffer.asLong();
96+
DataType dataType = Shape.dataType(shapeInfo);
97+
long[] shape = Shape.shape(shapeInfo);
98+
String wsName = detached ? outputWs : workingMemoryWs;
99+
WorkspaceConfiguration wsConf = detached ? confOutput : confWorking;
100+
101+
if(wsName == null) {
102+
//Scoped out
103+
INDArray ret = Nd4j.createUninitializedDetached(dataType, shape);
104+
Preconditions.checkState(!ret.isAttached(), "Returned array should be detached");
105+
return ret;
106+
} else {
107+
MemoryWorkspace ws = Nd4j.getWorkspaceManager().getWorkspaceForCurrentThread(wsConf, wsName);
108+
ws.notifyScopeBorrowed();
109+
return Nd4j.createUninitialized(dataType, shape);
110+
111+
}
112+
113+
}
90114
}

libnd4j/include/array/ArrayOptions.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,9 @@ class SD_LIB_EXPORT ArrayOptions {
137137
static SD_HOST void validateSingleDataType(LongType property);
138138
static SD_HOST void setPropertyBit(LongType *shapeInfo, LongType property);
139139
static SD_HOST void setPropertyBits(LongType *shapeInfo, std::initializer_list<LongType> properties);
140-
141-
static SD_HOST bool isSparseArray(LongType *shapeInfo);
140+
static SD_HOST sd::LongType numDataTypesSet(sd::LongType property);
142141
static SD_HOST bool isUnsigned(LongType *shapeInfo);
143-
142+
static SD_HOST bool isSparseArray(sd::LongType *shapeInfo);
144143
static SD_HOST DataType dataType(const LongType *shapeInfo);
145144

146145
static SD_HOST SpaceType spaceType(LongType *shapeInfo);

libnd4j/include/array/ArrayOptions.hXX

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,9 @@ SD_HOST bool ArrayOptions::isUnsigned(sd::LongType *shapeInfo) {
245245
sd::DataType::UTF32 \
246246
}
247247

248+
long long int numDataTypesSet(sd::LongType property);
249+
long long int numDataTypesSet(sd::LongType property);
248250
SD_HOST sd::DataType ArrayOptions::dataTypeValue(sd::LongType property) {
249-
validateSingleDataType(property);
250251
const sd::LongType dataTypeFlags[] = DATA_TYPE_FLAGS;
251252
const sd::DataType dataTypes[] = DATA_TYPES;
252253
const size_t numTypes = sizeof(dataTypeFlags) / sizeof(sd::LongType);
@@ -273,6 +274,8 @@ SD_HOST sd::DataType ArrayOptions::dataTypeValue(sd::LongType property) {
273274
return sd::DataType::UNKNOWN;
274275
}
275276

277+
278+
276279
SD_HOST void validateFlags(sd::LongType property, const sd::LongType flags[], size_t numFlags) {
277280
LongType flagIndices[numFlags];
278281
int numFlagsSet = 0;
@@ -311,19 +314,28 @@ SD_HOST void ArrayOptions::validateSingleDataType(sd::LongType property) {
311314
}
312315

313316

317+
SD_HOST sd::LongType ArrayOptions::numDataTypesSet(sd::LongType property) {
318+
const sd::LongType dataTypeFlags[] = DATA_TYPE_FLAGS;
319+
const size_t numDataTypeFlags = sizeof(dataTypeFlags) / sizeof(sd::LongType);
314320

321+
LongType flagIndices[numDataTypeFlags];
322+
sd::LongType numFlagsSet = 0;
323+
for (size_t i = 0; i < numDataTypeFlags; ++i) {
324+
if (hasPropertyBitSetForFlags(property, dataTypeFlags[i])) {
325+
flagIndices[i] = 1;
326+
numFlagsSet++;
327+
} else {
328+
flagIndices[i] = 0;
329+
}
330+
}
331+
332+
return numFlagsSet;
333+
}
315334

316335
SD_HOST sd::DataType ArrayOptions::dataType(const sd::LongType *shapeInfo) {
317336
if(shapeInfo == nullptr)
318337
THROW_EXCEPTION("ArrayOptions::dataType(..) shapeInfo can not be null!");
319-
/*#if defined(SD_GCC_FUNCTRACE)
320-
Printer p;
321-
StackTrace st;
322-
st.load_here();
323-
FILE *fp = fopen("stacktrace-.txt", "a+");
324-
p.print(st,fp);
325-
fclose(fp);
326-
#endif*/
338+
327339
auto extra = ArrayOptions::extra(shapeInfo);
328340
return ArrayOptions::dataTypeValue(extra);
329341
}

libnd4j/include/array/ConstantShapeBuffer.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,15 @@ namespace sd {
3838

3939
class SD_LIB_EXPORT ConstantShapeBuffer {
4040
private:
41-
std::shared_ptr<PointerWrapper> _primaryShapeInfo;
42-
std::shared_ptr<PointerWrapper> _specialShapeInfo;
41+
PointerWrapper* _primaryShapeInfo;
42+
PointerWrapper* _specialShapeInfo;
4343

4444

4545
public:
46-
ConstantShapeBuffer(const std::shared_ptr<PointerWrapper> &primary);
47-
ConstantShapeBuffer(const std::shared_ptr<PointerWrapper> &primary, const std::shared_ptr<PointerWrapper> &special);
48-
ConstantShapeBuffer() = default;
46+
ConstantShapeBuffer( PointerWrapper* primary);
47+
ConstantShapeBuffer( PointerWrapper* primary, PointerWrapper* special);
48+
ConstantShapeBuffer();
49+
~ConstantShapeBuffer();
4950
#ifndef __JAVACPP_HACK__
5051
#if defined(SD_GCC_FUNCTRACE)
5152
backward::StackTrace st;

libnd4j/include/array/NDArray.hXX

Lines changed: 74 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,20 @@ std::u32string NDArray::e(sd::LongType i) {
9898
}
9999

100100
LongType NDArray::getOffset(const LongType i) {
101+
if (!isScalar() && i >= lengthOf()) {
102+
std::string errorMessage;
103+
errorMessage += "Requested index is out of range: [";
104+
errorMessage += StringUtils::valueToString<sd::LongType>(i);
105+
errorMessage += "] vs ";
106+
errorMessage += StringUtils::valueToString<sd::LongType>(lengthOf());
107+
errorMessage += " on array with shape ";
108+
errorMessage += ShapeUtils::shapeAsString(shapeInfo());
109+
THROW_EXCEPTION(errorMessage.c_str());
110+
}
111+
112+
101113
return _offset + i;
114+
102115
}
103116

104117
template <>
@@ -1810,14 +1823,8 @@ bool NDArray::isBroadcastableTo(NDArray &other) {
18101823
// This method assigns values of given NDArray to this one
18111824
void NDArray::assign(NDArray other, bool allowParallelism) {
18121825
NDArray::validateAssign(*this, other);
1813-
18141826
const sd::LongType* modifiedOtherShapeInfo = NDArray::modifyShapeForAssign(*this, other);
1815-
18161827
NDArray::copyDataForAssign(*this, other, modifiedOtherShapeInfo, allowParallelism);
1817-
1818-
if (modifiedOtherShapeInfo != other.shapeInfo()) {
1819-
RELEASE(const_cast<sd::LongType*>(modifiedOtherShapeInfo), getContext()->getWorkspace());
1820-
}
18211828
}
18221829
//////////////////////////////////////////////////////////////////////////
18231830

@@ -1947,7 +1954,7 @@ void NDArray::templatedSet(void *buffer, LongType offset, void *value) {
19471954
auto t = reinterpret_cast<T *>(buffer);
19481955
const auto y = *(reinterpret_cast<const Y *>(value));
19491956
if(t == nullptr) {
1950-
THROW_EXCEPTION("NDArray::templatedSet: first buffer is nullptr");
1957+
THROW_EXCEPTION("NDArray::templatedSet: first buffer is nullptr");
19511958
}
19521959

19531960
t[offset] = y;
@@ -2659,20 +2666,46 @@ void NDArray::copyDataForAssign(NDArray& thisArray, NDArray& other, const sd::L
26592666
// Adjusts shape for assignment without modifying the original array
26602667
const sd::LongType* NDArray::modifyShapeForAssign( NDArray& thisArray, NDArray& other) {
26612668
if (!shape::shapeEquals(thisArray.shapeInfo(), other.shapeInfo())) {
2662-
std::vector<sd::LongType> thisShape = thisArray.getShapeAsVector();
2663-
return reshapeShapeInfo(other, other.ordering(), thisShape);
2669+
std::vector<sd::LongType> *thisShape = new std::vector<sd::LongType>(thisArray.getShapeAsVector());
2670+
auto ret = reshapeShapeInfo(other, other.ordering(), *thisShape);
2671+
delete thisShape;
2672+
return ret;
26642673
}
26652674
return other.shapeInfo();
26662675
}
26672676

26682677
// Reshape logic modularized into a static helper function
2669-
sd::LongType* NDArray::reshapeShapeInfo( NDArray& array, char order, const std::vector<sd::LongType>& newShape) {
2678+
// Reshape logic modularized into a static helper function
2679+
sd::LongType* NDArray::reshapeShapeInfo(NDArray& array, char order, const std::vector<sd::LongType>& newShape) {
2680+
//nothing to do for scalar shape info
2681+
if(array.isScalar()) {
2682+
//no need for strides with scalar just set shape
2683+
sd::LongType *ret = new sd::LongType[shape::shapeInfoLength(newShape.size())];
2684+
// Initialize memory to prevent garbage values
2685+
memset(ret, 0, sizeof(sd::LongType) * shape::shapeInfoLength(newShape.size()));
2686+
2687+
ret[0] = newShape.size();
2688+
for (size_t i = 0; i < newShape.size(); i++) {
2689+
ret[i + 1] = newShape[i];
2690+
}
2691+
2692+
2693+
shape::setOrder(ret, 'c');
2694+
ArrayOptions::setExtra(ret, ArrayOptions::defaultFlag());
2695+
ArrayOptions::setDataType(ret, array.dataType());
2696+
2697+
auto ret2 = ConstantShapeHelper::getInstance().bufferForShapeInfo(ret);
2698+
delete[] ret;
2699+
return ret2->primary();
2700+
}
2701+
26702702
if (order != 'c' && order != 'f') {
26712703
std::string errorMessage = "reshapeShapeInfo: unknown order, must be 'c' or 'f', received: ";
26722704
errorMessage += order;
26732705
THROW_EXCEPTION(errorMessage.c_str());
26742706
}
26752707

2708+
26762709
std::vector<sd::LongType> shape_vector;
26772710
int numberNegativesOnes = 0;
26782711
for (size_t i = 0; i < newShape.size(); i++) {
@@ -2695,6 +2728,7 @@ sd::LongType* NDArray::reshapeShapeInfo( NDArray& array, char order, const std::
26952728
}
26962729
}
26972730

2731+
26982732
sd::LongType arrLength = 1;
26992733
for (const auto& dim : shape_vector) {
27002734
arrLength *= dim;
@@ -2704,20 +2738,36 @@ sd::LongType* NDArray::reshapeShapeInfo( NDArray& array, char order, const std::
27042738
THROW_EXCEPTION("reshapeShapeInfo: bad length of new shape!");
27052739
}
27062740

2707-
sd::LongType* shapeInfoNew = nullptr;
2708-
ALLOCATE(shapeInfoNew, array.getContext()->getWorkspace(),
2709-
shape::shapeInfoLength(shape_vector.size()), sd::LongType);
2741+
2742+
size_t shapeInfoLength = shape::shapeInfoLength(shape_vector.size());
2743+
2744+
2745+
sd::LongType* shapeInfoNew = new sd::LongType[shapeInfoLength];
2746+
2747+
// Initialize to prevent garbage values
2748+
memset(shapeInfoNew, 0, sizeof(sd::LongType) * shapeInfoLength);
2749+
27102750
shapeInfoNew[0] = static_cast<sd::LongType>(shape_vector.size());
2751+
27112752
bool canReshape = ops::helpers::reshapeNoAlloc(array.shapeInfo(), shape_vector, order, shapeInfoNew);
2712-
ArrayOptions::setDataType(shapeInfoNew, ArrayOptions::dataType(array.shapeInfo()));
2713-
shape::setOrder(shapeInfoNew, order);
27142753

27152754
if (!canReshape) {
27162755
shape::calcStrides(shapeInfoNew, order);
2756+
shape::setOrder(shapeInfoNew, order);
2757+
}
2758+
2759+
// Additional validation before passing to buffer
2760+
if (shapeInfoNew == nullptr) {
2761+
THROW_EXCEPTION("reshapeShapeInfo: shapeInfoNew is null after initialization!");
27172762
}
27182763

2719-
auto ret = ConstantShapeHelper::getInstance().bufferForShapeInfo(shapeInfoNew)->primary();
2720-
return const_cast<sd::LongType*>(ret);
2764+
2765+
auto ret = ConstantShapeHelper::getInstance().bufferForShapeInfo(shapeInfoNew);
2766+
2767+
delete[] shapeInfoNew;
2768+
2769+
2770+
return ret->primary();
27212771
}
27222772

27232773
NDArray& NDArray::reshape(const char order, std::vector<sd::LongType>& shape, bool copyToNewBuff) & {
@@ -2726,11 +2776,9 @@ NDArray& NDArray::reshape(const char order, std::vector<sd::LongType>& shape, bo
27262776
if (copyToNewBuff) {
27272777
NDArray* ret = new NDArray(newShapeInfo, true, getContext(), false);
27282778
this->applyTransform(transform::Assign, ret, nullptr);
2729-
RELEASE(const_cast<sd::LongType*>(newShapeInfo), getContext()->getWorkspace());
27302779
return *ret;
27312780
} else {
27322781
NDArray* ret = new NDArray(getDataBuffer(), const_cast<sd::LongType*>(newShapeInfo), getContext(), offset());
2733-
RELEASE(const_cast<sd::LongType*>(newShapeInfo), getContext()->getWorkspace());
27342782
return *ret;
27352783
}
27362784
}
@@ -3682,7 +3730,7 @@ void *NDArray::operator new(size_t i) {
36823730
////////////////////////////////////////////////////////////////////////
36833731
void NDArray::operator delete(void *p) {
36843732
if (!sd::memory::MemoryRegistrator::getInstance().hasWorkspaceAttached()) {
3685-
free(p);
3733+
free(p);
36863734
}
36873735
}
36883736

@@ -5043,7 +5091,7 @@ void NDArray::reduceAlongDimension(sd::reduce::BoolOps op, NDArray *target, cons
50435091
NativeOpExecutioner::execReduceBool(getContext(), op, buffer(), shapeInfo(), specialBuffer(), specialShapeInfo(),
50445092
nullptr, target->buffer(), zShapeInfoH, target->specialBuffer(), zShapeInfoD,
50455093
dims->data(), dims->size());
5046-
delete dims;
5094+
delete dims;
50475095
}
50485096
synchronize("NDArray::reduceAlongDimension LongOps");
50495097

@@ -5119,9 +5167,9 @@ template SD_LIB_EXPORT void NDArray::p(const sd::LongType i, const sd::LongType
51195167

51205168
////////////////////////////////////////////////////////////////////////
51215169
void NDArray::p(const sd::LongType i, NDArray *scalar) {
5122-
if (!scalar->isScalar())
5170+
if (scalar->lengthOf() > 1) {
51235171
THROW_EXCEPTION("NDArray::p method: input array must be scalar!");
5124-
5172+
}
51255173
if (i >= _length) {
51265174
std::string errorMessage;
51275175
errorMessage += "NDArray::p(i, NDArray_scalar): input index is out of array length !";
@@ -5196,9 +5244,9 @@ NDArray::p(const sd::LongType i, const T value) { // Note: value not NDArray re
51965244
THROW_EXCEPTION(errorMessage.c_str());
51975245
}
51985246
if(isScalar()) {
5199-
// Direct value assignment, no need for scalar.isS() check
5200-
templatedSet<T, T>(buffer(), 0, dataType(), (void*)&value);
5201-
return;
5247+
// Direct value assignment, no need for scalar.isS() check
5248+
templatedSet<T, T>(buffer(), 0, dataType(), (void*)&value);
5249+
return;
52025250
}
52035251

52045252
sd::LongType coords[1] = {i};

libnd4j/include/array/TadCalculator.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ namespace sd {
4040
class SD_LIB_EXPORT TadCalculator {
4141
private:
4242
LongType* _originalShape; // Original shape info pointer
43-
ConstantShapeBuffer _tadShape; // Calculated TAD shape buffer
44-
ConstantOffsetsBuffer _tadOffsets; // Calculated TAD offsets buffer
43+
ConstantShapeBuffer *_tadShape; // Calculated TAD shape buffer
44+
ConstantOffsetsBuffer *_tadOffsets; // Calculated TAD offsets buffer
4545
LongType _numTads; // Number of TADs
4646

4747
public:
@@ -50,7 +50,7 @@ class SD_LIB_EXPORT TadCalculator {
5050
* @param originalShape Pointer to the original shape information
5151
*/
5252
explicit TadCalculator(LongType* originalShape);
53-
~TadCalculator() = default;
53+
~TadCalculator();
5454

5555
/**
5656
* Creates a TAD pack for the given dimensions
@@ -62,19 +62,20 @@ class SD_LIB_EXPORT TadCalculator {
6262
* Returns the calculated TAD shape buffer
6363
* @return ConstantShapeBuffer containing TAD shape information
6464
*/
65-
ConstantShapeBuffer tadShape() const { return _tadShape; }
65+
ConstantShapeBuffer *tadShape() const { return _tadShape; }
6666

6767
/**
6868
* Returns the calculated TAD offsets buffer
6969
* @return ConstantOffsetsBuffer containing TAD offset information
7070
*/
71-
ConstantOffsetsBuffer tadOffsets() const { return _tadOffsets; }
71+
ConstantOffsetsBuffer *tadOffsets() const { return _tadOffsets; }
7272

7373
/**
7474
* Returns the number of TADs calculated
7575
* @return Number of TADs
7676
*/
7777
LongType numberOfTads() const { return _numTads; }
78+
virtual ~TadCalculator();
7879
};
7980

8081
} // namespace sd

0 commit comments

Comments
 (0)