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
@@ -0,0 +1,121 @@
/* ******************************************************************************
*
*
* 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
//
#ifndef ND4J_GRAPH_PROFILE_H
#define ND4J_GRAPH_PROFILE_H
#include <chrono>
#include <map>
#include <string>
#include <vector>
#include "NodeProfile.h"
namespace sd {
namespace graph {
class SD_LIB_EXPORT GraphProfile {
private:
// this variable
LongType _merges = 1L;
/**
* This is global memory values
*/
LongType _memoryTotal = 0L;
LongType _memoryActivations = 0L;
LongType _memoryTemporary = 0L;
LongType _memoryObjects = 0L;
// time spent for graph construction
LongType _buildTime = 0L;
// time spent for graph execution
LongType _executionTime = 0L;
// collection of pointers to profile results
std::vector<NodeProfile *> _profiles;
std::map<int, NodeProfile *> _profilesById;
// collection of various timing reports
std::map<std::string, LongType> _timings;
std::chrono::time_point<std::chrono::system_clock> _last;
std::map<std::string, std::chrono::time_point<std::chrono::system_clock>> _timers;
void updateLast();
public:
GraphProfile();
~GraphProfile();
/**
* These methods just adding amount of bytes to various counters
*/
void addToTotal(LongType bytes);
void addToActivations(LongType bytes);
void addToTemporary(LongType bytes);
void addToObjects(LongType bytes);
/**
* This method allows to set graph construction (i.e. deserialization) time in nanoseconds
*/
void setBuildTime(LongType nanos);
/**
* This method sets graph execution time in nanoseconds.
*/
void setExecutionTime(LongType nanos);
void startEvent(const char *name);
void recordEvent(const char *name);
void deleteEvent(const char *name);
/**
* This method saves time as delta from last saved time
*/
void spotEvent(const char *name);
/**
* This method returns pointer to NodeProfile by ID
* PLEASE NOTE: this method will create new NodeProfile if there's none
*/
NodeProfile *nodeById(int id, const char *name = nullptr);
bool nodeExists(int id);
/**
* This method merges values from other profile report
* @param other
*/
void merge(GraphProfile *other);
void assign(GraphProfile *other);
/**
* These methods are just utility methods for time
*/
static LongType currentTime();
static LongType relativeTime(LongType time);
void printOut();
};
} // namespace graph
} // namespace sd
#endif
@@ -0,0 +1,39 @@
/* ******************************************************************************
*
*
* 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
******************************************************************************/
//
// Created by raver119 on 21.02.18.
//
#ifndef LIBND4J_GRAPHPROFILINGHELPER_H
#define LIBND4J_GRAPHPROFILINGHELPER_H
#include <graph/Graph.h>
#include "GraphProfile.h"
namespace sd {
namespace graph {
class GraphProfilingHelper {
public:
static GraphProfile* profile(Graph* graph, int iterations);
};
} // namespace graph
} // namespace sd
#endif // LIBND4J_GRAPHPROFILINGHELPER_H
@@ -0,0 +1,114 @@
/* ******************************************************************************
*
*
* 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
//
#ifndef LIBND4J_NODE_PROFILE_H
#define LIBND4J_NODE_PROFILE_H
#include <system/common.h>
#include <string>
#include <vector>
namespace sd {
namespace graph {
class SD_LIB_EXPORT NodeProfile {
private:
int _id;
std::string _name;
LongType _merges = 1L;
// time spent during deserialization
LongType _buildTime = 0L;
// time spent before op execution
LongType _preparationTime = 0L;
// time spent for op execution
LongType _executionTime = 0L;
// total time spent during node execution
LongType _totalTime = 0L;
// time spent for output shape creation
LongType _shapeTime = 0L;
// time spent for output arrays creation
LongType _arrayTime = 0L;
LongType _inputTime = 0L;
// amount of memory used for outputs
LongType _memoryActivations = 0L;
// amount of memory used internally for temporary arrays
LongType _memoryTemporary = 0L;
// amount of memory used internally for objects
LongType _memoryObjects = 0L;
// total amount of memory used during execution
LongType _memoryTotal = 0L;
std::vector<std::string> _inputShapes;
std::vector<std::string> _outputShapes;
public:
NodeProfile() = default;
~NodeProfile() = default;
explicit NodeProfile(int id, const char* name);
void setBuildTime(LongType time);
void setPreparationTime(LongType time);
void setExecutionTime(LongType time);
void setTotalTime(LongType time);
void setShapeFunctionTime(LongType time);
void setArrayTime(LongType time);
void setInputTime(LongType time);
void setActivationsSize(LongType bytes);
void setTemporarySize(LongType bytes);
void setObjectsSize(LongType bytes);
void setTotalSize(LongType bytes);
void addInputShape(LongType const* shapeInfo);
void addOutputShape(LongType const* shapeInfo);
LongType getActivationsSize() const;
LongType getTemporarySize() const;
LongType getObjectsSize() const;
LongType getTotalSize() const;
LongType getExecutionTime() const;
std::string& name();
void merge(NodeProfile* other);
void assign(NodeProfile* other);
void printOut();
};
} // namespace graph
} // namespace sd
#endif
@@ -0,0 +1,194 @@
/* ******************************************************************************
*
*
* 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 <graph/profiling/GraphProfile.h>
#include <helpers/logger.h>
#include <math/templatemath.h>
#include <algorithm>
#include <chrono>
namespace sd {
namespace graph {
GraphProfile::GraphProfile() { updateLast(); }
GraphProfile::~GraphProfile() {
// releasing NodeProfile pointers
for (auto v : _profiles) delete v;
_timings.clear();
}
void GraphProfile::addToTotal(LongType bytes) { _memoryTotal += bytes; }
void GraphProfile::addToActivations(LongType bytes) { _memoryActivations += bytes; }
void GraphProfile::addToTemporary(LongType bytes) { _memoryTemporary += bytes; }
void GraphProfile::addToObjects(LongType bytes) { _memoryObjects += bytes; }
void GraphProfile::setBuildTime(LongType nanos) { _buildTime = nanos; }
void GraphProfile::setExecutionTime(LongType nanos) { _executionTime = nanos; }
LongType GraphProfile::currentTime() {
auto t = std::chrono::system_clock::now();
auto v = std::chrono::time_point_cast<std::chrono::nanoseconds>(t);
auto epoch = v.time_since_epoch();
return (LongType)std::chrono::duration_cast<std::chrono::nanoseconds>(epoch).count();
}
LongType GraphProfile::relativeTime(LongType time) {
auto t1 = currentTime();
return t1 - time;
}
void GraphProfile::updateLast() { _last = std::chrono::system_clock::now(); }
void GraphProfile::startEvent(const char *name) {
std::string k = name;
_timers[k] = std::chrono::system_clock::now();
}
void GraphProfile::recordEvent(const char *name) {
std::string k = name;
if (_timers.count(k) == 0) {
sd_printf("Can't find timer key: [%s]", name);
THROW_EXCEPTION("Missing timer key");
}
auto t0 = _timers[k];
auto t1 = std::chrono::system_clock::now();
auto v = (LongType)std::chrono::duration_cast<std::chrono::nanoseconds>(t1 - t0).count();
_timings[k] = v;
_timers.erase(k);
}
void GraphProfile::deleteEvent(const char *name) {
std::string k = name;
_timers.erase(k);
}
void GraphProfile::spotEvent(const char *name) {
auto t = std::chrono::system_clock::now();
auto d = (LongType)std::chrono::duration_cast<std::chrono::nanoseconds>(t - _last).count();
std::string k = name;
_timings[k] = d;
updateLast();
}
NodeProfile *GraphProfile::nodeById(int id, const char *name) {
if (_profilesById.count(id) == 0) {
auto node = new NodeProfile(id, name);
_profiles.emplace_back(node);
_profilesById[id] = node;
return node;
}
return _profilesById[id];
}
void GraphProfile::merge(GraphProfile *other) {
_merges += other->_merges;
_memoryActivations += other->_memoryActivations;
_memoryTemporary += other->_memoryTemporary;
_memoryTotal += other->_memoryTotal;
_memoryObjects += other->_memoryObjects;
_executionTime += other->_executionTime;
_buildTime += other->_buildTime;
for (auto v : _profilesById) {
if (!other->nodeExists(v.first)) continue;
v.second->merge(other->nodeById(v.first));
}
}
void GraphProfile::assign(GraphProfile *other) {
_merges = other->_merges;
_memoryActivations = other->_memoryActivations;
_memoryTemporary = other->_memoryTemporary;
_memoryTotal = other->_memoryTotal;
_memoryObjects = other->_memoryObjects;
_executionTime = other->_executionTime;
_buildTime = other->_buildTime;
for (auto v : other->_profilesById) {
nodeById(v.first, v.second->name().c_str())->assign(v.second);
}
}
bool GraphProfile::nodeExists(int id) { return _profilesById.count(id) > 0; }
void GraphProfile::printOut() {
sd_printf("Graph profile: %i executions\n", _merges);
sd_printf("\nMemory:\n", "");
LongType tmp = 0L;
LongType obj = 0L;
LongType act = 0L;
LongType ttl = 0L;
for (auto v : _profiles) {
tmp += v->getTemporarySize();
obj += v->getObjectsSize();
act += v->getActivationsSize();
ttl += v->getTotalSize();
}
sd_printf("ACT: %lld; TMP: %lld; OBJ: %lld; TTL: %lld;\n", act / _merges, tmp / _merges, obj / _merges,
ttl / _merges);
sd_printf("\nTime:\n", "");
sd_printf("Construction time: %lld ns;\n", _buildTime / _merges);
sd_printf("Execution time: %lld ns;\n", _executionTime / _merges);
sd_printf("\nPer-node reports:\n", "");
if (_profiles.empty()) sd_printf("No nodes in graph\n", "");
// printint out stuff
std::vector<NodeProfile *> sorted;
for (auto v : _profiles) {
v->printOut();
sorted.emplace_back(v);
}
if (_profiles.size() > 1) {
// building hot spots
std::sort(sorted.begin(), sorted.end(), [](const NodeProfile *a, const NodeProfile *b) -> bool {
return a->getExecutionTime() > b->getExecutionTime();
});
sd_printf("\nTop 50 reports by EXEC:\n", "");
auto limit = sd::math::sd_min<int>(50, sorted.size());
for (int e = 0; e < limit; e++) {
sorted[e]->printOut();
}
}
sd_printf("\nSpecial timers:\n", "");
if (_timings.empty()) sd_printf("No special timers were set\n", "");
for (auto v : _timings) sd_printf("%s: %lld ns;\n", v.first.c_str(), v.second);
}
} // namespace graph
} // namespace sd
@@ -0,0 +1,68 @@
/* ******************************************************************************
*
*
* 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
******************************************************************************/
//
// Created by raver119 on 21.02.18.
//
#include <graph/GraphExecutioner.h>
#include <graph/profiling/GraphProfilingHelper.h>
namespace sd {
namespace graph {
GraphProfile *GraphProfilingHelper::profile(Graph *graph, int iterations) {
// saving original workspace
auto varSpace = graph->getVariableSpace()->clone();
// printing out graph structure
// warm up
for (int e = 0; e < iterations; e++) {
FlowPath fp;
auto _vs = varSpace->clone();
_vs->setFlowPath(&fp);
GraphExecutioner::execute(graph, _vs);
delete _vs;
}
auto profile = new GraphProfile();
for (int e = 0; e < iterations; e++) {
FlowPath fp;
// we're always starting from "fresh" varspace here
auto _vs = varSpace->clone();
//_vs->workspace()->expandTo(100000);
_vs->setFlowPath(&fp);
GraphExecutioner::execute(graph, _vs);
auto p = fp.profile();
if (e == 0)
profile->assign(p);
else
profile->merge(p);
delete _vs;
}
delete varSpace;
return profile;
}
} // namespace graph
} // namespace sd
@@ -0,0 +1,133 @@
/* ******************************************************************************
*
*
* 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 <graph/profiling/NodeProfile.h>
#include <helpers/ShapeUtils.h>
#include <helpers/logger.h>
namespace sd {
namespace graph {
NodeProfile::NodeProfile(int id, const char *name) {
_id = id;
if (name != nullptr) _name = name;
};
void NodeProfile::printOut() {
sd_printf("Node: <%i:%s>\n", _id, _name.c_str());
sd_printf(" Memory: ACT: %lld; TMP: %lld; OBJ: %lld; TTL: %lld;\n", _memoryActivations / _merges,
_memoryTemporary / _merges, _memoryObjects / _merges, _memoryTotal / _merges);
sd_printf(" Time: PREP: %lld ns; EXEC: %lld ns; TTL: %lld ns;\n", _preparationTime / _merges,
_executionTime / _merges, _totalTime / _merges);
sd_printf(" PREP: INPUT: %lld ns; SHAPE: %lld ns; ARRAY: %lld ns;\n", _inputTime / _merges, _shapeTime / _merges,
_arrayTime / _merges);
std::string inputs;
std::string outputs;
int cnt = 0;
for (const auto &v : _inputShapes) inputs += v + " ";
for (const auto &v : _outputShapes) outputs += v + " ";
sd_printf(" Inputs: %s\n", inputs.c_str());
sd_printf(" Outputs: %s\n", outputs.c_str());
};
LongType NodeProfile::getActivationsSize() const { return _memoryActivations; }
void NodeProfile::setShapeFunctionTime(LongType time) { _shapeTime = time; }
void NodeProfile::setArrayTime(LongType time) { _arrayTime = time; }
void NodeProfile::setInputTime(LongType time) { _inputTime = time; }
LongType NodeProfile::getTemporarySize() const { return _memoryTemporary; }
LongType NodeProfile::getObjectsSize() const { return _memoryObjects; }
LongType NodeProfile::getTotalSize() const { return _memoryTotal; }
void NodeProfile::setBuildTime(LongType time) { _buildTime = time; }
void NodeProfile::setPreparationTime(LongType time) { _preparationTime = time; }
void NodeProfile::setExecutionTime(LongType time) { _executionTime = time; }
void NodeProfile::setTotalTime(LongType time) { _totalTime = time; }
void NodeProfile::setActivationsSize(LongType bytes) { _memoryActivations = bytes; }
void NodeProfile::setTemporarySize(LongType bytes) { _memoryTemporary = bytes; }
void NodeProfile::setObjectsSize(LongType bytes) { _memoryObjects = bytes; }
void NodeProfile::setTotalSize(LongType bytes) { _memoryTotal = bytes; }
LongType NodeProfile::getExecutionTime() const { return _executionTime; }
void NodeProfile::addInputShape(LongType const *shapeInfo) {
_inputShapes.emplace_back(ShapeUtils::shapeInfoAsString(shapeInfo));
}
void NodeProfile::addOutputShape(LongType const *shapeInfo) {
_outputShapes.emplace_back(ShapeUtils::shapeInfoAsString(shapeInfo));
}
void NodeProfile::merge(NodeProfile *other) {
_merges += other->_merges;
_memoryObjects += other->_memoryObjects;
_memoryActivations += other->_memoryActivations;
_memoryTemporary += other->_memoryTemporary;
_memoryTotal += other->_memoryTotal;
_preparationTime += other->_preparationTime;
_executionTime += other->_executionTime;
_totalTime += other->_totalTime;
_shapeTime += other->_shapeTime;
_arrayTime += other->_arrayTime;
_inputTime += other->_inputTime;
_inputShapes = other->_inputShapes;
_outputShapes = other->_outputShapes;
}
std::string &NodeProfile::name() { return _name; }
void NodeProfile::assign(NodeProfile *other) {
_merges = other->_merges;
_memoryObjects = other->_memoryObjects;
_memoryActivations = other->_memoryActivations;
_memoryTemporary = other->_memoryTemporary;
_memoryTotal = other->_memoryTotal;
_preparationTime = other->_preparationTime;
_executionTime = other->_executionTime;
_totalTime = other->_totalTime;
_shapeTime = other->_shapeTime;
_arrayTime = other->_arrayTime;
_inputTime = other->_inputTime;
_inputShapes = other->_inputShapes;
_outputShapes = other->_outputShapes;
}
} // namespace graph
} // namespace sd