chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:47:05 +08:00
commit 4f3b7da785
7394 changed files with 2005594 additions and 0 deletions
+878
View File
@@ -0,0 +1,878 @@
/* ******************************************************************************
*
*
* 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
******************************************************************************/
//
// @author raver119@gmail.com
//
#include <array/InteropDataBuffer.h>
#include <graph/Context.h>
#include <helpers/ShapeUtils.h>
#if defined(SD_GCC_FUNCTRACE)
#include <graph/OpContextLifecycleTracker.h>
#endif
namespace sd {
namespace graph {
Context::Context(ContextPrototype *prototype, VariableSpace *variableSpace) {
_variableSpace = variableSpace;
_dataType = prototype->dataType();
if (prototype != nullptr) {
for (const auto &v : *(prototype->inputs())) {
this->_inputs.push_back(v);
}
for (const auto &v : *(prototype->getTArguments())) {
this->_tArgs.push_back(v);
}
for (const auto &v : *(prototype->getIArguments())) {
this->_iArgs.push_back(v);
}
for (const auto &v : *(prototype->getBArguments())) {
this->_bArgs.push_back(v);
}
for (const auto &v : *(prototype->getAxis())) {
this->_axis.push_back(v);
}
for(auto v : *(prototype->getDArguments())) {
this->_dataTypes.push_back(v);
}
this->_opNum = prototype->opNum();
this->_isInplace = prototype->isInplace();
this->_nodeId = prototype->nodeId();
this->_useONEDNN = prototype->isUseONEDNN();
}
if (variableSpace != nullptr && variableSpace->launchContext()->getWorkspace() != nullptr)
this->_workspace = variableSpace->launchContext()->getWorkspace();
#if defined(SD_GCC_FUNCTRACE)
// Track OpContext allocation
OpContextLifecycleTracker::getInstance().recordAllocation(
this, _nodeId,
_fastpath_in.size(), _fastpath_out.size(),
_intermediateResults.size(), _handles.size(),
_workspace != nullptr, isFastPath());
#endif
}
DataType Context::dataType(int index) {
if(numD() < 1) {
if(width() > 0) {
return this->array(index)->dataType();
} else {
std::string errorMessage;
errorMessage += std::string("Context::dataType: Unable to determine data type. Both d args and inputs are empty.");
errorMessage += std::string(" Index: ");
errorMessage += std::to_string(index);
errorMessage += std::string(" Width: ");
errorMessage += std::to_string(width());
THROW_EXCEPTION(errorMessage.c_str());
};
}
return getDArguments()->at(index);
}
DataType Context::dataType() { return dataType(0); }
void Context::setDataType(int index, DataType type) {
if (this->_dataTypes.size() > (size_t)index) _dataTypes[index] = type;
_dataType = type;
}
Context::Context(int nodeId, VariableSpace *variableSpace) {
this->_nodeId = nodeId;
this->_variableSpace = variableSpace;
this->_isInplace = false;
this->_workspace = nullptr;
this->_executionTime.first = 0;
this->_executionTime.second = 0;
if (variableSpace != nullptr && variableSpace->launchContext()->getWorkspace() != nullptr)
this->_workspace = variableSpace->launchContext()->getWorkspace();
#if defined(SD_GCC_FUNCTRACE)
// Track OpContext allocation
OpContextLifecycleTracker::getInstance().recordAllocation(
this, _nodeId,
_fastpath_in.size(), _fastpath_out.size(),
_intermediateResults.size(), _handles.size(),
_workspace != nullptr, isFastPath());
#endif
}
Context::Context(int nodeId, VariableSpace *variableSpace, bool isInplace) : Context(nodeId, variableSpace) {
this->_isInplace = isInplace;
}
Context::~Context() {
#if defined(SD_GCC_FUNCTRACE)
// Track OpContext deallocation before cleanup
OpContextLifecycleTracker::getInstance().recordDeallocation(this);
#endif
this->_iArgs.clear();
this->_tArgs.clear();
this->_inputs.clear();
// IMPORTANT: Do NOT delete arrays in _fastpath_in and _fastpath_out!
// These are BORROWED pointers - the Context does not own them.
// The caller (e.g., DeclarableOp::execute) owns these arrays and is
// responsible for their lifecycle. Deleting them here causes use-after-free
// bugs when operations call sub-operations (e.g., layer_norm calling standardize).
// Only _handles contains arrays explicitly marked as owned by this Context.
this->_fastpath_in.clear();
this->_fastpath_out.clear();
// Clean up intermediate results - these ARE owned by the Context
for (auto v : _intermediateResults) {
if (v != nullptr) delete v;
}
_intermediateResults.clear();
// Clean up handles - these are arrays explicitly marked as removable/owned
for (auto v : _handles) delete v;
if (_context != nullptr) delete _context;
}
void Context::setTargetEngine(samediff::Engine engine) { _engine = engine; }
bool Context::hasWorkspaceProvided() { return this->_workspace != nullptr; }
void Context::attachWorkspace(sd::memory::Workspace *workspace) { this->_workspace = workspace; }
void Context::setVariableSpace(VariableSpace *variableSpace) { this->_variableSpace = variableSpace; }
void Context::forgetWorkspace() { _workspace = nullptr; }
std::vector<NDArray *> &Context::fastpath_in() { return _fastpath_in; }
std::vector<NDArray *> &Context::fastpath_out() { return _fastpath_out; }
bool Context::isFastPath() {
auto ie = _fastpath_in.empty();
auto io = _fastpath_out.empty();
// two options here.
// either both IN/OUT are filled
auto b1 = (!ie && !io) || (!ie && _isInplace);
// or at least something is filled, and FastPath is NOT forbidden
auto b2 = (!ie || !io) && !_forbidFastPath;
return b1 || b2;
}
void Context::forbidFastPath(bool reallyForbid) { _forbidFastPath = reallyForbid; }
VariableSpace *Context::getVariableSpace() { return _variableSpace; }
memory::Workspace *Context::getWorkspace() { return _workspace; }
memory::Workspace *Context::workspace() { return _workspace; }
random::RandomBuffer *Context::getRNG() { return _rng; }
void Context::setRNG(random::RandomBuffer *rng) { _rng = rng; }
Stash *Context::getStash() {
if (_variableSpace == nullptr) {
THROW_EXCEPTION("Context::getStash: VariableSpace is null. Context was not properly initialized.");
}
return _variableSpace->getStash();
}
void Context::trackList(NDArrayList *list) {
if (_variableSpace == nullptr) {
THROW_EXCEPTION("Context::trackList: VariableSpace is null. Context was not properly initialized.");
}
_variableSpace->trackList(list);
}
int Context::getBranch() {
if (_variableSpace == nullptr) {
THROW_EXCEPTION("Context::getBranch: VariableSpace is null. Context was not properly initialized.");
}
if (_variableSpace->flowPath() == nullptr) {
return 0; // Default branch when no flow path is set
}
return _variableSpace->flowPath()->branch(this->nodeId());
}
void Context::setBranch(int branch) {
//_branch = branch;
if (_variableSpace != nullptr && _variableSpace->flowPath() != nullptr) {
_variableSpace->flowPath()->markBranch(this->nodeId(), branch);
}
}
LongType Context::getOuterTime() { return this->_executionTime.first; }
LongType Context::getInnerTime() { return this->_executionTime.second; }
void Context::setOuterTime(LongType time) { this->_executionTime.first = time; }
void Context::setInnerTime(LongType time) { this->_executionTime.second = time; }
Variable *Context::getVariable(int idx) {
if (static_cast<size_t>(idx) >= this->_inputs.size()) {
std::string errorMessage;
errorMessage += "Node ";
errorMessage += std::to_string(this->_nodeId);
errorMessage += "; Variable [";
errorMessage += std::to_string(idx);
errorMessage += " requested, but only ";
errorMessage += std::to_string(this->_inputs.size());
errorMessage += " available";
THROW_EXCEPTION(errorMessage.c_str());
}
auto p = this->_inputs[idx];
auto v = variable(p);
// preconditioned with v->variableType()==VariableType::NDARRAY as for other cases getNDArray() can throw exception
if (Environment::getInstance().isDebugAndVerbose() && v != nullptr && v->variableType() == NDARRAY &&
v->getNDArray() != nullptr) {
auto array = v->getNDArray();
std::string shape_ = ShapeUtils::shapeAsString(array);
auto type = DataTypeUtils::asString(array->dataType());
float m = std::numeric_limits<float>::quiet_NaN();
if (!array->isEmpty()) {
LongType maxLen = sd::math::sd_min<LongType>(16, array->lengthOf() - 1);
sd_printf("Debug info for node_%i input[%i]; shape: %s; ews: [%i]; order: [%c]; dtype: [%s];\n",
this->_nodeId, idx, shape_.c_str(),array->ews(), array->ordering(), type.c_str());
std::vector<sd::LongType> shapeLen = {array->lengthOf()};
NDArray *raveled = array->reshape(array->ordering(), shapeLen);
sd_printf("Values: [ ",0);
for (LongType i = 0; i < maxLen; i++) {
auto v2 = raveled->e<float>(i);
sd_printf("%f, ", v2);
}
delete raveled;
sd_printf("]\n",0);
} else {
sd_printf("Debug info for node_%i input[%i]; shape: %s; ews: [%i]; order: [%c]; dtype: [%s]; mean value: [%f]\n",
this->_nodeId, idx, shape_.c_str(), (int)array->ews(), array->ordering(), type.c_str(), m);
}
}
return v;
}
Variable *Context::variable(int idx) { return getVariable(idx); }
Variable *Context::variable(std::initializer_list<int> p) {
if (p.size() != 2) THROW_EXCEPTION("Variable address should have size of 2");
std::vector<int> vec(p);
std::pair<int, int> pair(vec[0], vec[1]);
return variable(pair);
}
Variable *Context::variable(int node, int idx) {
std::pair<int, int> pair(node, idx);
return variable(pair);
}
Variable *Context::variable(std::pair<int, int> &p) {
if (_variableSpace == nullptr) {
std::string errorMessage;
errorMessage += "Node ";
errorMessage += std::to_string(this->_nodeId);
errorMessage += "; VariableSpace is null when trying to get variable: [";
errorMessage += std::to_string(p.first);
errorMessage += ":";
errorMessage += std::to_string(p.second);
errorMessage += "]. This usually means the Context was not properly initialized or fastpath was expected but failed.";
THROW_EXCEPTION(errorMessage.c_str());
}
#ifdef __cpp_exceptions
try {
return _variableSpace->getVariable(p);
} catch (std::exception &e) {
std::string errorMessage;
errorMessage += "Node ";
errorMessage += std::to_string(this->_nodeId);
errorMessage += "; Non-existent variable requested: [";
errorMessage += std::to_string(p.first);
errorMessage += ":";
errorMessage += std::to_string(p.second);
errorMessage += "]";
errorMessage += "\n";
THROW_EXCEPTION(errorMessage.c_str());
}
#else
return _variableSpace->getVariable(p);
#endif
return nullptr;
}
void Context::pushNDArrayToVariableSpace(int nodeId, int index, NDArray *array, bool removable) {
std::pair<int, int> pair(nodeId, index);
pushNDArrayToVariableSpace(pair, array, removable);
}
void Context::pushNDArrayToVariableSpace(std::pair<int, int> &pair, NDArray *array, bool removable) {
if (_variableSpace != nullptr) {
if (!_variableSpace->hasVariable(pair)) {
auto var = new Variable(array, nullptr, pair.first, pair.second);
_variableSpace->putVariable(pair, var);
var->markRemovable(removable);
} else {
sd_debug("Context: Getting variable in push ndarray\n",0);
auto var = _variableSpace->getVariable(pair);
sd_debug("Context: After getting variable in push ndarray to variable space\n",0);
if (var->hasNDArray()) {
if (var->getNDArray() != array) {
if (var->isRemovable() && var->hasNDArray() && !var->getNDArray()->isView()) {
delete var->getNDArray();
}
var->setNDArray(array);
var->markRemovable(removable);
}
} else {
var->setNDArray(array);
var->markRemovable(removable);
}
}
}
}
void Context::pushNDArrayListToVariableSpace(int nodeId, int index, NDArrayList *list, bool track) {
std::pair<int, int> pair(nodeId, index);
pushNDArrayListToVariableSpace(pair, list, track);
}
void Context::pushNDArrayListToVariableSpace(std::pair<int, int> &pair, NDArrayList *list, bool track) {
sd_debug("Pre push variable list\n",0);
if (_variableSpace == nullptr) {
THROW_EXCEPTION("Context::pushNDArrayListToVariableSpace: VariableSpace is null. Context was not properly initialized.");
}
if (!_variableSpace->hasVariable(pair)) {
sd_debug("Context::pushNDArrayListToVariableSpace: Pre create variable when none exists\n",0);
auto var = new Variable(nullptr, nullptr, pair.first, pair.second);
sd_debug("Context::pushNDArrayListToVariableSpace: Created when none exists\n",0);
var->setNDArrayList(list);
_variableSpace->putVariable(pair, var);
sd_debug("Context::pushNDArrayListToVariableSpace: Put variable\n",0);
} else {
sd_debug("Context::pushNDArrayListToVariableSpace: In else: Getting variable\n",0);
auto var = _variableSpace->getVariable(pair);
sd_debug("Context::pushNDArrayListToVariableSpace: Got variable setting list\n",0);
var->setNDArrayList(list);
}
sd_debug("Context::pushNDArrayListToVariableSpace: pre tracking\n",0);
if (track) _variableSpace->trackList(list);
}
Variable *Context::ensureVariable(int idx) {
std::pair<int, int> pair(this->nodeId(), idx);
if (_variableSpace == nullptr) THROW_EXCEPTION("Context::ensureVariable VariableSpace is NULL!");
if (!_variableSpace->hasVariable(pair)) {
auto var = new Variable(nullptr, nullptr, this->nodeId(), idx);
_variableSpace->putVariable(pair, var);
return var;
} else {
sd_debug("Before ensure variable",0);
return _variableSpace->getVariable(pair);
}
}
bool Context::isValueAvailable(int idx) {
auto var = ensureVariable(idx);
if (var->variableType() == NDARRAY) {
return var->hasNDArray();
} else if (var->variableType() == ARRAY_LIST) {
return var->hasNDArrayList();
}
return false;
}
NDArray *Context::getNDArray(int idx) { return array(idx); }
NDArray *Context::outputArray(int idx) {
// we check for fastpath first
if (!_fastpath_out.empty() && _fastpath_out.size() > static_cast<size_t>(idx)) {
NDArray* result = _fastpath_out[idx];
// Validate the output NDArray to catch memory corruption early
if (result != nullptr) {
const sd::LongType* shInfo = result->shapeInfo();
if (shInfo == nullptr) {
std::string errorMessage;
errorMessage += "Context::outputArray(";
errorMessage += std::to_string(idx);
errorMessage += "): NDArray has null shapeInfo. This indicates severe memory corruption or use-after-free.";
THROW_EXCEPTION(errorMessage.c_str());
}
sd::LongType rank = shInfo[0];
if (rank < 0 || rank > 32) {
std::string errorMessage;
errorMessage += "Context::outputArray(";
errorMessage += std::to_string(idx);
errorMessage += "): NDArray has corrupted rank: ";
errorMessage += std::to_string(rank);
errorMessage += " (expected 0-32). This likely indicates:\n";
errorMessage += " 1. Memory corruption in the output NDArray\n";
errorMessage += " 2. Use-after-free (accessing deallocated memory)\n";
errorMessage += " 3. Uninitialized output buffer allocation failure\n";
errorMessage += " 4. JNI marshalling error from Java layer";
THROW_EXCEPTION(errorMessage.c_str());
}
}
return result;
}
std::string errorMessage;
errorMessage += std::string("Context::outputArray: Fastpath is empty");
errorMessage += std::string(" Index: ");
errorMessage += std::to_string(idx);
errorMessage += std::string(" Fastpath size: ");
errorMessage += std::to_string(_fastpath_out.size());
THROW_EXCEPTION(errorMessage.c_str());
return nullptr;
}
NDArray *Context::array(int idx) {
// we check for fastpath first
if (!_fastpath_in.empty() && _fastpath_in.size() > static_cast<size_t>(idx)) {
NDArray* result = _fastpath_in[idx];
// Validate the NDArray to catch memory corruption early
if (result != nullptr) {
const sd::LongType* shInfo = result->shapeInfo();
if (shInfo == nullptr) {
std::string errorMessage;
errorMessage += "Context::array(";
errorMessage += std::to_string(idx);
errorMessage += "): NDArray has null shapeInfo. This indicates severe memory corruption or use-after-free.";
THROW_EXCEPTION(errorMessage.c_str());
}
// Check if rank is valid (should be 0-32, not a memory address)
sd::LongType rank = shInfo[0];
if (rank < 0 || rank > 32) {
std::string errorMessage;
errorMessage += "Context::array(";
errorMessage += std::to_string(idx);
errorMessage += "): NDArray has corrupted rank: ";
errorMessage += std::to_string(rank);
errorMessage += " (expected 0-32). This likely indicates:\n";
errorMessage += " 1. Memory corruption in the NDArray\n";
errorMessage += " 2. Use-after-free (accessing deallocated memory)\n";
errorMessage += " 3. Uninitialized NDArray from failed operation\n";
errorMessage += " 4. JNI marshalling error from Java layer";
THROW_EXCEPTION(errorMessage.c_str());
}
}
return result;
}
// When using fastpath (from OpContext/Java), _variableSpace is null by design.
// If the operation expects more inputs than were provided via setInputArrays(),
// throw an informative error instead of crashing in getVariable().
if (!_fastpath_in.empty() && _variableSpace == nullptr) {
// Fastpath has some inputs but not enough for the requested index
std::string errorMessage;
errorMessage += "Context::array(";
errorMessage += std::to_string(idx);
errorMessage += "): Input index out of bounds. Fastpath has ";
errorMessage += std::to_string(_fastpath_in.size());
errorMessage += " input array(s), but input at index ";
errorMessage += std::to_string(idx);
errorMessage += " was requested.\n";
errorMessage += "This typically means the operation expects more inputs than were provided.\n";
errorMessage += "For variable-input operations (like concat), ensure all input arrays are set via setInputArrays().";
THROW_EXCEPTION(errorMessage.c_str());
}
// if no luck for fastpath - return whatever is available
NDArray* result = getVariable(idx)->getNDArray();
// Validate the NDArray from variable path as well
if (result != nullptr) {
const sd::LongType* shInfo = result->shapeInfo();
if (shInfo == nullptr) {
std::string errorMessage;
errorMessage += "Context::array(";
errorMessage += std::to_string(idx);
errorMessage += "): NDArray from variable has null shapeInfo. This indicates severe memory corruption or use-after-free.";
THROW_EXCEPTION(errorMessage.c_str());
}
sd::LongType rank = shInfo[0];
if (rank < 0 || rank > 32) {
std::string errorMessage;
errorMessage += "Context::array(";
errorMessage += std::to_string(idx);
errorMessage += "): NDArray from variable has corrupted rank: ";
errorMessage += std::to_string(rank);
errorMessage += " (expected 0-32). This likely indicates:\n";
errorMessage += " 1. Memory corruption in the NDArray\n";
errorMessage += " 2. Use-after-free (accessing deallocated memory)\n";
errorMessage += " 3. Uninitialized NDArray from failed operation\n";
errorMessage += " 4. JNI marshalling error from Java layer";
THROW_EXCEPTION(errorMessage.c_str());
}
}
return result;
}
memory::Workspace *Context::fWorkspace() { return workspace(); }
memory::Workspace *Context::tWorkspace() { return nullptr; }
memory::Workspace *Context::oWorkspace() { return nullptr; }
LaunchContext *Context::launchContext() {
// FIXME: we need proper context to be shared here
if (_context == nullptr) {
return LaunchContext::defaultContext();
} else {
return _context;
}
}
unsigned long Context::outputWidth() {
return _fastpath_out.size();
}
unsigned long Context::width() {
if (!_fastpath_in.empty())
return _fastpath_in.size();
else
return _inputs.size();
}
void Context::setInputArray(int index, NDArray *array, bool removable) {
// Check for null array FIRST before any dereference
if (array == nullptr) {
std::string errorMessage;
errorMessage += std::string("Context::setInputArray: Array at index ");
errorMessage += std::to_string(index);
errorMessage += std::string(" is null!");
THROW_EXCEPTION(errorMessage.c_str());
}
if(array->shapeInfo() == nullptr) {
std::string errorMessage;
errorMessage += std::string("Array at index ");
errorMessage += std::to_string(index);
errorMessage += std::string(" has a null shape buffer!");
THROW_EXCEPTION(errorMessage.c_str());
}
if(array->dataType() != ArrayOptions::dataType(array->shapeInfo())) {
std::string errorMessage;
errorMessage += std::string("Array at index ");
errorMessage += std::to_string(index);
errorMessage += std::string(" has a different data type than the shape buffer!");
//add the shape info as a string to the error message
errorMessage += std::string(" Shape info: ");
errorMessage += ShapeUtils::shapeAsString(array->shapeInfo());
errorMessage += std::string(" Data type: ");
errorMessage += DataTypeUtils::asString(ArrayOptions::dataType(array->shapeInfo()));
THROW_EXCEPTION(errorMessage.c_str());
}
if (_fastpath_in.size() < static_cast<size_t>(index + 1)) _fastpath_in.resize(index + 1);
_fastpath_in[index] = array;
if (removable) _handles.emplace_back(array);
}
void Context::setOutputArray(int index, NDArray *array, bool removable) {
// Check for null array FIRST before any dereference
if (array == nullptr) {
std::string errorMessage;
errorMessage += std::string("Context::setOutputArray: Array at index ");
errorMessage += std::to_string(index);
errorMessage += std::string(" is null!");
THROW_EXCEPTION(errorMessage.c_str());
}
if (_fastpath_out.size() < static_cast<size_t>(index + 1)) _fastpath_out.resize(index + 1);
// Check for null shapeInfo before accessing it
if (array->shapeInfo() == nullptr) {
std::string errorMessage;
errorMessage += std::string("Context::setOutputArray: Array at index ");
errorMessage += std::to_string(index);
errorMessage += std::string(" has a null shape buffer!");
THROW_EXCEPTION(errorMessage.c_str());
}
if(array->dataType() != ArrayOptions::dataType(array->shapeInfo())) {
std::string errorMessage;
errorMessage += std::string("Array at index ");
errorMessage += std::to_string(index);
errorMessage += std::string(" has a different data type than the shape buffer!");
//add the shape info as a string to the error message
errorMessage += std::string(" Shape info: ");
errorMessage += ShapeUtils::shapeAsString(array->shapeInfo());
errorMessage += std::string(" Data type: ");
errorMessage += DataTypeUtils::asString(ArrayOptions::dataType(array->shapeInfo()));
THROW_EXCEPTION(errorMessage.c_str());
}
_fastpath_out[index] = array;
if (removable) _handles.emplace_back(array);
}
void validateBufferAndShape(InteropDataBuffer* dataBuffer, LongType * newShapeInfoCast, int index) {
bool errorFound = false;
std::string errorMessage;
//opaque/interop data buffers are created with int8 on purpose and therefore will be excluded from validation here.
//see more here: https://github.com/deeplearning4j/deeplearning4j/blob/8aa0ef12794ca40a2d00c5c80206a24a3bd6529c/nd4j/nd4j-backends/nd4j-backend-impls/nd4j-cpu-backend-common/src/main/java/org/nd4j/linalg/cpu/nativecpu/buffer/BaseCpuDataBuffer.java#L386
bool isString = ArrayOptions::dataType(newShapeInfoCast) == UTF8 || ArrayOptions::dataType(newShapeInfoCast) == UTF16 ||
ArrayOptions::dataType(newShapeInfoCast) == UTF32;
if(isString || shape::isEmptyConst(newShapeInfoCast) || dataBuffer->getDataBuffer()->getDataType() == INT8) return;
if (dataBuffer != nullptr) {
if (!shape::isEmptyConst(newShapeInfoCast)) {
if (dataBuffer->dataBuffer() != nullptr) {
//opaque/interop data buffers are created with int8 on purpose and therefore will be excluded from validation here.
//see more here: https://github.com/deeplearning4j/deeplearning4j/blob/8aa0ef12794ca40a2d00c5c80206a24a3bd6529c/nd4j/nd4j-backends/nd4j-backend-impls/nd4j-cpu-backend-common/src/main/java/org/nd4j/linalg/cpu/nativecpu/buffer/BaseCpuDataBuffer.java#L386
if (!isString && dataBuffer->getDataBuffer()->getDataType() != ArrayOptions::dataType(newShapeInfoCast)) {
errorMessage += "Data type mismatch between data buffer and shape buffer. ";
errorMessage += "Data buffer data type: " + DataTypeUtils::asString(dataBuffer->dataBuffer()->getDataType()) + ". ";
errorMessage += "Shape buffer data type: " + DataTypeUtils::asString(ArrayOptions::dataType(newShapeInfoCast)) + ". ";
errorFound = true;
}
if (!DataTypeUtils::validDataType(dataBuffer->dataBuffer()->getDataType())) {
errorMessage += "Invalid data type in data buffer. ";
errorFound = true;
}
} else {
errorMessage += "Data buffer is null. ";
errorFound = true;
}
if (!DataTypeUtils::validDataType(ArrayOptions::dataType(newShapeInfoCast))) {
errorMessage += "Invalid data type in shape buffer. ";
errorFound = true;
}
} else if (dataBuffer->dataBuffer() != nullptr && (dataBuffer->dataBuffer()->primary() != nullptr || dataBuffer->dataBuffer()->special() != nullptr)) {
errorMessage += "Shape Buffer at index " + std::to_string(index) + " is marked as empty but data buffer is not null! ";
errorFound = true;
}
}
if (errorFound) {
errorMessage += "Shape info: " + ShapeUtils::shapeAsString(newShapeInfoCast) + ". ";
errorMessage += "Data type: " + DataTypeUtils::asString(ArrayOptions::dataType(newShapeInfoCast)) + ". ";
if (dataBuffer->dataBuffer() != nullptr) {
errorMessage += "Data buffer: " + std::string(dataBuffer->dataBuffer()->primary() != nullptr ? "not null" : "null") + ". ";
errorMessage += "Special buffer: " + std::string(dataBuffer->dataBuffer()->special() != nullptr ? "not null" : "null") + ". ";
}
errorMessage += "Elements: ";
for(int i = 0; i < shape::shapeInfoLength(newShapeInfoCast); i++) {
errorMessage += std::to_string(newShapeInfoCast[i]) + ", ";
}
errorMessage += "\n";
THROW_EXCEPTION(errorMessage.c_str());
}
}
void Context::setTArguments(double *arguments, int numberOfArguments) {
_tArgs.clear();
_tArgs.reserve(numberOfArguments);
for (int e = 0; e < numberOfArguments; e++) _tArgs.push_back(arguments[e]);
if(Environment::getInstance().isDebug() || Environment::getInstance().isVerbose()) {
printf("float values set in context: ");
for (auto d : _bArgs) {
printf("%s\n, ", std::to_string(d).c_str());
}
fflush(stdout);
}
}
void Context::setIArguments(LongType *arguments, int numberOfArguments) {
_iArgs.clear();
_iArgs.reserve(numberOfArguments);
for (int e = 0; e < numberOfArguments; e++) _iArgs.push_back(arguments[e]);
if(Environment::getInstance().isDebug() || Environment::getInstance().isVerbose()) {
printf("int arguments set in context: ");
for (auto d : _bArgs) {
printf("%s\n, ", std::to_string(d).c_str());
}
fflush(stdout);
}
}
void Context::setBArguments(bool *arguments, int numberOfArguments) {
_bArgs.clear();
_bArgs.reserve(numberOfArguments);
for (int e = 0; e < numberOfArguments; e++) _bArgs.push_back(arguments[e]);
if(Environment::getInstance().isDebug() || Environment::getInstance().isVerbose()) {
printf("boolean types set in context: ");
for (auto d : _bArgs) {
printf("%s\n, ", std::to_string(d).c_str());
}
fflush(stdout);
}
}
void Context::setCudaContext(Pointer cudaStream, Pointer reductionPointer, Pointer allocationPointer) {
#ifdef SD_CUDA
_context = new LaunchContext(cudaStream, reductionPointer, allocationPointer);
// FIXME: either pass handle from outside, or make sure outside we use the same handle
_context->setCublasHandle(LaunchContext::defaultContext()->getCublasHandle());
for (auto v : _fastpath_out) v->setContext(_context);
for (auto v : _fastpath_in) v->setContext(_context);
#endif
}
void Context::allowHelpers(bool reallyAllow) { _helpersAllowed = reallyAllow; }
bool Context::helpersAllowed() { return _helpersAllowed; }
void Context::setTArguments(const std::vector<double> &tArgs) {
for (auto t : tArgs) _tArgs.emplace_back(t);
if(Environment::getInstance().isDebug() || Environment::getInstance().isVerbose()) {
printf("t argument types set in context: ");
for (auto d : _bArgs) {
printf("%s\n, ", std::to_string(d).c_str());
}
fflush(stdout);
}
}
void Context::setIArguments(const std::vector<LongType> &iArgs) {
for (auto i : iArgs) _iArgs.emplace_back(i);
if(Environment::getInstance().isDebug() || Environment::getInstance().isVerbose()) {
printf("int argument types set in context: ");
for (auto d : iArgs) {
printf("%s\n, ", std::to_string(d).c_str());
}
fflush(stdout);
}
}
void Context::setBArguments(const std::vector<bool> &bArgs) {
for (auto b : bArgs) _bArgs.push_back(b);
if(Environment::getInstance().isDebug() || Environment::getInstance().isVerbose()) {
printf("boolean types set in context: ");
for (auto d : _bArgs) {
printf("%s\n, ", std::to_string(d).c_str());
}
fflush(stdout);
}
}
void Context::setShapeFunctionOverride(bool reallyOverride) { _shapeFunctionOverride = reallyOverride; }
bool Context::shapeFunctionOverride() { return _shapeFunctionOverride; }
samediff::ExecutionMode Context::executionMode() { return _execMode; }
void Context::setExecutionMode(samediff::ExecutionMode executionMode) { _execMode = executionMode; }
bool Context::isTraining() { return _execMode == samediff::ExecutionMode::MODE_TRAINING; }
bool Context::isInference() { return _execMode == samediff::ExecutionMode::MODE_INFERENCE; }
void Context::setDArguments(DataType *arguments, int numberOfArguments) {
_dArgs.clear();
for (int e = 0; e < numberOfArguments; e++) _dArgs.emplace_back(arguments[e]);
if(Environment::getInstance().isDebug() || Environment::getInstance().isVerbose()) {
printf("data types set in context: ");
for (auto d : _dArgs) {
printf("%s\n, ", DataTypeUtils::asString(d).c_str());
}
fflush(stdout);
}
}
void Context::setDArguments(const std::vector<DataType> &dArgs) {
_dArgs.clear();
for (auto d : dArgs) _dArgs.emplace_back(d);
if(Environment::getInstance().isDebug() || Environment::getInstance().isVerbose()) {
printf("data types set in context: ");
for (auto d : dArgs) {
printf("%s\n, ", DataTypeUtils::asString(d).c_str());
}
fflush(stdout);
}
}
void Context::clearFastPath() {
_fastpath_in.clear();
_fastpath_out.clear();
// Delete arrays in _handles before clearing (fixes memory leak)
for (auto v : _handles) {
if (v != nullptr) delete v;
}
_handles.clear();
}
void Context::setInputArrays(int numArrays,NDArray** array, bool removable) {
for(int i = 0; i < numArrays; i++) {
setInputArray(i,array[i],removable);
}
}
void Context::setOutputArrays(int numArrays,NDArray** array, bool removable) {
for(int i = 0; i < numArrays; i++) {
setOutputArray(i,array[i],removable);
}
}
} // namespace graph
} // namespace sd