-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Computational graph uses two contiguous arrays of flyweight objects 1…
…2 bytes in total (FunctionObject), which serve as state machines and contain edges to previous operands.
- Loading branch information
1 parent
153059d
commit 6d7ed4a
Showing
13 changed files
with
1,476 additions
and
138 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
#include "tensor.h" | ||
#include "computational_graph_map.h" | ||
#include "m_algorithms_register.h" | ||
|
||
#include <assert.h> | ||
|
||
namespace NeuralNetwork { | ||
|
||
namespace Computation { | ||
|
||
|
||
namespace Graph { | ||
|
||
|
||
FunctionObject ComputationalGraphMap::_get_operation(TensorID my_tensor_id) noexcept { | ||
// u_int16_t my_tensor_id = _t->get_tensor_id(); | ||
|
||
assert(my_tensor_id > TensorID(0) && "Must be an op_id greater than 0."); | ||
assert(my_tensor_id <= tensor_id && "OP registry not this large"); | ||
// if (my_tensor_id >= tensor_id) throw std::invalid_argument("OP registry not this large."); | ||
return op_registry.at(my_tensor_id.get()); | ||
} | ||
|
||
std::shared_ptr<Tensor> ComputationalGraphMap::_get_tensor(TensorID my_tensor_id) noexcept { | ||
|
||
std::cout << "Get Tensor ID: " << my_tensor_id.get() << std::endl; | ||
|
||
assert(my_tensor_id > TensorID(0) && "Must be an op_id greater than 0."); | ||
assert(my_tensor_id <= tensor_id && "OP registry not this large"); | ||
|
||
return tensor_registry.at(my_tensor_id.get()); | ||
} | ||
|
||
|
||
|
||
|
||
|
||
void ComputationalGraphMap::_recover_tensor_id(TensorID my_tensor_id) noexcept { | ||
|
||
recovered_tensor_id.push(my_tensor_id); | ||
tensor_registry.at(my_tensor_id.get()) = nullptr; | ||
} | ||
|
||
|
||
|
||
TensorID ComputationalGraphMap::_obtain_tensor_id() noexcept { | ||
// Matrix::Operations::Utility::Stringify stringify; | ||
|
||
TensorID next_tensor_id = TensorID(0); | ||
|
||
if (!recovered_tensor_id.empty()){ | ||
next_tensor_id = recovered_tensor_id.top(); | ||
recovered_tensor_id.pop(); | ||
// auto fn = Matrix::Operations::Utility::Function::from(_get_operation(next_tensor_id).get_code()); | ||
// std::cout << "Recovered Registry: O[" << next_tensor_id << "]" << std::visit(stringify, fn) << std::endl; | ||
std::cout << "Recovered Registry: OP[" << next_tensor_id.get() << "]" << std::endl; | ||
} else { | ||
next_tensor_id = ++tensor_id; | ||
} | ||
return next_tensor_id; | ||
} | ||
|
||
|
||
TensorID ComputationalGraphMap::_register_operation(std::shared_ptr<Tensor> _t, FunctionObject& _node) noexcept { | ||
|
||
TensorID my_tensor_id = _t->get_tensor_id(); | ||
|
||
assert(my_tensor_id <= tensor_id && "OP registry not this large"); | ||
|
||
op_registry.at(my_tensor_id.get()) = _node; | ||
tensor_registry.at(my_tensor_id.get()) = _t; | ||
|
||
|
||
std::cout << "Updated Operation: OP[" << my_tensor_id.get() << "]" << std::endl; | ||
return my_tensor_id; | ||
} | ||
|
||
|
||
|
||
|
||
} | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,190 @@ | ||
#include "function_object_factory.h" | ||
#include "function_object.h" | ||
#include "computational_graph_map.h" | ||
#include "tensor.h" | ||
|
||
#include <optional> | ||
|
||
|
||
|
||
namespace NeuralNetwork { | ||
|
||
namespace Computation { | ||
|
||
namespace Graph { | ||
|
||
|
||
// std::optional<FunctionObject> DereferenceRegistry::from(RegisteredOperation _op) { | ||
// if (_op.get_tensor_id() == TensorID(0)) return {}; | ||
|
||
// ComputationalGraphMap& map = ComputationalGraphMap::get(); | ||
// return map._get_tensor(_op.get_tensor_id()); | ||
|
||
// } | ||
|
||
|
||
// void OperationFactory::create( | ||
// const Matrix::Operations::Code _typ, T _res, | ||
// TensorID _op, TensorID _op2) { | ||
|
||
|
||
|
||
// ComputationalGraphMap& map = ComputationalGraphMap::get(); | ||
|
||
// auto op = RegisteredOperation( | ||
// _typ, | ||
// _res->get_tensor_id(), | ||
// _op, | ||
// _op2 | ||
// ); | ||
|
||
// TensorID tensor_id = map._register_operation(_res, op); | ||
// op.result = tensor_id; | ||
// } | ||
|
||
|
||
/* | ||
Creates a Function Object signifying NOP expression. | ||
*/ | ||
FunctionObject FunctionObjectFactory::create(T _res) { | ||
|
||
ComputationalGraphMap& map = ComputationalGraphMap::get(); | ||
|
||
auto tensor_identification = _res->get_tensor_id(); | ||
|
||
auto fn_object = FunctionObject( | ||
RegisteredTensor(tensor_identification) | ||
); | ||
|
||
map._register_operation(_res, fn_object); | ||
|
||
return fn_object; | ||
} | ||
|
||
|
||
|
||
/* | ||
1) access _res NOP | ||
2) create Instantiate based on operation | ||
3) fill step 2 with TensorID of operands | ||
4) | ||
*/ | ||
|
||
template <Matrix::Operations::BinaryMatrixOperatable RegisteryType> | ||
FunctionObject FunctionObjectFactory::create( | ||
RegisteryType operation, T _res, | ||
TensorID _operand_id, TensorID _operand_id_two) { | ||
|
||
ComputationalGraphMap& map = ComputationalGraphMap::get(); | ||
|
||
auto res_tensor_id = _res->get_tensor_id(); | ||
|
||
auto fn_object = FunctionObject(); | ||
|
||
auto binaryRegistry = States::BinaryRegistered( | ||
RegisteredBinaryOperation(res_tensor_id, | ||
_operand_id, _operand_id_two) | ||
); | ||
|
||
auto instantiate_event = Events::Instantiate(operation, binaryRegistry); | ||
|
||
|
||
fn_object.process_event(instantiate_event); | ||
fn_object.stringify_type(); | ||
|
||
// transition _res default NOP state to unary-state | ||
// update computational graph OP state | ||
|
||
|
||
map._register_operation(_res, fn_object); | ||
|
||
return fn_object; | ||
} | ||
|
||
|
||
template <Matrix::Operations::UnaryMatrixOperatable RegisteryType> | ||
FunctionObject FunctionObjectFactory::create( | ||
RegisteryType operation, T _res, TensorID _operand_id) { | ||
|
||
ComputationalGraphMap& map = ComputationalGraphMap::get(); | ||
|
||
auto res_tensor_id = _res->get_tensor_id(); | ||
|
||
auto fn_object = FunctionObject(); | ||
|
||
auto unaryRegistry = States::UnaryRegistered( | ||
RegisteredUnaryOperation(res_tensor_id, _operand_id) | ||
); | ||
|
||
auto instantiate_event = Events::Instantiate(operation, unaryRegistry); | ||
|
||
fn_object.process_event(instantiate_event); | ||
fn_object.stringify_type(); | ||
|
||
// transition _res default NOP state to unary-state | ||
// update computational ~graph OP state | ||
|
||
map._register_operation(_res, fn_object); | ||
|
||
|
||
return fn_object; | ||
} | ||
|
||
|
||
template FunctionObject FunctionObjectFactory::create<Matrix::Operations::Unary::ReLU>( | ||
Matrix::Operations::Unary::ReLU operation, | ||
T _res, | ||
TensorID _operand_id); | ||
|
||
template FunctionObject FunctionObjectFactory::create<Matrix::Operations::Unary::SoftMax>( | ||
Matrix::Operations::Unary::SoftMax operation, | ||
T _res, | ||
TensorID _operand_id); | ||
|
||
template FunctionObject FunctionObjectFactory::create<Matrix::Operations::Binary::HadamardProduct::Std>( | ||
Matrix::Operations::Binary::HadamardProduct::Std operation, | ||
T _res, | ||
TensorID _operand_id, | ||
TensorID _operand_id_two); | ||
|
||
template FunctionObject FunctionObjectFactory::create<Matrix::Operations::Binary::Multiplication::ParallelDNC>( | ||
Matrix::Operations::Binary::Multiplication::ParallelDNC operation, | ||
T _res, | ||
TensorID _operand_id, | ||
TensorID _operand_id_two); | ||
|
||
template FunctionObject FunctionObjectFactory::create<Matrix::Operations::Binary::Multiplication::Naive>( | ||
Matrix::Operations::Binary::Multiplication::Naive operation, | ||
T _res, | ||
TensorID _operand_id, | ||
TensorID _operand_id_two); | ||
|
||
template FunctionObject FunctionObjectFactory::create<Matrix::Operations::Binary::Multiplication::Square>( | ||
Matrix::Operations::Binary::Multiplication::Square operation, | ||
T _res, | ||
TensorID _operand_id, | ||
TensorID _operand_id_two); | ||
|
||
template FunctionObject FunctionObjectFactory::create<Matrix::Operations::Binary::Addition::Std>( | ||
Matrix::Operations::Binary::Addition::Std operation, | ||
T _res, | ||
TensorID _operand_id, | ||
TensorID _operand_id_two); | ||
|
||
template FunctionObject FunctionObjectFactory::create<Matrix::Operations::Binary::OuterProduct::Naive>( | ||
Matrix::Operations::Binary::OuterProduct::Naive operation, | ||
T _res, | ||
TensorID _operand_id, | ||
TensorID _operand_id_two); | ||
|
||
template FunctionObject FunctionObjectFactory::create<Matrix::Operations::Metric::CrossEntropy>( | ||
Matrix::Operations::Metric::CrossEntropy operation, | ||
T _res, | ||
TensorID _operand_id, | ||
TensorID _operand_id_two); | ||
|
||
|
||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
#ifndef COMPUTATIONAL_GRAPH_MAP_H | ||
#define COMPUTATIONAL_GRAPH_MAP_H | ||
|
||
#include <memory> | ||
#include <stack> | ||
|
||
#include "strong_types.h" | ||
#include "m_algorithms_register.h" | ||
#include "function_object.h" | ||
|
||
|
||
namespace NeuralNetwork { | ||
|
||
namespace Computation { | ||
|
||
|
||
namespace Graph { | ||
|
||
class Tensor; | ||
|
||
/* | ||
DESCRIPTION: | ||
Singleton Mediator that holds the edges between Tensors | ||
and their registered operations. | ||
Organised as contiguous data structure, to avoid pointer | ||
chasing during runtime and help CPU's memory prefetcher | ||
load data before it's used. | ||
*/ | ||
class ComputationalGraphMap { | ||
|
||
public: | ||
static ComputationalGraphMap& get(){ | ||
static ComputationalGraphMap map; | ||
return map; | ||
} | ||
ComputationalGraphMap(ComputationalGraphMap const&) = delete; | ||
ComputationalGraphMap(ComputationalGraphMap&&) = delete; | ||
ComputationalGraphMap& operator=(ComputationalGraphMap const&) = delete; | ||
ComputationalGraphMap& operator=(ComputationalGraphMap &&) = delete; | ||
|
||
void _recover_tensor_id(TensorID my_tensor_id) noexcept; | ||
std::shared_ptr<Tensor> _get_tensor(TensorID my_tensor_id) noexcept; | ||
FunctionObject _get_operation(TensorID my_tensor_id) noexcept; | ||
TensorID _obtain_tensor_id() noexcept; | ||
TensorID _register_operation(std::shared_ptr<Tensor> _t, FunctionObject& _node) noexcept; | ||
|
||
|
||
protected: | ||
ComputationalGraphMap() : | ||
op_registry(2000), | ||
tensor_registry(2000), | ||
recovered_tensor_id(), | ||
tensor_id(0) {} | ||
|
||
|
||
private: | ||
std::vector<FunctionObject> op_registry; | ||
std::vector<std::shared_ptr<Tensor>> tensor_registry; | ||
std::stack<TensorID> recovered_tensor_id; | ||
TensorID tensor_id; | ||
|
||
|
||
}; | ||
|
||
|
||
|
||
} | ||
|
||
} | ||
|
||
} | ||
|
||
|
||
#endif // COMPUTATIONAL_GRAPH_MAP_H |
Oops, something went wrong.