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
# Add sources for the CPU backend
# and all its dependencies
set(SRC ${SRC}
codegen/code_writer.cpp
codegen/compiler.cpp
runtime/cpu/call_frame.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 @@
#include <string>
#include <vector>
#include "ngraph/codegen/code_writer.hpp"
#include "ngraph/node.hpp"
#include "ngraph/runtime/cpu/external_function.hpp"
#include "ngraph/runtime/tensor_view_info.hpp"
......@@ -37,14 +38,15 @@ namespace ngraph
class Emitter
{
protected:
std::string TU;
codegen::CodeWriter TU;
public:
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(EmitAdd);
void EMITTER_DECL(EmitDot);
......
......@@ -20,6 +20,7 @@
#include <typeinfo>
#include <unordered_map>
#include "ngraph/codegen/code_writer.hpp"
#include "ngraph/codegen/compiler.hpp"
#include "ngraph/descriptor/input.hpp"
#include "ngraph/descriptor/layout/dense_tensor_view_layout.hpp"
......@@ -78,6 +79,25 @@ using namespace ngraph::runtime::cpu;
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))
static const OpMap dispatcher{
......@@ -202,7 +222,7 @@ void ExternalFunction::compile(FunctionMap& function_map)
// Now we build the TU
Emitter emitter;
auto& TU = emitter.GetTU();
codegen::CodeWriter& TU = emitter.get_code_writer();
TU += R"(// Generated by the NGraph CPU backend
#include <algorithm>
#include <cmath>
......@@ -258,7 +278,8 @@ extern "C" void __entrypoint(ngraph::runtime::cpu::CallFrame* call_frame,
// TODO: Cleanup and make this a utility function
ofstream out("__ngcpu_codegen.cpp");
out << TU;
string code = TU.get_code();
out << code;
out.close();
ngraph::codegen::execution_state estate;
......@@ -271,7 +292,7 @@ extern "C" void __entrypoint(ngraph::runtime::cpu::CallFrame* call_frame,
estate.set_debuginfo_enabled(true);
#endif
auto llvm_module = estate.compile(TU, "__ngcpu_codegen.cpp");
auto llvm_module = estate.compile(code, "__ngcpu_codegen.cpp");
assert(llvm_module);
estate.add_module(llvm_module);
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