forked from jiuyuan/InfiniTensor
feat: 整理子项目结构,实现一部分导入
Signed-off-by: YdrMaster <ydrml@hotmail.com>
This commit is contained in:
parent
9cfe223953
commit
cc62a3216d
|
@ -62,6 +62,7 @@ endif()
|
|||
include_directories(include)
|
||||
|
||||
add_subdirectory(optimization)
|
||||
include_directories(optimization/include)
|
||||
|
||||
# Pybind11
|
||||
add_subdirectory(3rd-party/pybind11)
|
||||
|
|
|
@ -5,4 +5,4 @@
|
|||
|
||||
namespace infini {
|
||||
void start_interpreter();
|
||||
} // namespace infini
|
||||
} // namespace infini
|
||||
|
|
|
@ -4,6 +4,8 @@ project(optimization LANGUAGES CXX C)
|
|||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "$ENV{CMAKE_CXX_FLAGS} -fPIC")
|
||||
|
||||
file(GLOB_RECURSE SRC src/*.h src/*.cc src/*.cpp)
|
||||
add_library(optimization ${SRC})
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../src/mutation.h"
|
|
@ -4,6 +4,8 @@
|
|||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
namespace optimization {
|
||||
|
||||
/// @brief Stores tensor data。
|
||||
struct Data {
|
||||
/// @brief `cpu_data` is stored in the memory space,
|
||||
|
@ -28,3 +30,5 @@ struct Data {
|
|||
return ans;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace optimization
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "data_type.h"
|
||||
|
||||
using namespace optimization;
|
||||
|
||||
size_t DataType::size() const {
|
||||
switch (id) {
|
||||
case DataTypeId::FLOAT:
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
namespace optimization {
|
||||
|
||||
enum class DataTypeId : uint8_t {
|
||||
UNDEFINED,
|
||||
FLOAT,
|
||||
|
@ -41,3 +43,5 @@ template <> inline DataType ty<bool>() { return {DataTypeId::BOOL}; }
|
|||
template <> inline DataType ty<double>() { return {DataTypeId::DOUBLE}; }
|
||||
template <> inline DataType ty<uint32_t>() { return {DataTypeId::UINT32}; }
|
||||
template <> inline DataType ty<uint64_t>() { return {DataTypeId::UINT64}; }
|
||||
|
||||
} // namespace optimization
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "graph.h"
|
||||
|
||||
using namespace optimization;
|
||||
|
||||
static size_t GRAPH_ID = 1;
|
||||
|
||||
Unigraph::Unigraph() : id(GRAPH_ID++) {}
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
#include "op_type.h"
|
||||
#include "tensor.h"
|
||||
|
||||
namespace optimization {
|
||||
|
||||
/// @brief a struct to represent an operator in the computation graph.
|
||||
/// The ownership of an `Operator` belongs to one `Unigraph`.
|
||||
struct Operator {
|
||||
|
@ -49,3 +51,5 @@ struct Unigraph {
|
|||
Vec<Arc<Tensor>> outputs //
|
||||
);
|
||||
};
|
||||
|
||||
} // namespace optimization
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
#include "mutation.h"
|
||||
#include <unordered_set>
|
||||
|
||||
Vec<std::pair<Unigraph, SingleOperator>> split_each(Unigraph &&g) {
|
||||
using namespace optimization;
|
||||
|
||||
Vec<std::pair<Unigraph, SingleOperator>>
|
||||
optimization::split_each(Unigraph &&g) {
|
||||
Vec<std::pair<Unigraph, SingleOperator>> ans;
|
||||
for (auto &op : g.operators) {
|
||||
auto &[g, t] = ans.emplace_back();
|
||||
|
@ -10,7 +13,7 @@ Vec<std::pair<Unigraph, SingleOperator>> split_each(Unigraph &&g) {
|
|||
return ans;
|
||||
}
|
||||
|
||||
float memory_usage(Unigraph const &g) {
|
||||
float optimization::memory_usage(Unigraph const &g) {
|
||||
std::unordered_set<size_t> mark;
|
||||
uintptr_t memory;
|
||||
for (const auto &op : g.operators)
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
#include "graph.h"
|
||||
#include <functional>
|
||||
|
||||
namespace optimization {
|
||||
|
||||
/// @brief A candidate subgraph mutant.
|
||||
struct Mutant {
|
||||
/// @brief The mutated subgraph.
|
||||
|
@ -165,3 +167,5 @@ template <class t> Vec<size_t> list_size(Vec<SubGraph<t>> const &list) {
|
|||
[](const auto &e) { return e.mutants.size(); });
|
||||
return ans;
|
||||
}
|
||||
|
||||
} // namespace optimization
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
#include <cstdint>
|
||||
|
||||
namespace optimization {
|
||||
|
||||
enum class OpType : uint16_t {
|
||||
Abs,
|
||||
Acos,
|
||||
|
@ -190,3 +192,5 @@ enum class OpType : uint16_t {
|
|||
Where,
|
||||
Xor,
|
||||
};
|
||||
|
||||
} // namespace optimization
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include "tensor.h"
|
||||
#include <numeric>
|
||||
|
||||
using namespace optimization;
|
||||
|
||||
Arc<Tensor> Tensor::share(Vec<size_t> shape, DataType data_type, Data data) {
|
||||
return Arc<Tensor>(
|
||||
new Tensor(std::move(shape), std::move(data_type), std::move(data)));
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace optimization {
|
||||
|
||||
/// @brief Defines a template alias for `std::vector`.
|
||||
template <class t> using Vec = std::vector<t>;
|
||||
|
||||
|
@ -45,6 +47,25 @@ struct Tensor {
|
|||
/// @return A `shared_ptr<Tensor>`.
|
||||
static Arc<Tensor> share(Vec<size_t> shape, DataType data_type, Data data);
|
||||
|
||||
/// @brief A static factory method to create a `shared_ptr<Tensor>` with
|
||||
/// single data.
|
||||
/// @tparam t Data type.
|
||||
/// @param val Data value.
|
||||
/// @return A `shared_ptr<Tensor>`.
|
||||
template <class t> static Arc<Tensor> share_single(t val) {
|
||||
return Tensor::share({1}, ty<t>(), Data::cpu<t>({val}));
|
||||
}
|
||||
|
||||
/// @brief A static factory method to create a `shared_ptr<Tensor>` with
|
||||
/// 1D data.
|
||||
/// @tparam t Data type.
|
||||
/// @param val Data value.
|
||||
/// @return A `shared_ptr<Tensor>`.
|
||||
template <class t> static Arc<Tensor> share_vec(Vec<t> val) {
|
||||
return Tensor::share({val.size()}, ty<t>(),
|
||||
Data::cpu<t>(std::move(val)));
|
||||
}
|
||||
|
||||
/// @brief Calculates the size of the tensor in bytes.
|
||||
/// @return Memory usage in bytes.
|
||||
size_t size() const;
|
||||
|
@ -53,3 +74,5 @@ struct Tensor {
|
|||
/// @brief Constructor is private and only accessible by the factory method.
|
||||
Tensor(Vec<size_t> &&, DataType &&, Data &&);
|
||||
};
|
||||
|
||||
} // namespace optimization
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#include <iostream>
|
||||
#include <unordered_set>
|
||||
|
||||
using namespace optimization;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
Unigraph g;
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
#include "core/graph.h"
|
||||
#include "operators/concat.h"
|
||||
#include "operators/conv.h"
|
||||
#include "operators/gather.h"
|
||||
#include "operators/unary.h"
|
||||
#include "optimization/common.h"
|
||||
#include <algorithm>
|
||||
#include <queue>
|
||||
|
||||
|
@ -114,13 +119,262 @@ bool GraphObj::topo_sort() {
|
|||
return this->sorted = true;
|
||||
}
|
||||
|
||||
optimization::DataType cast(DataType ty) {
|
||||
#define IT(A, B) \
|
||||
if (ty == DataType::A) \
|
||||
return {optimization::DataTypeId::B};
|
||||
|
||||
IT(Float32, FLOAT) //
|
||||
else IT(UInt32, UINT32) //
|
||||
else IT(UInt8, UINT8) //
|
||||
else IT(Int8, INT8) //
|
||||
else IT(UInt16, UINT16) //
|
||||
else IT(Int16, INT16) //
|
||||
else IT(Int32, INT32) //
|
||||
else IT(Int64, INT64) //
|
||||
else IT_ASSERT(false, "unsupported data type");
|
||||
|
||||
#undef IT
|
||||
}
|
||||
|
||||
optimization::OpType cast(OpType ty) {
|
||||
#define IT(A, B) \
|
||||
case OpType::A: \
|
||||
return optimization::OpType::B
|
||||
|
||||
switch (ty) {
|
||||
IT(Abs, Abs);
|
||||
IT(Add, Add);
|
||||
IT(And, And);
|
||||
IT(AvgPool, AveragePool);
|
||||
IT(BatchNorm, BatchNormalization);
|
||||
IT(Cast, Cast);
|
||||
IT(Clip, Clip);
|
||||
IT(Concat, Concat);
|
||||
IT(Conv, Conv);
|
||||
IT(ConvTrans, ConvTranspose);
|
||||
IT(Cos, Cos);
|
||||
IT(Div, Div);
|
||||
IT(Dropout, Dropout);
|
||||
IT(Erf, Erf);
|
||||
IT(Exp, Exp);
|
||||
IT(Flatten, Flatten);
|
||||
IT(Gather, Gather);
|
||||
IT(Identity, Identity);
|
||||
IT(Log, Log);
|
||||
IT(Matmul, MatMul);
|
||||
IT(MaxPool, MaxPool);
|
||||
IT(Mul, Mul);
|
||||
IT(Neg, Neg);
|
||||
IT(Not, Not);
|
||||
IT(Or, Or);
|
||||
IT(PRelu, PRelu);
|
||||
IT(Pad, Pad);
|
||||
IT(Pow, Pow);
|
||||
IT(ReduceMean, ReduceMean);
|
||||
IT(Relu, Relu);
|
||||
IT(Reshape, Reshape);
|
||||
IT(Resize, Resize);
|
||||
IT(Shape, Shape);
|
||||
IT(Sigmoid, Sigmoid);
|
||||
IT(Sin, Sin);
|
||||
IT(SinH, Sinh);
|
||||
IT(Slice, Slice);
|
||||
IT(Softmax, Softmax);
|
||||
IT(Split, Split);
|
||||
IT(Sqrt, Sqrt);
|
||||
IT(Sub, Sub);
|
||||
IT(Tan, Tan);
|
||||
IT(TanH, Tanh);
|
||||
IT(Transpose, Transpose);
|
||||
IT(Xor, Xor);
|
||||
default:
|
||||
IT_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
#undef IT
|
||||
}
|
||||
|
||||
void GraphObj::optimize() {
|
||||
for (auto &op : ops) {
|
||||
namespace opt = optimization;
|
||||
|
||||
topo_sort();
|
||||
|
||||
#define I(PTR) reinterpret_cast<uintptr_t>((PTR).get())
|
||||
|
||||
unordered_map<uintptr_t, opt::Arc<opt::Tensor>> tensors;
|
||||
for (const auto &t : this->getTensors()) {
|
||||
const auto dims = t->getDims();
|
||||
opt::Vec<size_t> shape(dims.size());
|
||||
std::transform(dims.begin(), dims.end(), shape.begin(),
|
||||
[](auto x) { return static_cast<size_t>(x); });
|
||||
|
||||
opt::Data data{};
|
||||
if (t->hasData()) {
|
||||
auto origin = t->getDataBlob();
|
||||
data.cpu_data.resize(t->getBytes());
|
||||
memcpy(data.cpu_data.data(), origin->getPtr<uint8_t *>(),
|
||||
data.cpu_data.size());
|
||||
}
|
||||
tensors[I(t)] =
|
||||
opt::Tensor::share(shape, cast(t->getDType()), std::move(data));
|
||||
}
|
||||
|
||||
opt::Unigraph ans;
|
||||
|
||||
for (const auto &op : this->getOperators()) {
|
||||
const auto inputs = op->getInputs(), outputs = op->getOutputs();
|
||||
opt::Vec<opt::Arc<opt::Tensor>> in(inputs.size()), out(outputs.size());
|
||||
std::transform(inputs.begin(), inputs.end(), in.begin(),
|
||||
[&](auto x) { return tensors[I(x)]; });
|
||||
std::transform(outputs.begin(), outputs.end(), out.begin(),
|
||||
[&](auto x) { return tensors[I(x)]; });
|
||||
switch (op->getOpType()) {
|
||||
case OpType::Abs:
|
||||
ans.push_operator(opt::OpType::Abs, std::move(in), std::move(out));
|
||||
break;
|
||||
case OpType::ACos:
|
||||
ans.push_operator(opt::OpType::Acos, std::move(in), std::move(out));
|
||||
break;
|
||||
case OpType::ACosH:
|
||||
ans.push_operator(opt::OpType::Acosh, std::move(in),
|
||||
std::move(out));
|
||||
break;
|
||||
case OpType::Add:
|
||||
ans.push_operator(opt::OpType::Add, std::move(in), std::move(out));
|
||||
break;
|
||||
case OpType::And:
|
||||
ans.push_operator(opt::OpType::And, std::move(in), std::move(out));
|
||||
break;
|
||||
case OpType::ASin:
|
||||
ans.push_operator(opt::OpType::Asin, std::move(in), std::move(out));
|
||||
break;
|
||||
case OpType::ASinH:
|
||||
ans.push_operator(opt::OpType::Asinh, std::move(in),
|
||||
std::move(out));
|
||||
break;
|
||||
case OpType::ATan:
|
||||
ans.push_operator(opt::OpType::Atan, std::move(in), std::move(out));
|
||||
break;
|
||||
case OpType::ATanH:
|
||||
ans.push_operator(opt::OpType::Atanh, std::move(in),
|
||||
std::move(out));
|
||||
break;
|
||||
case OpType::AvgPool:
|
||||
ans.push_operator(opt::OpType::AveragePool, std::move(in),
|
||||
std::move(out));
|
||||
break;
|
||||
case OpType::BatchNorm:
|
||||
ans.push_operator(opt::OpType::BatchNormalization, std::move(in),
|
||||
std::move(out));
|
||||
break;
|
||||
case OpType::BitLeftShift:
|
||||
in.push_back(opt::Tensor::share_single<uint8_t>(0));
|
||||
ans.push_operator(opt::OpType::BitShift, std::move(in),
|
||||
std::move(out));
|
||||
break;
|
||||
case OpType::BitRightShift:
|
||||
in.push_back(opt::Tensor::share_single<uint8_t>(1));
|
||||
ans.push_operator(opt::OpType::BitShift, std::move(in),
|
||||
std::move(out));
|
||||
break;
|
||||
case OpType::BitAnd:
|
||||
ans.push_operator(opt::OpType::BitwiseAnd, std::move(in),
|
||||
std::move(out));
|
||||
break;
|
||||
case OpType::BitNot:
|
||||
ans.push_operator(opt::OpType::BitwiseNot, std::move(in),
|
||||
std::move(out));
|
||||
break;
|
||||
case OpType::BitOr:
|
||||
ans.push_operator(opt::OpType::BitwiseOr, std::move(in),
|
||||
std::move(out));
|
||||
break;
|
||||
case OpType::BitXor:
|
||||
ans.push_operator(opt::OpType::BitwiseXor, std::move(in),
|
||||
std::move(out));
|
||||
break;
|
||||
case OpType::Cast:
|
||||
ans.push_operator(opt::OpType::Cast, std::move(in), std::move(out));
|
||||
break;
|
||||
case OpType::Ceil:
|
||||
ans.push_operator(opt::OpType::Ceil, std::move(in), std::move(out));
|
||||
break;
|
||||
case OpType::Clip: {
|
||||
auto obj = as<ClipObj>(op);
|
||||
auto min = obj->getMin();
|
||||
auto max = obj->getMax();
|
||||
in.push_back(
|
||||
opt::Tensor::share_single<float>(min ? *min : -INFINITY));
|
||||
in.push_back(
|
||||
opt::Tensor::share_single<float>(max ? *max : INFINITY));
|
||||
ans.push_operator(opt::OpType::Clip, std::move(in), std::move(out));
|
||||
} break;
|
||||
case OpType::Concat:
|
||||
in.push_back(
|
||||
opt::Tensor::share_single<int>(as<ConcatObj>(op)->getDim()));
|
||||
ans.push_operator(opt::OpType::Concat, std::move(in),
|
||||
std::move(out));
|
||||
break;
|
||||
case OpType::Conv: {
|
||||
auto obj = as<ConvObj>(op);
|
||||
in.push_back(opt::Tensor::share_vec<size_t>(
|
||||
{(size_t)obj->getDh(), (size_t)obj->getDw()}));
|
||||
in.push_back(opt::Tensor::share_vec<size_t>(
|
||||
{(size_t)obj->getPh(), (size_t)obj->getPw()}));
|
||||
in.push_back(opt::Tensor::share_vec<size_t>(
|
||||
{(size_t)obj->getSh(), (size_t)obj->getSw()}));
|
||||
ans.push_operator(opt::OpType::Conv, std::move(in), std::move(out));
|
||||
} break;
|
||||
case OpType::Cos:
|
||||
ans.push_operator(opt::OpType::Cos, std::move(in), std::move(out));
|
||||
break;
|
||||
case OpType::CosH:
|
||||
ans.push_operator(opt::OpType::Cosh, std::move(in), std::move(out));
|
||||
break;
|
||||
case OpType::Div:
|
||||
ans.push_operator(opt::OpType::Div, std::move(in), std::move(out));
|
||||
break;
|
||||
case OpType::Dropout:
|
||||
ans.push_operator(opt::OpType::Dropout, std::move(in),
|
||||
std::move(out));
|
||||
break;
|
||||
case OpType::Exp:
|
||||
ans.push_operator(opt::OpType::Exp, std::move(in), std::move(out));
|
||||
break;
|
||||
case OpType::Flatten:
|
||||
ans.push_operator(opt::OpType::Flatten, std::move(in),
|
||||
std::move(out));
|
||||
break;
|
||||
case OpType::Floor:
|
||||
ans.push_operator(opt::OpType::Floor, std::move(in),
|
||||
std::move(out));
|
||||
break;
|
||||
case OpType::Gather:
|
||||
in.push_back(
|
||||
opt::Tensor::share_single<int>(as<GatherObj>(op)->getAxis()));
|
||||
ans.push_operator(opt::OpType::Gather, std::move(in),
|
||||
std::move(out));
|
||||
break;
|
||||
case OpType::GreaterThan:
|
||||
ans.push_operator(opt::OpType::Greater, std::move(in),
|
||||
std::move(out));
|
||||
break;
|
||||
case OpType::GreaterEqual:
|
||||
ans.push_operator(opt::OpType::GreaterOrEqual, std::move(in),
|
||||
std::move(out));
|
||||
break;
|
||||
case OpType::Identity:
|
||||
ans.push_operator(opt::OpType::Identity, std::move(in),
|
||||
std::move(out));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#undef I
|
||||
}
|
||||
|
||||
void GraphObj::dataMalloc() {
|
||||
|
@ -191,7 +445,8 @@ void GraphObj::replaceConnection(Tensor oldTensor, Tensor newTensor,
|
|||
// tensor's "source" and "target" must be in "ops".
|
||||
// tensor has no "source" and no "target" must not exist.
|
||||
// "inputs" or "outputs" of operators must be in "tensors"
|
||||
// "predecessors" and "successors" of an operator of "ops" must be in "ops".
|
||||
// "predecessors" and "successors" of an operator of "ops" must be in
|
||||
// "ops".
|
||||
bool GraphObj::checkValid() const {
|
||||
for (auto tensor : tensors) {
|
||||
IT_ASSERT(!(tensor->getTargets().size() == 0 &&
|
||||
|
|
Loading…
Reference in New Issue