Commit b556db1f authored by Robert Kimball's avatar Robert Kimball

add codewriter

parent 00125a23
...@@ -104,6 +104,7 @@ if (NGRAPH_CPU_ENABLE AND LLVM_INCLUDE_DIR AND ...@@ -104,6 +104,7 @@ if (NGRAPH_CPU_ENABLE AND LLVM_INCLUDE_DIR AND
# Add sources for the CPU backend # Add sources for the CPU backend
# and all its dependencies # and all its dependencies
set(SRC ${SRC} set(SRC ${SRC}
codegen/code_writer.cpp
codegen/compiler.cpp codegen/compiler.cpp
runtime/cpu/call_frame.cpp runtime/cpu/call_frame.cpp
runtime/cpu/cpu_backend.cpp runtime/cpu/cpu_backend.cpp
......
// ----------------------------------------------------------------------------
// Copyright 2017 Nervana Systems Inc.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// 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
// ----------------------------------------------------------------------------
#include "code_writer.hpp"
using namespace std;
using namespace ngraph;
codegen::CodeWriter::CodeWriter()
: indent(0)
, m_pending_indent(true)
{
}
string codegen::CodeWriter::get_code() const
{
return m_ss.str();
}
void codegen::CodeWriter::operator+=(const std::string& s)
{
*this << s;
}
// ----------------------------------------------------------------------------
// Copyright 2017 Nervana Systems Inc.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// 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
// ----------------------------------------------------------------------------
#pragma once
#include <sstream>
#include <string>
#include "ngraph/log.hpp"
namespace ngraph
{
namespace codegen
{
class CodeWriter;
}
}
class ngraph::codegen::CodeWriter
{
public:
CodeWriter();
std::string get_code() const;
void operator+=(const std::string&);
size_t indent;
template <typename T>
friend CodeWriter& operator<<(CodeWriter& out, const T& obj)
{
std::stringstream ss;
ss << obj;
for (char c : ss.str())
{
if (c == '\n')
{
out.m_pending_indent = true;
}
else
{
if (out.m_pending_indent)
{
out.m_pending_indent = false;
for (size_t i = 0; i < out.indent; i++)
{
out.m_ss << " ";
}
}
}
out.m_ss << c;
}
return out;
}
private:
std::stringstream m_ss;
bool m_pending_indent;
};
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "ngraph/codegen/code_writer.hpp"
#include "ngraph/node.hpp" #include "ngraph/node.hpp"
#include "ngraph/runtime/cpu/external_function.hpp" #include "ngraph/runtime/cpu/external_function.hpp"
#include "ngraph/runtime/tensor_view_info.hpp" #include "ngraph/runtime/tensor_view_info.hpp"
...@@ -37,14 +38,15 @@ namespace ngraph ...@@ -37,14 +38,15 @@ namespace ngraph
class Emitter class Emitter
{ {
protected: protected:
std::string TU; codegen::CodeWriter TU;
public: public:
Emitter() Emitter()
: TU("") : TU()
{ {
} }
std::string& GetTU() { return TU; } std::string get_code() { return TU.get_code(); }
codegen::CodeWriter& get_code_writer() { return TU; }
void EMITTER_DECL(EmitNop); void EMITTER_DECL(EmitNop);
void EMITTER_DECL(EmitAdd); void EMITTER_DECL(EmitAdd);
void EMITTER_DECL(EmitDot); void EMITTER_DECL(EmitDot);
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <typeinfo> #include <typeinfo>
#include <unordered_map> #include <unordered_map>
#include "ngraph/codegen/code_writer.hpp"
#include "ngraph/codegen/compiler.hpp" #include "ngraph/codegen/compiler.hpp"
#include "ngraph/descriptor/input.hpp" #include "ngraph/descriptor/input.hpp"
#include "ngraph/descriptor/layout/dense_tensor_view_layout.hpp" #include "ngraph/descriptor/layout/dense_tensor_view_layout.hpp"
...@@ -78,6 +79,25 @@ using namespace ngraph::runtime::cpu; ...@@ -78,6 +79,25 @@ using namespace ngraph::runtime::cpu;
using ngraph::descriptor::layout::DenseTensorViewLayout; using ngraph::descriptor::layout::DenseTensorViewLayout;
extern "C" void
allocate_aligned_buffer(size_t size, size_t alignment, char** allocated, char** aligned_ptr)
{
size_t allocation_size = size + alignment;
*allocated = new char[allocation_size];
*aligned_ptr = *allocated;
size_t mod = size_t(*aligned_ptr) % alignment;
if (mod != 0)
{
(*aligned_ptr) += (alignment - mod);
}
}
extern "C" void free_aligned_buffer(void* allocated)
{
free(allocated);
}
#define TI(x) type_index(typeid(x)) #define TI(x) type_index(typeid(x))
static const OpMap dispatcher{ static const OpMap dispatcher{
...@@ -202,7 +222,7 @@ void ExternalFunction::compile(FunctionMap& function_map) ...@@ -202,7 +222,7 @@ void ExternalFunction::compile(FunctionMap& function_map)
// Now we build the TU // Now we build the TU
Emitter emitter; Emitter emitter;
auto& TU = emitter.GetTU(); codegen::CodeWriter& TU = emitter.get_code_writer();
TU += R"(// Generated by the NGraph CPU backend TU += R"(// Generated by the NGraph CPU backend
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
...@@ -258,7 +278,8 @@ extern "C" void __entrypoint(ngraph::runtime::cpu::CallFrame* call_frame, ...@@ -258,7 +278,8 @@ extern "C" void __entrypoint(ngraph::runtime::cpu::CallFrame* call_frame,
// TODO: Cleanup and make this a utility function // TODO: Cleanup and make this a utility function
ofstream out("__ngcpu_codegen.cpp"); ofstream out("__ngcpu_codegen.cpp");
out << TU; string code = TU.get_code();
out << code;
out.close(); out.close();
ngraph::codegen::execution_state estate; ngraph::codegen::execution_state estate;
...@@ -271,7 +292,7 @@ extern "C" void __entrypoint(ngraph::runtime::cpu::CallFrame* call_frame, ...@@ -271,7 +292,7 @@ extern "C" void __entrypoint(ngraph::runtime::cpu::CallFrame* call_frame,
estate.set_debuginfo_enabled(true); estate.set_debuginfo_enabled(true);
#endif #endif
auto llvm_module = estate.compile(TU, "__ngcpu_codegen.cpp"); auto llvm_module = estate.compile(code, "__ngcpu_codegen.cpp");
assert(llvm_module); assert(llvm_module);
estate.add_module(llvm_module); estate.add_module(llvm_module);
estate.finalize(); estate.finalize();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment