Commit 6961353d authored by Robert Kimball's avatar Robert Kimball

tests pass

parent 6d43129f
...@@ -106,6 +106,7 @@ if (NGRAPH_CPU_ENABLE AND LLVM_INCLUDE_DIR AND ...@@ -106,6 +106,7 @@ if (NGRAPH_CPU_ENABLE AND LLVM_INCLUDE_DIR AND
set(SRC ${SRC} set(SRC ${SRC}
codegen/code_writer.cpp codegen/code_writer.cpp
codegen/compiler.cpp codegen/compiler.cpp
codegen/execution_engine.cpp
runtime/cpu/call_frame.cpp runtime/cpu/call_frame.cpp
runtime/cpu/cpu_backend.cpp runtime/cpu/cpu_backend.cpp
runtime/cpu/cpu_manager.cpp runtime/cpu/cpu_manager.cpp
......
This diff is collapsed.
...@@ -27,7 +27,7 @@ namespace ngraph ...@@ -27,7 +27,7 @@ namespace ngraph
namespace codegen namespace codegen
{ {
class module; class module;
class execution_state; class Compiler;
class HeaderCache; class HeaderCache;
} }
} }
...@@ -45,41 +45,24 @@ private: ...@@ -45,41 +45,24 @@ private:
std::unique_ptr<llvm::Module> m_module; std::unique_ptr<llvm::Module> m_module;
}; };
class ngraph::codegen::execution_state : public llvm::SectionMemoryManager class ngraph::codegen::Compiler : public llvm::SectionMemoryManager
{ {
public: public:
execution_state(); Compiler();
~execution_state(); ~Compiler();
void set_precompiled_headers_enabled(bool state) { precompiled_headers_enabled = state; } void set_precompiled_headers_enabled(bool state) { m_precompiled_headers_enabled = state; }
bool is_precompiled_headers_enabled() { return precompiled_headers_enabled; } bool is_precompiled_headers_enabled() { return m_precompiled_headers_enabled; }
void set_debuginfo_enabled(bool state) { debuginfo_enabled = state; } void set_debuginfo_enabled(bool state) { m_debuginfo_enabled = state; }
bool is_debuginfo_enabled() { return debuginfo_enabled; } bool is_debuginfo_enabled() { return m_debuginfo_enabled; }
std::unique_ptr<llvm::Module> compile(const std::string& source, const std::string& name = ""); std::unique_ptr<llvm::Module> compile(const std::string& source);
bool add_module(std::unique_ptr<llvm::Module>&);
void finalize();
template <typename ftype>
std::function<ftype> find_function(const std::string& func_name)
{
auto f = m_execution_engine->getPointerToNamedFunction(func_name);
return f_cast<ftype>(f);
}
private: private:
llvm::ExecutionEngine* m_execution_engine; std::unique_ptr<clang::CompilerInstance> m_compiler;
std::string jit_error; bool m_precompiled_headers_enabled;
bool precompiled_headers_enabled; bool m_debuginfo_enabled;
bool debuginfo_enabled; std::string m_source_name;
template <typename signature>
std::function<signature> f_cast(void* f)
{
return static_cast<signature*>(reinterpret_cast<signature*>(f));
}
bool is_version_number(const std::string& path); bool is_version_number(const std::string& path);
void add_header_search_path(clang::HeaderSearchOptions& hso, const std::string& path); void add_header_search_path(clang::HeaderSearchOptions& hso, const std::string& path);
void use_cached_files(std::unique_ptr<clang::CompilerInstance>& Clang); void use_cached_files(std::unique_ptr<clang::CompilerInstance>& Clang);
......
// ----------------------------------------------------------------------------
// 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 <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
#include "ngraph/codegen/execution_engine.hpp"
using namespace ngraph;
codegen::ExecutionEngine::ExecutionEngine()
: m_execution_engine{nullptr}
{
}
codegen::ExecutionEngine::~ExecutionEngine()
{
}
bool codegen::ExecutionEngine::add_module(std::unique_ptr<llvm::Module>& module)
{
if (module)
{
if (!m_execution_engine)
{
m_execution_engine = llvm::EngineBuilder(move(module))
.setEngineKind(llvm::EngineKind::JIT)
.setOptLevel(llvm::CodeGenOpt::Aggressive)
.setErrorStr(&m_jit_error)
.create();
if (!m_execution_engine)
{
return false;
}
}
}
else
{
return false;
}
return true;
}
void codegen::ExecutionEngine::finalize()
{
if (m_execution_engine)
{
m_execution_engine->finalizeObject();
m_execution_engine->runStaticConstructorsDestructors(false);
}
else
{
throw std::runtime_error(
"Error in finalize: " +
(m_jit_error.empty() ? "Could not create an execution engine" : m_jit_error));
}
}
// ----------------------------------------------------------------------------
// 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 <memory>
#include <llvm/ExecutionEngine/MCJIT.h> // forces JIT to link in
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
#include <llvm/Option/Arg.h>
namespace ngraph
{
namespace codegen
{
class ExecutionEngine;
}
}
class ngraph::codegen::ExecutionEngine
{
public:
ExecutionEngine();
~ExecutionEngine();
bool add_module(std::unique_ptr<llvm::Module>& module);
void finalize();
template <typename ftype>
std::function<ftype> find_function(const std::string& func_name)
{
auto f = m_execution_engine->getPointerToNamedFunction(func_name);
return f_cast<ftype>(f);
}
private:
llvm::ExecutionEngine* m_execution_engine;
std::string m_jit_error;
template <typename signature>
std::function<signature> f_cast(void* f)
{
return static_cast<signature*>(reinterpret_cast<signature*>(f));
}
};
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include <memory> #include <memory>
#include "ngraph/codegen/compiler.hpp" #include "ngraph/codegen/execution_engine.hpp"
#include "ngraph/runtime/manager.hpp" #include "ngraph/runtime/manager.hpp"
namespace ngraph namespace ngraph
...@@ -33,7 +33,7 @@ namespace ngraph ...@@ -33,7 +33,7 @@ namespace ngraph
class CPUManager : public Manager class CPUManager : public Manager
{ {
protected: protected:
ngraph::codegen::execution_state exec_state; ngraph::codegen::ExecutionEngine exec_state;
public: public:
virtual std::shared_ptr<Backend> allocate_backend() override; virtual std::shared_ptr<Backend> allocate_backend() override;
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "ngraph/codegen/code_writer.hpp" #include "ngraph/codegen/code_writer.hpp"
#include "ngraph/codegen/compiler.hpp" #include "ngraph/codegen/compiler.hpp"
#include "ngraph/codegen/execution_engine.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"
#include "ngraph/descriptor/output.hpp" #include "ngraph/descriptor/output.hpp"
...@@ -314,24 +315,25 @@ using namespace ngraph::runtime::cpu::eigen; ...@@ -314,24 +315,25 @@ using namespace ngraph::runtime::cpu::eigen;
out << code; out << code;
out.close(); out.close();
ngraph::codegen::execution_state estate; codegen::Compiler compiler;
codegen::ExecutionEngine execution_engine;
#if NGCPU_PCH #if NGCPU_PCH
estate.set_precompiled_headers_enabled(true); compiler.set_precompiled_headers_enabled(true);
#endif #endif
#if NGCPU_DEBUGINFO #if NGCPU_DEBUGINFO
estate.set_debuginfo_enabled(true); compiler.set_debuginfo_enabled(true);
#endif #endif
auto llvm_module = estate.compile(code, function_name + "_codegen.cpp"); auto llvm_module = compiler.compile(code);
if (llvm_module == nullptr) if (llvm_module == nullptr)
{ {
throw runtime_error("function failed to compile"); throw runtime_error("function failed to compile");
} }
estate.add_module(llvm_module); execution_engine.add_module(llvm_module);
estate.finalize(); execution_engine.finalize();
m_compiled_function = estate.find_function<EntryPoint_t>(function_name); m_compiled_function = execution_engine.find_function<EntryPoint_t>(function_name);
assert(m_compiled_function); assert(m_compiled_function);
m_is_compiled = true; m_is_compiled = true;
......
...@@ -19,23 +19,26 @@ ...@@ -19,23 +19,26 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "ngraph/codegen/compiler.hpp" #include "ngraph/codegen/compiler.hpp"
#include "ngraph/codegen/execution_engine.hpp"
using namespace std; using namespace std;
using namespace ngraph;
TEST(codegen, simple_return) TEST(codegen, simple_return)
{ {
constexpr auto name = "test.cpp";
constexpr auto source = R"(extern "C" int test() { return 2+5; })"; constexpr auto source = R"(extern "C" int test() { return 2+5; })";
ngraph::codegen::execution_state estate; codegen::Compiler compiler;
auto module = estate.compile(source, name); codegen::ExecutionEngine execution_engine;
auto module = compiler.compile(source);
ASSERT_NE(nullptr, module); ASSERT_NE(nullptr, module);
estate.add_module(module); execution_engine.add_module(module);
estate.finalize(); execution_engine.finalize();
auto func = estate.find_function<int()>("test"); auto func = execution_engine.find_function<int()>("test");
ASSERT_NE(nullptr, func); ASSERT_NE(nullptr, func);
int result = func(); int result = func();
...@@ -44,18 +47,19 @@ TEST(codegen, simple_return) ...@@ -44,18 +47,19 @@ TEST(codegen, simple_return)
TEST(codegen, pass_args) TEST(codegen, pass_args)
{ {
constexpr auto name = "test.cpp";
constexpr auto source = R"(extern "C" int test(int a, int b) { return a+b; })"; constexpr auto source = R"(extern "C" int test(int a, int b) { return a+b; })";
ngraph::codegen::execution_state estate; codegen::Compiler compiler;
auto module = estate.compile(source, name); codegen::ExecutionEngine execution_engine;
auto module = compiler.compile(source);
ASSERT_NE(nullptr, module); ASSERT_NE(nullptr, module);
estate.add_module(module); execution_engine.add_module(module);
estate.finalize(); execution_engine.finalize();
auto func = estate.find_function<int(int, int)>("test"); auto func = execution_engine.find_function<int(int, int)>("test");
ASSERT_NE(nullptr, func); ASSERT_NE(nullptr, func);
int result = func(20, 22); int result = func(20, 22);
...@@ -64,7 +68,6 @@ TEST(codegen, pass_args) ...@@ -64,7 +68,6 @@ TEST(codegen, pass_args)
TEST(codegen, include) TEST(codegen, include)
{ {
constexpr auto name = "test.cpp";
constexpr auto source = constexpr auto source =
R"( R"(
#include <cmath> #include <cmath>
...@@ -74,15 +77,17 @@ TEST(codegen, include) ...@@ -74,15 +77,17 @@ TEST(codegen, include)
} }
)"; )";
ngraph::codegen::execution_state estate; codegen::Compiler compiler;
auto module = estate.compile(source, name); codegen::ExecutionEngine execution_engine;
auto module = compiler.compile(source);
ASSERT_NE(nullptr, module); ASSERT_NE(nullptr, module);
estate.add_module(module); execution_engine.add_module(module);
estate.finalize(); execution_engine.finalize();
auto func = estate.find_function<int(int, int)>("test"); auto func = execution_engine.find_function<int(int, int)>("test");
ASSERT_NE(nullptr, func); ASSERT_NE(nullptr, func);
int result = func(20, 2); int result = func(20, 2);
......
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