Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
N
ngraph
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
ngraph
Commits
0ef1c2f9
Unverified
Commit
0ef1c2f9
authored
Nov 16, 2017
by
Jai Menon
Committed by
GitHub
Nov 16, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #243 from NervanaSystems/bob/static_compiler
Bob/static compiler
parents
7b9b35d3
1ac8d820
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
853 additions
and
672 deletions
+853
-672
CMakeLists.txt
src/ngraph/CMakeLists.txt
+2
-0
compiler.cpp
src/ngraph/codegen/compiler.cpp
+186
-84
compiler.hpp
src/ngraph/codegen/compiler.hpp
+52
-26
execution_engine.cpp
src/ngraph/codegen/execution_engine.cpp
+70
-0
execution_engine.hpp
src/ngraph/codegen/execution_engine.hpp
+57
-0
file_util.cpp
src/ngraph/file_util.cpp
+72
-35
file_util.hpp
src/ngraph/file_util.hpp
+15
-14
cpu_kernels.hpp
src/ngraph/runtime/cpu/cpu_kernels.hpp
+1
-1
cpu_manager.hpp
src/ngraph/runtime/cpu/cpu_manager.hpp
+2
-2
eigen_utils.hpp
src/ngraph/runtime/cpu/eigen_utils.hpp
+2
-3
emitter.cpp
src/ngraph/runtime/cpu/emitter.cpp
+207
-415
emitter.hpp
src/ngraph/runtime/cpu/emitter.hpp
+9
-0
external_function.cpp
src/ngraph/runtime/cpu/external_function.cpp
+49
-64
memory_handler.cpp
src/ngraph/runtime/cpu/memory_handler.cpp
+43
-0
memory_handler.hpp
src/ngraph/runtime/cpu/memory_handler.hpp
+41
-0
tensor_view.cpp
src/ngraph/runtime/cpu/tensor_view.cpp
+20
-8
tensor_view.hpp
src/ngraph/runtime/cpu/tensor_view.hpp
+2
-2
codegen.cpp
test/codegen.cpp
+23
-18
No files found.
src/ngraph/CMakeLists.txt
View file @
0ef1c2f9
...
...
@@ -106,12 +106,14 @@ if (NGRAPH_CPU_ENABLE AND LLVM_INCLUDE_DIR AND
set
(
SRC
${
SRC
}
codegen/code_writer.cpp
codegen/compiler.cpp
codegen/execution_engine.cpp
runtime/cpu/call_frame.cpp
runtime/cpu/cpu_backend.cpp
runtime/cpu/cpu_manager.cpp
runtime/cpu/cpu_kernels.cpp
runtime/cpu/emitter.cpp
runtime/cpu/external_function.cpp
runtime/cpu/memory_handler.cpp
runtime/cpu/tensor_view.cpp
)
# LLVM binary builds are typically built without RTTI
...
...
src/ngraph/codegen/compiler.cpp
View file @
0ef1c2f9
...
...
@@ -45,13 +45,15 @@
#include <clang/Frontend/TextDiagnosticPrinter.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
#include "ngraph/codegen/compiler.hpp"
#include "ngraph/file_util.hpp"
#include "ngraph/log.hpp"
#include "ngraph/util.hpp"
// TODO: Fix leaks
// #define USE_CACHE
using
namespace
clang
;
using
namespace
llvm
;
using
namespace
llvm
::
opt
;
...
...
@@ -59,26 +61,36 @@ using namespace std;
using
namespace
ngraph
::
codegen
;
static
std
::
string
GetExecutablePath
(
const
char
*
Argv0
)
static
HeaderCache
s_header_cache
;
static
StaticCompiler
s_static_compiler
;
static
std
::
mutex
m_mutex
;
Compiler
::
Compiler
()
{
// This just needs to be some symbol in the binary; C++ doesn't
// allow taking the address of ::main however.
void
*
MainAddr
=
reinterpret_cast
<
void
*>
(
GetExecutablePath
);
return
llvm
::
sys
::
fs
::
getMainExecutable
(
Argv0
,
MainAddr
);
}
execution_state
::
execution_state
()
:
m_execution_engine
{
nullptr
}
,
precompiled_headers_enabled
(
false
)
,
debuginfo_enabled
(
false
)
Compiler
::~
Compiler
()
{
}
execution_state
::~
execution_state
(
)
std
::
unique_ptr
<
llvm
::
Module
>
Compiler
::
compile
(
const
std
::
string
&
source
)
{
lock_guard
<
mutex
>
lock
(
m_mutex
);
return
s_static_compiler
.
compile
(
source
);
}
std
::
unique_ptr
<
llvm
::
Module
>
execution_state
::
compile
(
const
string
&
source
,
const
string
&
name
)
static
std
::
string
GetExecutablePath
(
const
char
*
Argv0
)
{
// This just needs to be some symbol in the binary; C++ doesn't
// allow taking the address of ::main however.
void
*
MainAddr
=
reinterpret_cast
<
void
*>
(
GetExecutablePath
);
return
llvm
::
sys
::
fs
::
getMainExecutable
(
Argv0
,
MainAddr
);
}
StaticCompiler
::
StaticCompiler
()
:
m_precompiled_headers_enabled
(
false
)
,
m_debuginfo_enabled
(
false
)
,
m_source_name
(
"code.cpp"
)
{
llvm
::
InitializeAllTargets
();
llvm
::
InitializeAllTargetMCs
();
...
...
@@ -87,7 +99,7 @@ std::unique_ptr<llvm::Module> execution_state::compile(const string& source, con
// Prepare compilation arguments
vector
<
const
char
*>
args
;
args
.
push_back
(
name
.
c_str
());
args
.
push_back
(
m_source_
name
.
c_str
());
// Prepare DiagnosticEngine
DiagnosticOptions
DiagOpts
;
...
...
@@ -97,45 +109,76 @@ std::unique_ptr<llvm::Module> execution_state::compile(const string& source, con
new
DiagnosticsEngine
(
pDiagIDs
,
&
DiagOpts
,
textDiagPrinter
);
// Create and initialize CompilerInstance
std
::
unique_ptr
<
CompilerInstance
>
Clang
(
new
CompilerInstance
());
Clang
->
createDiagnostics
();
m_compiler
=
std
::
unique_ptr
<
CompilerInstance
>
(
new
CompilerInstance
());
m_compiler
->
createDiagnostics
();
// Initialize CompilerInvocation
CompilerInvocation
::
CreateFromArgs
(
Clang
->
getInvocation
(),
&
args
[
0
],
&
args
[
0
]
+
args
.
size
(),
*
pDiagnosticsEngine
);
m_compiler
->
getInvocation
(),
&
args
[
0
],
&
args
[
0
]
+
args
.
size
(),
*
pDiagnosticsEngine
);
// Infer the builtin include path if unspecified.
if
(
Clang
->
getHeaderSearchOpts
().
UseBuiltinIncludes
&&
Clang
->
getHeaderSearchOpts
().
ResourceDir
.
empty
())
if
(
m_compiler
->
getHeaderSearchOpts
().
UseBuiltinIncludes
&&
m_compiler
->
getHeaderSearchOpts
().
ResourceDir
.
empty
())
{
void
*
MainAddr
=
reinterpret_cast
<
void
*>
(
GetExecutablePath
);
auto
path
=
CompilerInvocation
::
GetResourcesPath
(
args
[
0
],
MainAddr
);
Clang
->
getHeaderSearchOpts
().
ResourceDir
=
path
;
m_compiler
->
getHeaderSearchOpts
().
ResourceDir
=
path
;
}
auto
&
HSO
=
Clang
->
getInvocation
().
getHeaderSearchOpts
();
// Add base toolchain-supplied header paths
// Ideally one would use the Linux toolchain definition in clang/lib/Driver/ToolChains.h
// But that's a private header and isn't part of the public libclang API
// Instead of re-implementing all of that functionality in a custom toolchain
// just hardcode the paths relevant to frequently used build/test machines for now
HSO
.
AddPath
(
CLANG_BUILTIN_HEADERS_PATH
,
clang
::
frontend
::
System
,
false
,
false
);
HSO
.
AddPath
(
"/usr/include/x86_64-linux-gnu"
,
clang
::
frontend
::
System
,
false
,
false
);
HSO
.
AddPath
(
"/usr/include"
,
clang
::
frontend
::
System
,
false
,
false
);
// Add C++ standard library headers
// Debian-like + GCC 4.8 libstdc++
HSO
.
AddPath
(
"/usr/include/x86_64-linux-gnu/c++/4.8"
,
clang
::
frontend
::
System
,
false
,
false
);
HSO
.
AddPath
(
"/usr/include/c++/4.8"
,
clang
::
frontend
::
System
,
false
,
false
);
// Debian-like + GCC 5 libstdc++
HSO
.
AddPath
(
"/usr/include/x86_64-linux-gnu/c++/5"
,
clang
::
frontend
::
System
,
false
,
false
);
HSO
.
AddPath
(
"/usr/include/c++/5"
,
clang
::
frontend
::
System
,
false
,
false
);
HSO
.
AddPath
(
EIGEN_HEADERS_PATH
,
clang
::
frontend
::
System
,
false
,
false
);
HSO
.
AddPath
(
NGRAPH_HEADERS_PATH
,
clang
::
frontend
::
System
,
false
,
false
);
if
(
s_header_cache
.
is_valid
()
==
false
)
{
// Add base toolchain-supplied header paths
// Ideally one would use the Linux toolchain definition in clang/lib/Driver/ToolChains.h
// But that's a private header and isn't part of the public libclang API
// Instead of re-implementing all of that functionality in a custom toolchain
// just hardcode the paths relevant to frequently used build/test machines for now
add_header_search_path
(
CLANG_BUILTIN_HEADERS_PATH
);
add_header_search_path
(
"/usr/include/x86_64-linux-gnu"
);
add_header_search_path
(
"/usr/include"
);
// Search for headers in
// /usr/include/x86_64-linux-gnu/c++/N.N
// /usr/include/c++/N.N
// and add them to the header search path
file_util
::
iterate_files
(
"/usr/include/x86_64-linux-gnu/c++/"
,
[
&
](
const
std
::
string
&
file
,
bool
is_dir
)
{
if
(
is_dir
)
{
string
dir_name
=
file_util
::
get_file_name
(
file
);
if
(
is_version_number
(
dir_name
))
{
add_header_search_path
(
file
);
}
}
});
file_util
::
iterate_files
(
"/usr/include/c++/"
,
[
&
](
const
std
::
string
&
file
,
bool
is_dir
)
{
if
(
is_dir
)
{
string
dir_name
=
file_util
::
get_file_name
(
file
);
if
(
is_version_number
(
dir_name
))
{
add_header_search_path
(
file
);
}
}
});
add_header_search_path
(
EIGEN_HEADERS_PATH
);
add_header_search_path
(
NGRAPH_HEADERS_PATH
);
#ifdef USE_CACHE
s_header_cache
.
set_valid
();
#endif
}
#ifdef USE_CACHE
use_cached_files
(
m_compiler
);
#endif
// Language options
// These are the C++ features needed to compile ngraph headers
// and any dependencies like Eigen
auto
LO
=
Clang
->
getInvocation
().
getLangOpts
();
auto
LO
=
m_compiler
->
getInvocation
().
getLangOpts
();
LO
->
CPlusPlus
=
1
;
LO
->
CPlusPlus11
=
1
;
LO
->
Bool
=
1
;
...
...
@@ -148,7 +191,7 @@ std::unique_ptr<llvm::Module> execution_state::compile(const string& source, con
LO
->
OpenMPUseTLS
=
1
;
// CodeGen options
auto
&
CGO
=
Clang
->
getInvocation
().
getCodeGenOpts
();
auto
&
CGO
=
m_compiler
->
getInvocation
().
getCodeGenOpts
();
CGO
.
OptimizationLevel
=
3
;
CGO
.
RelocationModel
=
"static"
;
CGO
.
ThreadModel
=
"posix"
;
...
...
@@ -158,22 +201,22 @@ std::unique_ptr<llvm::Module> execution_state::compile(const string& source, con
CGO
.
VectorizeSLP
=
1
;
CGO
.
CXAAtExit
=
0
;
if
(
debuginfo_enabled
)
if
(
m_
debuginfo_enabled
)
{
CGO
.
setDebugInfo
(
codegenoptions
::
FullDebugInfo
);
}
if
(
precompiled_headers_enabled
)
if
(
m_
precompiled_headers_enabled
)
{
// Preprocessor options
auto
&
PPO
=
Clang
->
getInvocation
().
getPreprocessorOpts
();
auto
&
PPO
=
m_compiler
->
getInvocation
().
getPreprocessorOpts
();
PPO
.
ImplicitPCHInclude
=
"ngcpu.pch"
;
PPO
.
DisablePCHValidation
=
1
;
}
// Enable various target features
// Most of these are for Eigen
auto
&
TO
=
Clang
->
getInvocation
().
getTargetOpts
();
auto
&
TO
=
m_compiler
->
getInvocation
().
getTargetOpts
();
// TODO: This needs to be configurable and selected carefully
TO
.
CPU
=
"broadwell"
;
TO
.
FeaturesAsWritten
.
emplace_back
(
"+sse"
);
...
...
@@ -185,62 +228,121 @@ std::unique_ptr<llvm::Module> execution_state::compile(const string& source, con
TO
.
FeaturesAsWritten
.
emplace_back
(
"+avx"
);
TO
.
FeaturesAsWritten
.
emplace_back
(
"+avx2"
);
TO
.
FeaturesAsWritten
.
emplace_back
(
"+fma"
);
}
// Map code filename to a memoryBuffer
StringRef
source_ref
(
source
);
unique_ptr
<
MemoryBuffer
>
buffer
=
MemoryBuffer
::
getMemBufferCopy
(
source_ref
);
Clang
->
getInvocation
().
getPreprocessorOpts
().
addRemappedFile
(
name
,
buffer
.
get
());
// Create and execute action
CodeGenAction
*
compilerAction
=
new
EmitCodeGenOnlyAction
();
std
::
unique_ptr
<
llvm
::
Module
>
rc
;
if
(
Clang
->
ExecuteAction
(
*
compilerAction
)
==
true
)
{
rc
=
compilerAction
->
takeModule
();
}
buffer
.
release
();
return
rc
;
StaticCompiler
::~
StaticCompiler
()
{
}
bool
execution_state
::
add_module
(
std
::
unique_ptr
<
llvm
::
Module
>&
module
)
bool
StaticCompiler
::
is_version_number
(
const
string
&
path
)
{
if
(
module
)
bool
rc
=
true
;
vector
<
string
>
tokens
=
ngraph
::
split
(
path
,
'.'
);
for
(
string
s
:
tokens
)
{
if
(
!
m_execution_engine
)
for
(
char
c
:
s
)
{
m_execution_engine
=
llvm
::
EngineBuilder
(
move
(
module
))
.
setEngineKind
(
llvm
::
EngineKind
::
JIT
)
.
setOptLevel
(
llvm
::
CodeGenOpt
::
Aggressive
)
.
setErrorStr
(
&
jit_error
)
.
create
();
if
(
!
m_execution_engine
)
if
(
!
isdigit
(
c
))
{
r
eturn
false
;
r
c
=
false
;
}
}
}
else
return
rc
;
}
void
StaticCompiler
::
add_header_search_path
(
const
string
&
path
)
{
if
(
!
contains
(
m_extra_search_path_list
,
path
))
{
return
false
;
}
m_extra_search_path_list
.
push_back
(
path
);
HeaderSearchOptions
&
hso
=
m_compiler
->
getInvocation
().
getHeaderSearchOpts
();
#ifdef USE_CACHE
static
vector
<
string
>
valid_ext
=
{
".h"
,
".hpp"
,
".tcc"
,
""
};
string
mapped_path
=
file_util
::
path_join
(
"/$BUILTIN"
,
path
);
mapped_path
=
path
;
s_header_cache
.
add_path
(
mapped_path
);
auto
func
=
[
&
](
const
std
::
string
&
file
,
bool
is_dir
)
{
if
(
!
is_dir
)
{
string
ext
=
file_util
::
get_file_ext
(
file
);
if
(
contains
(
valid_ext
,
ext
))
{
// This is a header file
string
relative_name
=
file
.
substr
(
path
.
size
()
+
1
);
string
mapped_name
=
file_util
::
path_join
(
mapped_path
,
relative_name
);
ErrorOr
<
unique_ptr
<
MemoryBuffer
>>
code
=
MemoryBuffer
::
getFile
(
file
);
if
(
error_code
ec
=
code
.
getError
())
{
// throw up
throw
runtime_error
(
"could not find file '"
+
file
+
"'"
);
}
return
true
;
s_header_cache
.
add_file
(
mapped_name
,
code
.
get
());
}
}
};
file_util
::
iterate_files
(
path
,
func
,
true
);
#else
hso
.
AddPath
(
path
,
clang
::
frontend
::
System
,
false
,
false
);
#endif
}
}
void
execution_state
::
finalize
()
void
StaticCompiler
::
use_cached_files
()
{
if
(
m_execution_engine
)
HeaderSearchOptions
&
hso
=
m_compiler
->
getInvocation
().
getHeaderSearchOpts
();
for
(
const
string
&
path
:
s_header_cache
.
get_include_paths
())
{
m_execution_engine
->
finalizeObject
();
m_execution_engine
->
runStaticConstructorsDestructors
(
false
);
hso
.
AddPath
(
path
,
clang
::
frontend
::
System
,
false
,
false
);
}
else
for
(
auto
&
header
:
s_header_cache
.
get_header_map
())
{
throw
std
::
runtime_error
(
"Error in finalize: "
+
(
jit_error
.
empty
()
?
"Could not create an execution engine"
:
jit_error
));
m_compiler
->
getPreprocessorOpts
().
addRemappedFile
(
header
.
first
,
header
.
second
.
get
());
}
}
std
::
unique_ptr
<
llvm
::
Module
>
StaticCompiler
::
compile
(
const
string
&
source
)
{
// Map code filename to a memoryBuffer
StringRef
source_ref
(
source
);
unique_ptr
<
MemoryBuffer
>
buffer
=
MemoryBuffer
::
getMemBufferCopy
(
source_ref
);
m_compiler
->
getInvocation
().
getPreprocessorOpts
().
addRemappedFile
(
m_source_name
,
buffer
.
get
());
// Create and execute action
CodeGenAction
*
compilerAction
=
new
EmitCodeGenOnlyAction
();
std
::
unique_ptr
<
llvm
::
Module
>
rc
;
if
(
m_compiler
->
ExecuteAction
(
*
compilerAction
)
==
true
)
{
rc
=
compilerAction
->
takeModule
();
}
buffer
.
release
();
m_compiler
->
getInvocation
().
getPreprocessorOpts
().
clearRemappedFiles
();
return
rc
;
}
// std::unique_ptr<llvm::Module> StaticCompiler::generate_pch(const string& source)
// {
// // Map code filename to a memoryBuffer
// StringRef source_ref(source);
// unique_ptr<MemoryBuffer> buffer = MemoryBuffer::getMemBufferCopy(source_ref);
// m_compiler->getInvocation().getPreprocessorOpts().addRemappedFile(m_source_name, buffer.get());
// // Create and execute action
// CodeGenAction* compilerAction = new GeneratePCHAction();
// std::unique_ptr<llvm::Module> rc;
// if (m_compiler->ExecuteAction(*compilerAction) == true)
// {
// rc = compilerAction->takeModule();
// }
// buffer.release();
// m_compiler->getInvocation().getPreprocessorOpts().clearRemappedFiles();
// return rc;
// }
src/ngraph/codegen/compiler.hpp
View file @
0ef1c2f9
...
...
@@ -27,10 +27,18 @@ namespace ngraph
namespace
codegen
{
class
module
;
class
execution_state
;
class
Compiler
;
class
StaticCompiler
;
class
HeaderCache
;
}
}
namespace
clang
{
class
HeaderSearchOptions
;
class
CompilerInstance
;
}
class
ngraph
::
codegen
::
module
{
public
:
...
...
@@ -38,39 +46,57 @@ private:
std
::
unique_ptr
<
llvm
::
Module
>
m_module
;
};
class
ngraph
::
codegen
::
execution_state
:
public
llvm
::
SectionMemoryManag
er
class
ngraph
::
codegen
::
Compil
er
{
public
:
execution_state
();
~
execution_state
();
void
set_precompiled_headers_enabled
(
bool
state
)
{
precompiled_headers_enabled
=
state
;
}
bool
is_precompiled_headers_enabled
()
{
return
precompiled_headers_enabled
;
}
void
set_debuginfo_enabled
(
bool
state
)
{
debuginfo_enabled
=
state
;
}
bool
is_debuginfo_enabled
()
{
return
debuginfo_enabled
;
}
std
::
unique_ptr
<
llvm
::
Module
>
compile
(
const
std
::
string
&
source
,
const
std
::
string
&
name
=
""
);
bool
add_module
(
std
::
unique_ptr
<
llvm
::
Module
>&
);
Compiler
();
~
Compiler
();
std
::
unique_ptr
<
llvm
::
Module
>
compile
(
const
std
::
string
&
source
);
void
finalize
();
private
:
};
template
<
typename
ftype
>
std
::
function
<
ftype
>
find_function
(
const
std
::
string
&
func_name
)
{
auto
f
=
m_execution_engine
->
getPointerToNamedFunction
(
func_name
);
class
ngraph
::
codegen
::
StaticCompiler
:
public
llvm
::
SectionMemoryManager
{
public
:
StaticCompiler
();
~
StaticCompiler
();
return
f_cast
<
ftype
>
(
f
);
}
void
set_precompiled_headers_enabled
(
bool
state
)
{
m_precompiled_headers_enabled
=
state
;
}
bool
is_precompiled_headers_enabled
()
{
return
m_precompiled_headers_enabled
;
}
void
set_debuginfo_enabled
(
bool
state
)
{
m_debuginfo_enabled
=
state
;
}
bool
is_debuginfo_enabled
()
{
return
m_debuginfo_enabled
;
}
void
add_header_search_path
(
const
std
::
string
&
path
);
std
::
unique_ptr
<
llvm
::
Module
>
compile
(
const
std
::
string
&
source
);
private
:
llvm
::
ExecutionEngine
*
m_execution_engine
;
std
::
string
jit_error
;
bool
precompiled_headers_enabled
;
bool
debuginfo_enabled
;
std
::
unique_ptr
<
clang
::
CompilerInstance
>
m_compiler
;
bool
m_precompiled_headers_enabled
;
bool
m_debuginfo_enabled
;
std
::
string
m_source_name
;
std
::
vector
<
std
::
string
>
m_extra_search_path_list
;
template
<
typename
signature
>
std
::
function
<
signature
>
f_cast
(
void
*
f
)
bool
is_version_number
(
const
std
::
string
&
path
);
void
use_cached_files
();
};
class
ngraph
::
codegen
::
HeaderCache
{
public
:
bool
is_valid
()
const
{
return
m_headers_valid
;
}
bool
set_valid
()
{
return
m_headers_valid
=
true
;
}
void
add_path
(
const
std
::
string
&
path
)
{
m_include_paths
.
push_back
(
path
);
}
void
add_file
(
const
std
::
string
&
path
,
std
::
unique_ptr
<
llvm
::
MemoryBuffer
>&
code
)
{
m_headers
.
insert
(
std
::
make_pair
(
path
,
std
::
move
(
code
)));
}
const
std
::
map
<
std
::
string
,
std
::
unique_ptr
<
llvm
::
MemoryBuffer
>>&
get_header_map
()
const
{
return
static_cast
<
signature
*>
(
reinterpret_cast
<
signature
*>
(
f
))
;
return
m_headers
;
}
const
std
::
vector
<
std
::
string
>&
get_include_paths
()
const
{
return
m_include_paths
;
}
private
:
std
::
map
<
std
::
string
,
std
::
unique_ptr
<
llvm
::
MemoryBuffer
>>
m_headers
;
std
::
vector
<
std
::
string
>
m_include_paths
;
bool
m_headers_valid
;
};
src/ngraph/codegen/execution_engine.cpp
0 → 100644
View file @
0ef1c2f9
// ----------------------------------------------------------------------------
// 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
));
}
}
src/ngraph/codegen/execution_engine.hpp
0 → 100644
View file @
0ef1c2f9
// ----------------------------------------------------------------------------
// 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
));
}
};
src/ngraph/file_util.cpp
View file @
0ef1c2f9
/*
Copyright 2016 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
limitations under the License.
*/
// ----------------------------------------------------------------------------
// 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 <cassert>
#include <dirent.h>
...
...
@@ -29,10 +28,37 @@
#include <unistd.h>
#include <vector>
#include "file_util.hpp"
#include "ngraph/file_util.hpp"
#include "ngraph/log.hpp"
using
namespace
std
;
std
::
string
ngraph
::
file_util
::
get_file_name
(
const
std
::
string
&
s
)
{
string
rc
=
s
;
auto
pos
=
s
.
find_last_of
(
'/'
);
if
(
pos
!=
string
::
npos
)
{
rc
=
s
.
substr
(
pos
+
1
);
}
return
rc
;
}
std
::
string
ngraph
::
file_util
::
get_file_ext
(
const
std
::
string
&
s
)
{
string
rc
=
get_file_name
(
s
);
auto
pos
=
rc
.
find_last_of
(
'.'
);
if
(
pos
!=
string
::
npos
)
{
rc
=
rc
.
substr
(
pos
);
}
else
{
rc
=
""
;
}
return
rc
;
}
string
ngraph
::
file_util
::
path_join
(
const
string
&
s1
,
const
string
&
s2
)
{
string
rc
;
...
...
@@ -79,20 +105,22 @@ size_t ngraph::file_util::get_file_size(const string& filename)
void
ngraph
::
file_util
::
remove_directory
(
const
string
&
dir
)
{
struct
stat
status
;
if
(
stat
(
dir
.
c_str
(),
&
status
)
=
=
-
1
)
if
(
stat
(
dir
.
c_str
(),
&
status
)
!
=
-
1
)
{
return
;
iterate_files
(
dir
,
[](
const
string
&
file
,
bool
is_dir
)
{
if
(
is_dir
)
{
rmdir
(
file
.
c_str
());
}
else
{
remove
(
file
.
c_str
());
}
},
true
);
rmdir
(
dir
.
c_str
());
}
file_util
::
iterate_files
(
dir
,
[](
const
string
&
file
,
bool
is_dir
)
{
if
(
is_dir
)
rmdir
(
file
.
c_str
());
else
remove
(
file
.
c_str
());
},
true
);
rmdir
(
dir
.
c_str
());
}
void
ngraph
::
file_util
::
remove_file
(
const
string
&
file
)
...
...
@@ -117,7 +145,7 @@ bool ngraph::file_util::make_directory(const string& dir)
string
ngraph
::
file_util
::
make_temp_directory
(
const
string
&
path
)
{
string
fname
=
path
.
empty
()
?
file_util
::
get_temp_directory
()
:
path
;
string
tmp_template
=
file_util
::
path_join
(
fname
,
"
aeon
XXXXXX"
);
string
tmp_template
=
file_util
::
path_join
(
fname
,
"
ngraph_
XXXXXX"
);
char
*
tmpname
=
strdup
(
tmp_template
.
c_str
());
mkdtemp
(
tmpname
);
...
...
@@ -129,7 +157,7 @@ string ngraph::file_util::make_temp_directory(const string& path)
std
::
string
ngraph
::
file_util
::
get_temp_directory
()
{
const
vector
<
string
>
potential_tmps
=
{
"N
ERVANA_AEON
_TMP"
,
"TMPDIR"
,
"TMP"
,
"TEMP"
,
"TEMPDIR"
};
const
vector
<
string
>
potential_tmps
=
{
"N
GRAPH
_TMP"
,
"TMPDIR"
,
"TMP"
,
"TEMP"
,
"TEMPDIR"
};
const
char
*
path
=
nullptr
;
for
(
const
string
&
var
:
potential_tmps
)
...
...
@@ -161,7 +189,7 @@ vector<char> ngraph::file_util::read_file_contents(const string& path)
char
*
p
=
data
.
data
();
size_t
remainder
=
file_size
;
size_t
offset
=
0
;
while
(
remainder
>
0
)
while
(
f
&&
remainder
>
0
)
{
size_t
rc
=
fread
(
&
p
[
offset
],
1
,
remainder
,
f
);
offset
+=
rc
;
...
...
@@ -197,12 +225,16 @@ void ngraph::file_util::iterate_files(const string& path,
else
files
.
push_back
(
file
);
},
tru
e
);
recurs
e
);
for
(
auto
f
:
files
)
{
func
(
f
,
false
);
}
for
(
auto
f
:
dirs
)
{
func
(
f
,
true
);
}
}
void
ngraph
::
file_util
::
iterate_files_worker
(
...
...
@@ -218,18 +250,23 @@ void ngraph::file_util::iterate_files_worker(
switch
(
ent
->
d_type
)
{
case
DT_DIR
:
if
(
recurse
&&
name
!=
"."
&&
name
!=
".."
)
if
(
name
!=
"."
&&
name
!=
".."
)
{
string
dir_path
=
file_util
::
path_join
(
path
,
name
);
iterate_files
(
dir_path
,
func
,
recurse
);
if
(
recurse
)
{
iterate_files
(
dir_path
,
func
,
recurse
);
}
func
(
dir_path
,
true
);
}
break
;
case
DT_LNK
:
break
;
case
DT_REG
:
name
=
file_util
::
path_join
(
path
,
name
);
func
(
name
,
false
);
{
string
file_name
=
file_util
::
path_join
(
path
,
name
);
func
(
file_name
,
false
);
break
;
}
default
:
break
;
}
}
...
...
src/ngraph/file_util.hpp
View file @
0ef1c2f9
/*
Copyright 2016 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
limitations under the License.
*/
// ----------------------------------------------------------------------------
// 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
...
...
@@ -27,6 +26,8 @@ namespace ngraph
class
ngraph
::
file_util
{
public
:
static
std
::
string
get_file_name
(
const
std
::
string
&
);
static
std
::
string
get_file_ext
(
const
std
::
string
&
);
static
std
::
string
path_join
(
const
std
::
string
&
s1
,
const
std
::
string
&
s2
);
static
size_t
get_file_size
(
const
std
::
string
&
filename
);
static
void
remove_directory
(
const
std
::
string
&
dir
);
...
...
src/ngraph/runtime/cpu/cpu_kernels.hpp
View file @
0ef1c2f9
...
...
@@ -14,8 +14,8 @@
#pragma once
#include <cinttypes>
#include <cstddef>
#include <cstdint>
// CBLAS types and wrappers
...
...
src/ngraph/runtime/cpu/cpu_manager.hpp
View file @
0ef1c2f9
...
...
@@ -16,7 +16,7 @@
#include <memory>
#include "ngraph/codegen/
compiler
.hpp"
#include "ngraph/codegen/
execution_engine
.hpp"
#include "ngraph/runtime/manager.hpp"
namespace
ngraph
...
...
@@ -33,7 +33,7 @@ namespace ngraph
class
CPUManager
:
public
Manager
{
protected
:
ngraph
::
codegen
::
execution_stat
e
exec_state
;
ngraph
::
codegen
::
ExecutionEngin
e
exec_state
;
public
:
virtual
std
::
shared_ptr
<
Backend
>
allocate_backend
()
override
;
...
...
src/ngraph/runtime/cpu/eigen_utils.hpp
View file @
0ef1c2f9
...
...
@@ -89,7 +89,7 @@ namespace ngraph
};
}
//
E
T element type
// T element type
// FMT array format (fmt::V for vector, etc.)
// BASE select array/matrix
template
<
typename
T
,
...
...
@@ -128,4 +128,4 @@ namespace ngraph
}
}
}
}
\ No newline at end of file
}
src/ngraph/runtime/cpu/emitter.cpp
View file @
0ef1c2f9
...
...
@@ -66,20 +66,12 @@ void Emitter::EmitAdd(const ngraph::Node* n,
const
std
::
vector
<
TensorViewInfo
>&
inputs
,
const
std
::
vector
<
TensorViewInfo
>&
outputs
)
{
const
element
::
Type
&
et
=
(
dynamic_pointer_cast
<
const
TensorViewType
>
(
n
->
get_arguments
().
at
(
0
)
->
get_value_type
()))
->
get_element_type
();
string
type
=
et
.
c_type_string
();
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
type
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
;
TU
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
type
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
") +
\n
"
;
TU
<<
"EigenArray1d<"
<<
type
<<
">("
<<
inputs
[
1
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
1
])
<<
");
\n
"
;
TU
<<
emit_array1d
(
inputs
[
0
])
<<
" +
\n
"
;
TU
<<
emit_array1d
(
inputs
[
1
])
<<
";
\n
"
;
TU
.
indent
-=
2
;
TU
<<
"}
\n
"
;
}
...
...
@@ -111,11 +103,8 @@ void Emitter::EmitDot(const ngraph::Node* n,
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenVector<"
<<
arg0_element_type
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
")
\n
= "
<<
first
.
get_tensor
().
get_name
()
<<
"[0]
\n
* EigenVector<"
<<
arg0_element_type
.
c_type_string
()
<<
">("
<<
second
.
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
second
)
<<
");
\n
"
;
TU
<<
""
<<
emit_vector
(
outputs
[
0
])
<<
"
\n
= "
;
TU
<<
first
.
get_tensor
().
get_name
()
<<
"[0]
\n
* "
<<
emit_vector
(
second
)
<<
";
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -123,15 +112,9 @@ void Emitter::EmitDot(const ngraph::Node* n,
{
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenVector<"
<<
arg0_element_type
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") <<
\n
"
<<
" EigenVector<"
<<
arg0_element_type
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
").dot("
<<
"EigenVector<"
<<
arg0_element_type
.
c_type_string
()
<<
">("
<<
inputs
[
1
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
1
])
<<
"));
\n
"
;
TU
<<
""
<<
emit_vector
(
outputs
[
0
])
<<
" <<
\n
"
<<
" "
<<
emit_vector
(
inputs
[
0
])
<<
".dot("
<<
""
<<
emit_vector
(
inputs
[
1
])
<<
");
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -141,14 +124,9 @@ void Emitter::EmitDot(const ngraph::Node* n,
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenVector<"
<<
arg0_element_type
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" EigenMatrix<"
<<
arg0_element_type
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_matrix_format
(
arg0_layout
->
get_shape
(),
arg0_layout
->
get_strides
())
<<
") * "
<<
"EigenVector<"
<<
arg0_element_type
.
c_type_string
()
<<
">("
<<
inputs
[
1
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
1
])
<<
");
\n
"
;
TU
<<
""
<<
emit_vector
(
outputs
[
0
])
<<
" =
\n
"
<<
" "
<<
emit_matrix
(
inputs
[
0
])
<<
" * "
<<
""
<<
emit_vector
(
inputs
[
1
])
<<
";
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -179,18 +157,9 @@ void Emitter::EmitDot(const ngraph::Node* n,
{
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenMatrix<"
<<
arg0_element_type
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_matrix_format
(
out_layout
->
get_shape
(),
out_layout
->
get_strides
())
<<
") =
\n
"
<<
" EigenMatrix<"
<<
arg0_element_type
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_matrix_format
(
arg0_layout
->
get_shape
(),
arg0_layout
->
get_strides
())
<<
") * "
<<
"EigenMatrix<"
<<
arg0_element_type
.
c_type_string
()
<<
">("
<<
inputs
[
1
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_matrix_format
(
arg1_layout
->
get_shape
(),
arg1_layout
->
get_strides
())
<<
");
\n
"
;
TU
<<
""
<<
emit_matrix
(
outputs
[
0
])
<<
" =
\n
"
<<
" "
<<
emit_matrix
(
inputs
[
0
])
<<
" * "
<<
""
<<
emit_matrix
(
inputs
[
1
])
<<
";
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -213,12 +182,9 @@ void Emitter::EmitMultiply(const ngraph::Node* n,
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
type
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" EigenArray1d<"
<<
type
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
") *
\n
"
<<
" EigenArray1d<"
<<
type
<<
">("
<<
inputs
[
1
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
1
])
<<
");
\n
"
;
TU
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
0
])
<<
" *
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
1
])
<<
";
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -276,16 +242,10 @@ void Emitter::EmitAbs(const ngraph::Node* n,
const
std
::
vector
<
TensorViewInfo
>&
inputs
,
const
std
::
vector
<
TensorViewInfo
>&
outputs
)
{
const
element
::
Type
&
et
=
(
dynamic_pointer_cast
<
const
TensorViewType
>
(
n
->
get_arguments
().
at
(
0
)
->
get_value_type
()))
->
get_element_type
();
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
;
TU
<<
"Eigen::abs(EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
"));
\n
"
;
TU
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
;
TU
<<
"Eigen::abs("
<<
emit_array1d
(
inputs
[
0
])
<<
");
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -299,24 +259,19 @@ void Emitter::EmitConcat(const ngraph::Node* n,
assert
(
result_tensor_type
);
auto
result_shape
=
result_tensor_type
->
get_shape
();
auto
&
result_element_type
=
result_tensor_type
->
get_element_type
();
if
(
result_shape
.
size
()
==
1
)
{
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenVector<"
<<
result_element_type
.
c_type_string
()
<<
"> out_vector("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
");
\n
"
;
TU
<<
""
<<
emit_vector
(
outputs
[
0
],
"out_vector"
)
<<
";
\n
"
;
size_t
concat_pos
=
0
;
for
(
size_t
i
=
0
;
i
<
inputs
.
size
();
i
++
)
{
TU
<<
"out_vector.segment("
<<
concat_pos
<<
", "
<<
inputs
[
i
].
get_tensor_view_layout
()
->
get_shape
().
at
(
0
)
<<
") << "
<<
"EigenVector<"
<<
result_element_type
.
c_type_string
()
<<
">("
<<
inputs
[
i
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
i
])
<<
");
\n
"
;
<<
""
<<
emit_vector
(
inputs
[
i
])
<<
";
\n
"
;
concat_pos
+=
inputs
[
i
].
get_tensor_view_layout
()
->
get_shape
().
at
(
0
);
}
TU
.
indent
--
;
...
...
@@ -329,9 +284,7 @@ void Emitter::EmitConcat(const ngraph::Node* n,
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenMatrix<"
<<
result_element_type
.
c_type_string
()
<<
"> out_matrix("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_matrix_format
(
out_layout
->
get_shape
(),
out_layout
->
get_strides
())
<<
");
\n
"
;
TU
<<
""
<<
emit_matrix
(
outputs
[
0
],
"out_matrix"
)
<<
";
\n
"
;
size_t
concat_pos
[
2
]{
0
,
0
};
for
(
size_t
i
=
0
;
i
<
inputs
.
size
();
i
++
)
...
...
@@ -341,9 +294,7 @@ void Emitter::EmitConcat(const ngraph::Node* n,
TU
<<
"out_matrix.block("
<<
concat_pos
[
0
]
<<
", "
<<
concat_pos
[
1
]
<<
", "
<<
arg_shape
.
at
(
0
)
<<
", "
<<
arg_shape
.
at
(
1
)
<<
") << "
<<
"EigenMatrix<"
<<
result_element_type
.
c_type_string
()
<<
">("
<<
inputs
[
i
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_matrix_format
(
arg_layout
->
get_shape
(),
arg_layout
->
get_strides
())
<<
");
\n
"
;
<<
""
<<
emit_matrix
(
inputs
[
i
])
<<
";
\n
"
;
concat_pos
[
axis
]
+=
arg_shape
.
at
(
axis
);
}
...
...
@@ -358,18 +309,11 @@ void Emitter::EmitDivide(const ngraph::Node* n,
const
std
::
vector
<
TensorViewInfo
>&
inputs
,
const
std
::
vector
<
TensorViewInfo
>&
outputs
)
{
const
element
::
Type
&
et
=
(
dynamic_pointer_cast
<
const
TensorViewType
>
(
n
->
get_arguments
().
at
(
0
)
->
get_value_type
()))
->
get_element_type
();
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
") /
\n
"
<<
" EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
1
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
1
])
<<
");
\n
"
;
TU
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
0
])
<<
" /
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
1
])
<<
";
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -379,18 +323,11 @@ void Emitter::EmitEqual(const ngraph::Node* n,
const
std
::
vector
<
TensorViewInfo
>&
inputs
,
const
std
::
vector
<
TensorViewInfo
>&
outputs
)
{
const
element
::
Type
&
et
=
(
dynamic_pointer_cast
<
const
TensorViewType
>
(
n
->
get_arguments
().
at
(
0
)
->
get_value_type
()))
->
get_element_type
();
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
element
::
Bool
::
element_type
().
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" (EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
") ==
\n
"
<<
" EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
1
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
1
])
<<
")).template cast<char>();
\n
"
;
TU
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
<<
" ("
<<
emit_array1d
(
inputs
[
0
])
<<
" ==
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
1
])
<<
").template cast<char>();
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -400,18 +337,11 @@ void Emitter::EmitGreater(const ngraph::Node* n,
const
std
::
vector
<
TensorViewInfo
>&
inputs
,
const
std
::
vector
<
TensorViewInfo
>&
outputs
)
{
const
element
::
Type
&
et
=
(
dynamic_pointer_cast
<
const
TensorViewType
>
(
n
->
get_arguments
().
at
(
0
)
->
get_value_type
()))
->
get_element_type
();
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
<<
"{ // "
<<
n
->
get_name
()
<<
" xxx
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
element
::
Bool
::
element_type
().
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" (EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
") >
\n
"
<<
" EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
1
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
1
])
<<
")).template cast<char>();
\n
"
;
TU
<<
""
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
<<
" ("
<<
emit_array1d
(
inputs
[
0
])
<<
" >
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
1
])
<<
").template cast<char>();
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -421,18 +351,11 @@ void Emitter::EmitGreaterEq(const ngraph::Node* n,
const
std
::
vector
<
TensorViewInfo
>&
inputs
,
const
std
::
vector
<
TensorViewInfo
>&
outputs
)
{
const
element
::
Type
&
et
=
(
dynamic_pointer_cast
<
const
TensorViewType
>
(
n
->
get_arguments
().
at
(
0
)
->
get_value_type
()))
->
get_element_type
();
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
element
::
Bool
::
element_type
().
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" (EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
") >=
\n
"
<<
" EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
1
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
1
])
<<
")).template cast<char>();
\n
"
;
TU
<<
""
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
<<
" ("
<<
emit_array1d
(
inputs
[
0
])
<<
" >=
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
1
])
<<
").template cast<char>();
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -442,18 +365,11 @@ void Emitter::EmitLess(const ngraph::Node* n,
const
std
::
vector
<
TensorViewInfo
>&
inputs
,
const
std
::
vector
<
TensorViewInfo
>&
outputs
)
{
const
element
::
Type
&
et
=
(
dynamic_pointer_cast
<
const
TensorViewType
>
(
n
->
get_arguments
().
at
(
0
)
->
get_value_type
()))
->
get_element_type
();
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
element
::
Bool
::
element_type
().
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" (EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
") <
\n
"
<<
" EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
1
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
1
])
<<
")).template cast<char>();
\n
"
;
TU
<<
""
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
<<
" ("
<<
emit_array1d
(
inputs
[
0
])
<<
" <
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
1
])
<<
").template cast<char>();
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -463,18 +379,11 @@ void Emitter::EmitLessEq(const ngraph::Node* n,
const
std
::
vector
<
TensorViewInfo
>&
inputs
,
const
std
::
vector
<
TensorViewInfo
>&
outputs
)
{
const
element
::
Type
&
et
=
(
dynamic_pointer_cast
<
const
TensorViewType
>
(
n
->
get_arguments
().
at
(
0
)
->
get_value_type
()))
->
get_element_type
();
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
element
::
Bool
::
element_type
().
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" (EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
") <=
\n
"
<<
" EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
1
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
1
])
<<
")).template cast<char>();
\n
"
;
TU
<<
""
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
<<
" ("
<<
emit_array1d
(
inputs
[
0
])
<<
" <=
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
1
])
<<
").template cast<char>();
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -484,16 +393,10 @@ void Emitter::EmitLog(const ngraph::Node* n,
const
std
::
vector
<
TensorViewInfo
>&
inputs
,
const
std
::
vector
<
TensorViewInfo
>&
outputs
)
{
const
element
::
Type
&
et
=
(
dynamic_pointer_cast
<
const
TensorViewType
>
(
n
->
get_arguments
().
at
(
0
)
->
get_value_type
()))
->
get_element_type
();
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" Eigen::log(EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
"));
\n
"
;
TU
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
<<
" Eigen::log("
<<
emit_array1d
(
inputs
[
0
])
<<
");
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -503,18 +406,11 @@ void Emitter::EmitMaximum(const ngraph::Node* n,
const
std
::
vector
<
TensorViewInfo
>&
inputs
,
const
std
::
vector
<
TensorViewInfo
>&
outputs
)
{
const
element
::
Type
&
et
=
(
dynamic_pointer_cast
<
const
TensorViewType
>
(
n
->
get_arguments
().
at
(
0
)
->
get_value_type
()))
->
get_element_type
();
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
").max(
\n
"
<<
" EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
1
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
1
])
<<
"));
\n
"
;
TU
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
0
])
<<
".max(
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
1
])
<<
");
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -524,18 +420,11 @@ void Emitter::EmitMinimum(const ngraph::Node* n,
const
std
::
vector
<
TensorViewInfo
>&
inputs
,
const
std
::
vector
<
TensorViewInfo
>&
outputs
)
{
const
element
::
Type
&
et
=
(
dynamic_pointer_cast
<
const
TensorViewType
>
(
n
->
get_arguments
().
at
(
0
)
->
get_value_type
()))
->
get_element_type
();
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
").min(
\n
"
<<
" EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
1
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
1
])
<<
"));
\n
"
;
TU
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
0
])
<<
".min(
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
1
])
<<
");
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -545,16 +434,10 @@ void Emitter::EmitNegative(const ngraph::Node* n,
const
std
::
vector
<
TensorViewInfo
>&
inputs
,
const
std
::
vector
<
TensorViewInfo
>&
outputs
)
{
const
element
::
Type
&
et
=
(
dynamic_pointer_cast
<
const
TensorViewType
>
(
n
->
get_arguments
().
at
(
0
)
->
get_value_type
()))
->
get_element_type
();
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" -EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
");
\n
"
;
TU
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
<<
" -"
<<
emit_array1d
(
inputs
[
0
])
<<
";
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -564,18 +447,11 @@ void Emitter::EmitNotEqual(const ngraph::Node* n,
const
std
::
vector
<
TensorViewInfo
>&
inputs
,
const
std
::
vector
<
TensorViewInfo
>&
outputs
)
{
const
element
::
Type
&
et
=
(
dynamic_pointer_cast
<
const
TensorViewType
>
(
n
->
get_arguments
().
at
(
0
)
->
get_value_type
()))
->
get_element_type
();
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
element
::
Bool
::
element_type
().
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" (EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
") !=
\n
"
<<
" EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
1
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
1
])
<<
")).template cast<char>();
\n
"
;
TU
<<
""
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
<<
" ("
<<
emit_array1d
(
inputs
[
0
])
<<
" !=
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
1
])
<<
").template cast<char>();
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -585,20 +461,12 @@ void Emitter::EmitSelect(const ngraph::Node* n,
const
std
::
vector
<
TensorViewInfo
>&
inputs
,
const
std
::
vector
<
TensorViewInfo
>&
outputs
)
{
const
element
::
Type
&
et
=
(
dynamic_pointer_cast
<
const
TensorViewType
>
(
n
->
get_arguments
().
at
(
1
)
->
get_value_type
()))
->
get_element_type
();
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" EigenArray1d<"
<<
element
::
Bool
::
element_type
().
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
")
\n
"
<<
" .select(EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
1
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
"),
\n
"
<<
" EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
2
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
1
])
<<
"));
\n
"
;
TU
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
0
])
<<
"
\n
"
<<
" .select("
<<
emit_array1d
(
inputs
[
1
])
<<
",
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
2
])
<<
");
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -608,18 +476,11 @@ void Emitter::EmitSubtract(const ngraph::Node* n,
const
std
::
vector
<
TensorViewInfo
>&
inputs
,
const
std
::
vector
<
TensorViewInfo
>&
outputs
)
{
const
element
::
Type
&
et
=
(
dynamic_pointer_cast
<
const
TensorViewType
>
(
n
->
get_arguments
().
at
(
0
)
->
get_value_type
()))
->
get_element_type
();
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
") -
\n
"
<<
" EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
1
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
1
])
<<
");
\n
"
;
TU
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
0
])
<<
" -
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
1
])
<<
";
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -808,7 +669,6 @@ void Emitter::EmitBroadcast(const ngraph::Node* n,
auto
arg_shape
=
arg_tensor_type
->
get_shape
();
auto
result_shape
=
result_tensor_type
->
get_shape
();
auto
&
result_element_type
=
result_tensor_type
->
get_element_type
();
if
(
broadcast
->
get_broadcast_axes
().
empty
())
{
...
...
@@ -826,12 +686,8 @@ void Emitter::EmitBroadcast(const ngraph::Node* n,
{
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
result_element_type
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" EigenArray1d<"
<<
result_element_type
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
")(0, 0);
\n
"
;
TU
<<
""
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
0
])
<<
"(0, 0);
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -843,13 +699,8 @@ void Emitter::EmitBroadcast(const ngraph::Node* n,
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenMatrix<"
<<
result_element_type
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_matrix_format
(
out_layout
->
get_shape
(),
out_layout
->
get_strides
())
<<
").colwise() =
\n
"
<<
" EigenVector<"
<<
result_element_type
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
");
\n
"
;
TU
<<
""
<<
emit_matrix
(
outputs
[
0
])
<<
".colwise() =
\n
"
<<
" "
<<
emit_vector
(
inputs
[
0
])
<<
";
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -859,13 +710,8 @@ void Emitter::EmitBroadcast(const ngraph::Node* n,
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenMatrix<"
<<
result_element_type
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_matrix_format
(
out_layout
->
get_shape
(),
out_layout
->
get_strides
())
<<
").rowwise() =
\n
"
<<
" EigenVector<"
<<
result_element_type
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
").transpose();
\n
"
;
TU
<<
""
<<
emit_matrix
(
outputs
[
0
])
<<
".rowwise() =
\n
"
<<
" "
<<
emit_vector
(
inputs
[
0
])
<<
".transpose();
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -892,8 +738,6 @@ void Emitter::EmitConvert(const ngraph::Node* n,
auto
arg_tensor_type
=
dynamic_pointer_cast
<
const
TensorViewType
>
(
arg
->
get_value_type
());
assert
(
arg_tensor_type
);
auto
&
arg_element_type
=
arg_tensor_type
->
get_element_type
();
auto
result_tensor_type
=
dynamic_pointer_cast
<
const
TensorViewType
>
(
n
->
get_value_type
());
assert
(
result_tensor_type
);
...
...
@@ -901,10 +745,8 @@ void Emitter::EmitConvert(const ngraph::Node* n,
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
result_element_type
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" EigenArray1d<"
<<
arg_element_type
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
")
\n
"
TU
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
0
])
<<
"
\n
"
<<
" .template cast<"
<<
result_element_type
.
c_type_string
()
<<
">();
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
...
...
@@ -961,7 +803,8 @@ void Emitter::EmitReshape(const ngraph::Node* n,
result_shape_product
*=
i
;
}
// If there is no layout change or we are just going from 1^n to 1^m or a zero-size tensor, we can just copy.
// If there is no layout change or we are just going from 1^n to 1^m or a zero-size tensor,
// we can just copy.
if
(
same_layout
||
result_shape_product
<
2
)
{
TU
<<
"{ // "
<<
n
->
get_name
()
<<
" 1
\n
"
;
...
...
@@ -1000,13 +843,8 @@ void Emitter::EmitReshape(const ngraph::Node* n,
{
TU
<<
"{ // "
<<
n
->
get_name
()
<<
" 3
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenMatrix<"
<<
result_element_type
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_matrix_format
(
out_layout
->
get_shape
(),
out_layout
->
get_strides
())
<<
") =
\n
"
<<
" EigenMatrix<"
<<
result_element_type
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_matrix_format
(
arg0_layout
->
get_shape
(),
arg0_layout
->
get_strides
())
<<
").transpose();
\n
"
;
TU
<<
""
<<
emit_matrix
(
outputs
[
0
])
<<
" =
\n
"
<<
" "
<<
emit_matrix
(
inputs
[
0
])
<<
".transpose();
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -1029,19 +867,7 @@ void Emitter::EmitFunctionCall(const ngraph::Node* n,
TU
<<
"{ // Call "
<<
function
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"std::vector<void*> inputs;
\n
"
;
for
(
const
TensorViewInfo
&
input
:
inputs
)
{
TU
<<
"inputs.push_back("
<<
input
.
get_tensor
().
get_name
()
<<
");
\n
"
;
}
TU
<<
"
\n
"
;
TU
<<
"std::vector<void*> outputs;
\n
"
;
for
(
const
TensorViewInfo
&
output
:
outputs
)
{
TU
<<
"outputs.push_back("
<<
output
.
get_tensor
().
get_name
()
<<
");
\n
"
;
}
TU
<<
"
\n
"
;
TU
<<
function
->
get_name
()
<<
"(inputs, outputs);
\n
"
;
generate_call
(
inputs
,
outputs
,
function
);
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -1137,24 +963,18 @@ void Emitter::EmitReduce(const ngraph::Node* n,
TU
<<
"{ // "
<<
n
->
get_name
()
<<
" 3
\n
"
;
TU
.
indent
++
;
string
type
=
f_result_element_type
.
c_type_string
();
TU
<<
"auto f = []("
<<
type
<<
" x, "
<<
type
<<
" y) -> "
<<
type
<<
"
{
\n
"
;
TU
<<
"auto f = []("
<<
type
<<
" x, "
<<
type
<<
" y) -> "
<<
type
<<
"
\n
{
"
;
TU
.
indent
++
;
TU
<<
"std::vector<void*> inputs;
\n
"
;
TU
<<
"inputs.push_back(&x);
\n
"
;
TU
<<
"inputs.push_back(&y);
\n\n
"
;
TU
<<
"
\n
"
;
TU
<<
type
<<
" result;
\n
"
;
TU
<<
"std::vector<void*>
outputs
;
\n
"
;
TU
<<
"
outputs.push_back(&result)
;
\n
"
;
TU
<<
"std::vector<void*>
inputs = {&x, &y}
;
\n
"
;
TU
<<
"
std::vector<void*> outputs = {&result}
;
\n
"
;
TU
<<
reduction_function
->
get_name
()
<<
"(inputs, outputs);
\n
"
;
TU
<<
"return result;
\n
"
;
TU
.
indent
--
;
TU
<<
"};
\n
"
;
TU
<<
"EigenArray1d<"
<<
f_result_element_type
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" EigenArray1d<"
<<
f_result_element_type
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
").redux(f);
\n
"
;
TU
<<
""
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
0
])
<<
".redux(f);
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -1165,12 +985,8 @@ void Emitter::EmitReduce(const ngraph::Node* n,
{
TU
<<
"{ // "
<<
n
->
get_name
()
<<
" 4
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
f_result_element_type
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" EigenArray1d<"
<<
f_result_element_type
.
c_type_string
()
<<
">("
<<
inputs
[
1
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
1
])
<<
")(0, 0);
\n
"
;
TU
<<
""
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
1
])
<<
"(0, 0);
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -1183,25 +999,18 @@ void Emitter::EmitReduce(const ngraph::Node* n,
TU
<<
"{ // "
<<
n
->
get_name
()
<<
" 5
\n
"
;
TU
.
indent
++
;
string
type
=
f_result_element_type
.
c_type_string
();
TU
<<
"auto f = []("
<<
type
<<
" x, "
<<
type
<<
" y) -> "
<<
type
<<
"
{
\n
"
;
TU
<<
"auto f = []("
<<
type
<<
" x, "
<<
type
<<
" y) -> "
<<
type
<<
"
\n
{
"
;
TU
.
indent
++
;
TU
<<
"std::vector<void*> inputs;
\n
"
;
TU
<<
"inputs.push_back(&x);
\n
"
;
TU
<<
"inputs.push_back(&y);
\n\n
"
;
TU
<<
"
\n
"
;
TU
<<
type
<<
" result;
\n
"
;
TU
<<
"std::vector<void*>
outputs
;
\n
"
;
TU
<<
"
outputs.push_back(&result)
;
\n
"
;
TU
<<
"std::vector<void*>
inputs = {&x, &y}
;
\n
"
;
TU
<<
"
std::vector<void*> outputs = {&result}
;
\n
"
;
TU
<<
reduction_function
->
get_name
()
<<
"(inputs, outputs);
\n
"
;
TU
<<
"return result;
\n
"
;
TU
.
indent
--
;
TU
<<
"};
\n
"
;
TU
<<
"EigenVector<"
<<
f_result_element_type
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" EigenMatrix<"
<<
f_result_element_type
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_matrix_format
(
arg0_layout
->
get_shape
(),
arg0_layout
->
get_strides
())
<<
").rowwise().redux(f);
\n
"
;
TU
<<
""
<<
emit_vector
(
outputs
[
0
])
<<
" =
\n
"
<<
" "
<<
emit_matrix
(
inputs
[
0
])
<<
".rowwise().redux(f);
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -1212,12 +1021,8 @@ void Emitter::EmitReduce(const ngraph::Node* n,
{
TU
<<
"{ // "
<<
n
->
get_name
()
<<
" 6
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
f_result_element_type
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" EigenArray1d<"
<<
f_result_element_type
.
c_type_string
()
<<
">("
<<
inputs
[
1
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
1
])
<<
")(0, 0);
\n
"
;
TU
<<
""
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
1
])
<<
"(0, 0);
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -1226,25 +1031,18 @@ void Emitter::EmitReduce(const ngraph::Node* n,
TU
<<
"{ // "
<<
n
->
get_name
()
<<
" 7
\n
"
;
TU
.
indent
++
;
string
type
=
f_result_element_type
.
c_type_string
();
TU
<<
"auto f = []("
<<
type
<<
" x, "
<<
type
<<
" y) -> "
<<
type
<<
"
{
\n
"
;
TU
<<
"auto f = []("
<<
type
<<
" x, "
<<
type
<<
" y) -> "
<<
type
<<
"
\n
{
"
;
TU
.
indent
++
;
TU
<<
"std::vector<void*> inputs;
\n
"
;
TU
<<
"inputs.push_back(&x);
\n
"
;
TU
<<
"inputs.push_back(&y);
\n\n
"
;
TU
<<
"
\n
"
;
TU
<<
type
<<
" result;
\n
"
;
TU
<<
"std::vector<void*>
outputs
;
\n
"
;
TU
<<
"
outputs.push_back(&result)
;
\n
"
;
TU
<<
"std::vector<void*>
inputs = {&x, &y}
;
\n
"
;
TU
<<
"
std::vector<void*> outputs = {&result}
;
\n
"
;
TU
<<
reduction_function
->
get_name
()
<<
"(inputs, outputs);
\n
"
;
TU
<<
"return result;
\n
"
;
TU
.
indent
--
;
TU
<<
"};
\n
"
;
TU
<<
"EigenVector<"
<<
f_result_element_type
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" EigenMatrix<"
<<
f_result_element_type
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_matrix_format
(
arg0_layout
->
get_shape
(),
arg0_layout
->
get_strides
())
<<
").colwise().redux(f);
\n
"
;
TU
<<
""
<<
emit_vector
(
outputs
[
0
])
<<
" =
\n
"
<<
" "
<<
emit_matrix
(
inputs
[
0
])
<<
".colwise().redux(f);
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -1260,16 +1058,10 @@ void Emitter::EmitSign(const ngraph::Node* n,
const
std
::
vector
<
TensorViewInfo
>&
inputs
,
const
std
::
vector
<
TensorViewInfo
>&
outputs
)
{
const
element
::
Type
&
et
=
(
dynamic_pointer_cast
<
const
TensorViewType
>
(
n
->
get_arguments
().
at
(
0
)
->
get_value_type
()))
->
get_element_type
();
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
").sign();
\n
"
;
TU
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
0
])
<<
".sign();
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -1294,7 +1086,6 @@ void Emitter::EmitSlice(const ngraph::Node* n,
assert
(
arg_tensor_view_type
);
auto
arg_shape
=
arg_tensor_view_type
->
get_shape
();
auto
arg_rank
=
arg_shape
.
size
();
auto
&
arg_element_type
=
arg_tensor_view_type
->
get_element_type
();
auto
&
lower_bounds
=
slice
->
get_lower_bounds
();
auto
&
upper_bounds
=
slice
->
get_upper_bounds
();
...
...
@@ -1316,12 +1107,8 @@ void Emitter::EmitSlice(const ngraph::Node* n,
{
TU
<<
"{ // "
<<
n
->
get_name
()
<<
" 2
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenVector<"
<<
arg_element_type
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" EigenVector<"
<<
arg_element_type
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
").segment(
\n
"
TU
<<
""
<<
emit_vector
(
outputs
[
0
])
<<
" =
\n
"
<<
" "
<<
emit_vector
(
inputs
[
0
])
<<
".segment(
\n
"
<<
" "
<<
to_string
(
lower_bounds
[
0
])
<<
", "
<<
to_string
(
upper_bounds
[
0
]
-
lower_bounds
[
0
])
<<
");
\n
"
;
TU
.
indent
--
;
...
...
@@ -1334,14 +1121,9 @@ void Emitter::EmitSlice(const ngraph::Node* n,
TU
<<
"{ // "
<<
n
->
get_name
()
<<
" 3
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenMatrix<"
<<
arg_element_type
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_matrix_format
(
out_layout
->
get_shape
(),
out_layout
->
get_strides
())
<<
") =
\n
"
<<
" EigenMatrix<"
<<
arg_element_type
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_matrix_format
(
arg0_layout
->
get_shape
(),
arg0_layout
->
get_strides
())
<<
").block("
<<
to_string
(
lower_bounds
[
0
])
<<
", "
<<
to_string
(
lower_bounds
[
1
])
<<
",
\n
"
TU
<<
""
<<
emit_matrix
(
outputs
[
0
])
<<
" =
\n
"
<<
" "
<<
emit_matrix
(
inputs
[
0
])
<<
".block("
<<
to_string
(
lower_bounds
[
0
])
<<
", "
<<
to_string
(
lower_bounds
[
1
])
<<
",
\n
"
<<
" "
<<
to_string
(
upper_bounds
[
0
]
-
lower_bounds
[
0
])
<<
",
\n
"
<<
" "
<<
to_string
(
upper_bounds
[
1
]
-
lower_bounds
[
1
])
<<
");
\n
"
;
TU
.
indent
--
;
...
...
@@ -1362,7 +1144,6 @@ void Emitter::EmitSum(const ngraph::Node* n,
auto
s
=
static_cast
<
const
op
::
Sum
*>
(
n
);
auto
s_tensor_view_type
=
dynamic_pointer_cast
<
const
TensorViewType
>
(
s
->
get_value_type
());
assert
(
s_tensor_view_type
);
auto
&
s_element_type
=
s_tensor_view_type
->
get_element_type
();
auto
s_shape
=
s_tensor_view_type
->
get_shape
();
auto
arg
=
s
->
get_arguments
().
at
(
0
);
...
...
@@ -1393,12 +1174,8 @@ void Emitter::EmitSum(const ngraph::Node* n,
{
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
s_element_type
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" EigenArray1d<"
<<
s_element_type
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
").sum();
\n
"
;
TU
<<
""
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
0
])
<<
".sum();
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -1408,13 +1185,8 @@ void Emitter::EmitSum(const ngraph::Node* n,
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenVector<"
<<
s_element_type
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" EigenMatrix<"
<<
s_element_type
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_matrix_format
(
arg0_layout
->
get_shape
(),
arg0_layout
->
get_strides
())
<<
").rowwise().sum();
\n
"
;
TU
<<
""
<<
emit_vector
(
outputs
[
0
])
<<
" =
\n
"
<<
" "
<<
emit_matrix
(
inputs
[
0
])
<<
".rowwise().sum();
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -1424,13 +1196,8 @@ void Emitter::EmitSum(const ngraph::Node* n,
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenVector<"
<<
s_element_type
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" EigenMatrix<"
<<
s_element_type
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_matrix_format
(
arg0_layout
->
get_shape
(),
arg0_layout
->
get_strides
())
<<
").colwise().sum();
\n
"
;
TU
<<
""
<<
emit_vector
(
outputs
[
0
])
<<
" =
\n
"
<<
" "
<<
emit_matrix
(
inputs
[
0
])
<<
".colwise().sum();
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -1445,16 +1212,10 @@ void Emitter::EmitExp(const ngraph::Node* n,
const
std
::
vector
<
TensorViewInfo
>&
inputs
,
const
std
::
vector
<
TensorViewInfo
>&
outputs
)
{
const
element
::
Type
&
et
=
(
dynamic_pointer_cast
<
const
TensorViewType
>
(
n
->
get_arguments
().
at
(
0
)
->
get_value_type
()))
->
get_element_type
();
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
").exp();
\n
"
;
TU
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
0
])
<<
".exp();
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -1464,16 +1225,10 @@ void Emitter::EmitSin(const ngraph::Node* n,
const
std
::
vector
<
TensorViewInfo
>&
inputs
,
const
std
::
vector
<
TensorViewInfo
>&
outputs
)
{
const
element
::
Type
&
et
=
(
dynamic_pointer_cast
<
const
TensorViewType
>
(
n
->
get_arguments
().
at
(
0
)
->
get_value_type
()))
->
get_element_type
();
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
").sin();
\n
"
;
TU
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
0
])
<<
".sin();
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -1483,16 +1238,10 @@ void Emitter::EmitSinh(const ngraph::Node* n,
const
std
::
vector
<
TensorViewInfo
>&
inputs
,
const
std
::
vector
<
TensorViewInfo
>&
outputs
)
{
const
element
::
Type
&
et
=
(
dynamic_pointer_cast
<
const
TensorViewType
>
(
n
->
get_arguments
().
at
(
0
)
->
get_value_type
()))
->
get_element_type
();
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
").sinh();
\n
"
;
TU
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
0
])
<<
".sinh();
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -1502,16 +1251,10 @@ void Emitter::EmitCos(const ngraph::Node* n,
const
std
::
vector
<
TensorViewInfo
>&
inputs
,
const
std
::
vector
<
TensorViewInfo
>&
outputs
)
{
const
element
::
Type
&
et
=
(
dynamic_pointer_cast
<
const
TensorViewType
>
(
n
->
get_arguments
().
at
(
0
)
->
get_value_type
()))
->
get_element_type
();
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
").cos();
\n
"
;
TU
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
0
])
<<
".cos();
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -1521,16 +1264,10 @@ void Emitter::EmitCosh(const ngraph::Node* n,
const
std
::
vector
<
TensorViewInfo
>&
inputs
,
const
std
::
vector
<
TensorViewInfo
>&
outputs
)
{
const
element
::
Type
&
et
=
(
dynamic_pointer_cast
<
const
TensorViewType
>
(
n
->
get_arguments
().
at
(
0
)
->
get_value_type
()))
->
get_element_type
();
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
").cosh();
\n
"
;
TU
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
0
])
<<
".cosh();
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -1540,16 +1277,10 @@ void Emitter::EmitTan(const ngraph::Node* n,
const
std
::
vector
<
TensorViewInfo
>&
inputs
,
const
std
::
vector
<
TensorViewInfo
>&
outputs
)
{
const
element
::
Type
&
et
=
(
dynamic_pointer_cast
<
const
TensorViewType
>
(
n
->
get_arguments
().
at
(
0
)
->
get_value_type
()))
->
get_element_type
();
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
").tan();
\n
"
;
TU
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
0
])
<<
".tan();
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -1579,16 +1310,10 @@ void Emitter::EmitAsin(const ngraph::Node* n,
const
std
::
vector
<
TensorViewInfo
>&
inputs
,
const
std
::
vector
<
TensorViewInfo
>&
outputs
)
{
const
element
::
Type
&
et
=
(
dynamic_pointer_cast
<
const
TensorViewType
>
(
n
->
get_arguments
().
at
(
0
)
->
get_value_type
()))
->
get_element_type
();
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
").asin();
\n
"
;
TU
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
0
])
<<
".asin();
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -1598,16 +1323,10 @@ void Emitter::EmitAcos(const ngraph::Node* n,
const
std
::
vector
<
TensorViewInfo
>&
inputs
,
const
std
::
vector
<
TensorViewInfo
>&
outputs
)
{
const
element
::
Type
&
et
=
(
dynamic_pointer_cast
<
const
TensorViewType
>
(
n
->
get_arguments
().
at
(
0
)
->
get_value_type
()))
->
get_element_type
();
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
").acos();
\n
"
;
TU
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
0
])
<<
".acos();
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
...
...
@@ -1617,16 +1336,89 @@ void Emitter::EmitAtan(const ngraph::Node* n,
const
std
::
vector
<
TensorViewInfo
>&
inputs
,
const
std
::
vector
<
TensorViewInfo
>&
outputs
)
{
const
element
::
Type
&
et
=
(
dynamic_pointer_cast
<
const
TensorViewType
>
(
n
->
get_arguments
().
at
(
0
)
->
get_value_type
()))
->
get_element_type
();
TU
<<
"{ // "
<<
n
->
get_name
()
<<
"
\n
"
;
TU
.
indent
++
;
TU
<<
"EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
outputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
outputs
[
0
])
<<
") =
\n
"
<<
" EigenArray1d<"
<<
et
.
c_type_string
()
<<
">("
<<
inputs
[
0
].
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
inputs
[
0
])
<<
").atan();
\n
"
;
TU
<<
emit_array1d
(
outputs
[
0
])
<<
" =
\n
"
<<
" "
<<
emit_array1d
(
inputs
[
0
])
<<
".atan();
\n
"
;
TU
.
indent
--
;
TU
<<
"}
\n
"
;
}
//------------------------------------------------------------------------------------------------
// Utility methods
//------------------------------------------------------------------------------------------------
void
Emitter
::
generate_call
(
const
std
::
vector
<
TensorViewInfo
>&
inputs
,
const
std
::
vector
<
TensorViewInfo
>&
outputs
,
shared_ptr
<
Function
>
function
)
{
vector
<
string
>
input_names
;
vector
<
string
>
output_names
;
for
(
const
TensorViewInfo
&
input
:
inputs
)
{
input_names
.
push_back
(
input
.
get_tensor
().
get_name
());
}
for
(
const
TensorViewInfo
&
output
:
outputs
)
{
output_names
.
push_back
(
output
.
get_tensor
().
get_name
());
}
TU
<<
"std::vector<void*> inputs =
\n
{"
;
TU
.
indent
++
;
TU
<<
"
\n
"
<<
join
(
input_names
,
",
\n
"
);
TU
.
indent
--
;
TU
<<
"
\n
};
\n
"
;
TU
<<
"std::vector<void*> outputs =
\n
{"
;
TU
.
indent
++
;
TU
<<
"
\n
"
<<
join
(
output_names
,
",
\n
"
);
TU
.
indent
--
;
TU
<<
"
\n
};
\n
"
;
TU
<<
"
\n
"
;
TU
<<
function
->
get_name
()
<<
"(inputs, outputs);
\n
"
;
}
static
string
format_name
(
const
string
&
name
)
{
string
rc
;
if
(
name
.
empty
())
{
rc
=
" "
+
name
;
}
return
rc
;
}
string
Emitter
::
emit_vector
(
const
TensorViewInfo
&
tvi
,
const
string
&
name
)
{
stringstream
ss
;
const
element
::
Type
&
et
=
tvi
.
get_tensor_view
()
->
get_value_type
()
->
get_element_type
();
ss
<<
"EigenVector<"
<<
et
.
c_type_string
()
<<
">"
<<
format_name
(
name
)
<<
"("
<<
tvi
.
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
tvi
)
<<
")"
;
return
ss
.
str
();
}
string
Emitter
::
emit_array1d
(
const
TensorViewInfo
&
tvi
,
const
string
&
name
)
{
stringstream
ss
;
const
element
::
Type
&
et
=
tvi
.
get_tensor_view
()
->
get_value_type
()
->
get_element_type
();
ss
<<
"EigenArray1d<"
<<
et
.
c_type_string
()
<<
">"
<<
format_name
(
name
)
<<
"("
<<
tvi
.
get_tensor
().
get_name
()
<<
", "
<<
eigen_vector_format
(
tvi
)
<<
")"
;
return
ss
.
str
();
}
string
Emitter
::
emit_matrix
(
const
TensorViewInfo
&
tvi
,
const
string
&
name
)
{
stringstream
ss
;
auto
layout
=
tvi
.
get_layout
<
DenseTensorViewLayout
>
();
const
element
::
Type
&
et
=
tvi
.
get_tensor_view
()
->
get_value_type
()
->
get_element_type
();
ss
<<
"EigenMatrix<"
<<
et
.
c_type_string
()
<<
">"
<<
format_name
(
name
)
<<
"("
<<
tvi
.
get_tensor
().
get_name
()
<<
", "
<<
eigen_matrix_format
(
layout
->
get_shape
(),
layout
->
get_strides
())
<<
")"
;
return
ss
.
str
();
}
src/ngraph/runtime/cpu/emitter.hpp
View file @
0ef1c2f9
...
...
@@ -94,6 +94,15 @@ namespace ngraph
void
EMITTER_DECL
(
EmitAsin
);
void
EMITTER_DECL
(
EmitAcos
);
void
EMITTER_DECL
(
EmitAtan
);
private
:
void
generate_call
(
const
std
::
vector
<
TensorViewInfo
>&
inputs
,
const
std
::
vector
<
TensorViewInfo
>&
outputs
,
std
::
shared_ptr
<
Function
>
function
);
std
::
string
emit_vector
(
const
TensorViewInfo
&
,
const
std
::
string
&
name
=
""
);
std
::
string
emit_array1d
(
const
TensorViewInfo
&
,
const
std
::
string
&
name
=
""
);
std
::
string
emit_matrix
(
const
TensorViewInfo
&
,
const
std
::
string
&
name
=
""
);
};
}
}
...
...
src/ngraph/runtime/cpu/external_function.cpp
View file @
0ef1c2f9
...
...
@@ -22,6 +22,7 @@
#include "ngraph/codegen/code_writer.hpp"
#include "ngraph/codegen/compiler.hpp"
#include "ngraph/codegen/execution_engine.hpp"
#include "ngraph/descriptor/input.hpp"
#include "ngraph/descriptor/layout/dense_tensor_view_layout.hpp"
#include "ngraph/descriptor/output.hpp"
...
...
@@ -74,6 +75,7 @@
#include "ngraph/pass/memory_layout.hpp"
#include "ngraph/pass/topological_sort.hpp"
#include "ngraph/runtime/cpu/call_frame.hpp"
#include "ngraph/runtime/cpu/cpu_backend.hpp"
#include "ngraph/runtime/cpu/emitter.hpp"
#include "ngraph/runtime/cpu/external_function.hpp"
#include "ngraph/runtime/utils.hpp"
...
...
@@ -81,26 +83,17 @@
using
namespace
std
;
using
namespace
ngraph
::
runtime
::
cpu
;
using
ngraph
::
descriptor
::
layout
::
DenseTensorViewLayout
;
static
const
std
::
string
s_output_dir
=
"cpu_codegen"
;
extern
"C"
void
allocate_aligned_buffer
(
size_t
size
,
size_t
alignment
,
char
**
allocated
,
char
**
aligned_ptr
)
class
StaticInitializers
{
size_t
allocation_size
=
size
+
alignment
;
*
allocated
=
static_cast
<
char
*>
(
malloc
(
allocation_size
));
*
aligned_ptr
=
*
allocated
;
size_t
mod
=
size_t
(
*
aligned_ptr
)
%
alignment
;
public
:
StaticInitializers
()
{
ngraph
::
file_util
::
remove_directory
(
s_output_dir
);
}
};
if
(
mod
!=
0
)
{
(
*
aligned_ptr
)
+=
(
alignment
-
mod
);
}
}
static
StaticInitializers
s_static_initializers
;
extern
"C"
void
free_aligned_buffer
(
void
*
allocated
)
{
free
(
allocated
);
}
using
ngraph
::
descriptor
::
layout
::
DenseTensorViewLayout
;
#define TI(x) type_index(typeid(x))
...
...
@@ -192,37 +185,25 @@ void ExternalFunction::compile()
TU
+=
R"(// Generated by the NGraph CPU backend
#include <algorithm>
#include <cmath>
#include <memory>
#include <vector>
#include <Eigen/Dense>
#include "ngraph/runtime/cpu/cpu_kernels.hpp"
#include "ngraph/runtime/cpu/eigen_utils.hpp"
#include "ngraph/runtime/cpu/memory_handler.hpp"
using namespace ngraph::runtime::cpu::eigen;
extern "C" void allocate_aligned_buffer(
size_t size,
size_t alignment,
char** allocated,
char** aligned_ptr);
extern "C" void free_aligned_buffer(void* allocated);
)"
;
TU
<<
"// Declare a
ny functions that are not main
\n
"
;
TU
<<
"// Declare a
ll functions
\n
"
;
for
(
shared_ptr
<
Function
>
f
:
pass_manager
.
get_state
().
get_functions
())
{
if
(
f
!=
m_function
)
{
TU
<<
"extern
\"
C
\"
void "
<<
f
->
get_name
()
<<
"(
\n
"
;
TU
<<
" const std::vector<void*>& inputs,
\n
"
;
TU
<<
" const std::vector<void*>& outputs);
\n
"
;
}
TU
<<
"extern
\"
C
\"
void "
<<
f
->
get_name
()
<<
"(
\n
"
;
TU
<<
" const std::vector<void*>& inputs,
\n
"
;
TU
<<
" const std::vector<void*>& outputs);
\n
"
;
}
TU
<<
"
\n
"
;
...
...
@@ -232,27 +213,37 @@ extern "C" void free_aligned_buffer(void* allocated);
TU
<<
" const std::vector<void*>& inputs,
\n
"
;
TU
<<
" const std::vector<void*>& outputs)
\n
"
;
TU
<<
"{
\n
"
;
TU
.
indent
++
;
TU
<<
"// Allocate the memory pool
\n
"
;
size_t
temp_pool_size
=
pass_manager
.
get_state
().
get_temporary_pool_size
();
TU
<<
"char* allocated_buffer_pool;
\n
"
;
TU
<<
"char* aligned_buffer_pool;
\n
"
;
TU
<<
"allocate_aligned_buffer("
<<
temp_pool_size
<<
", 64"
<<
", &allocated_buffer_pool, &aligned_buffer_pool);
\n
"
;
TU
<<
"
\n
"
;
TU
<<
"// Define temporary tensors
\n
"
;
bool
temporaries_used
=
false
;
for
(
shared_ptr
<
Node
>
node
:
current_function
->
get_ordered_ops
())
{
for
(
descriptor
::
Tensor
*
tensor
:
node
->
liveness_new_list
)
if
(
node
->
liveness_new_list
.
size
()
>
0
)
{
TU
<<
tensor
->
get_element_type
()
<<
"* "
<<
tensor
->
get_name
()
<<
" = ("
<<
tensor
->
get_element_type
()
<<
"*)(aligned_buffer_pool + "
<<
tensor
->
get_pool_offset
()
<<
");
\n
"
;
temporaries_used
=
true
;
break
;
}
}
TU
<<
"
\n
"
;
if
(
temporaries_used
)
{
size_t
temp_pool_size
=
pass_manager
.
get_state
().
get_temporary_pool_size
();
TU
<<
"// Allocate the memory pool
\n
"
;
TU
<<
"ngraph::runtime::cpu::MemoryHandler memory_handler("
<<
temp_pool_size
<<
", "
<<
ngraph
::
runtime
::
cpu
::
alignment
<<
");
\n
"
;
TU
<<
"
\n
"
;
TU
<<
"// Define temporary tensors
\n
"
;
for
(
shared_ptr
<
Node
>
node
:
current_function
->
get_ordered_ops
())
{
for
(
descriptor
::
Tensor
*
tensor
:
node
->
liveness_new_list
)
{
TU
<<
tensor
->
get_element_type
()
<<
"* "
<<
tensor
->
get_name
()
<<
" = ("
<<
tensor
->
get_element_type
()
<<
"*)(memory_handler.get_ptr("
<<
tensor
->
get_pool_offset
()
<<
"));
\n
"
;
}
}
TU
<<
"
\n
"
;
}
TU
<<
"// Define inputs
\n
"
;
size_t
arg_index
=
0
;
...
...
@@ -283,13 +274,10 @@ extern "C" void free_aligned_buffer(void* allocated);
}
TU
<<
"
\n
"
;
TU
<<
"// Define tensor views
\n
"
;
TU
<<
"
\n
"
;
for
(
shared_ptr
<
Node
>
node
:
current_function
->
get_ordered_ops
())
{
auto
&
n
=
*
node
;
// Work around a compiler warning (*node inside typeid may have effects
// with shared pointers, which is fine here but clang doesn't like it.)
// with shared pointers, which is fine here but clang doesn't like it.)
auto
handler
=
dispatcher
.
find
(
type_index
(
typeid
(
n
)));
if
(
handler
==
dispatcher
.
end
())
{
...
...
@@ -311,8 +299,6 @@ extern "C" void free_aligned_buffer(void* allocated);
handler
->
second
(
&
emitter
,
node
.
get
(),
this
,
in
,
out
);
}
TU
<<
"
\n
free_aligned_buffer(allocated_buffer_pool);
\n
"
;
TU
.
indent
--
;
// End TU
...
...
@@ -321,34 +307,33 @@ extern "C" void free_aligned_buffer(void* allocated);
// TODO: Cleanup and make this a utility function
string
output_dir
=
"cpu_codegen"
;
string
function_name
=
m_function
->
get_name
();
file_util
::
remove_directory
(
output_dir
);
file_util
::
make_directory
(
output_dir
);
string
filename
=
file_util
::
path_join
(
output_dir
,
function_name
+
"_codegen.cpp"
);
file_util
::
make_directory
(
s_output_dir
);
string
filename
=
file_util
::
path_join
(
s_output_dir
,
function_name
+
"_codegen.cpp"
);
ofstream
out
(
filename
);
string
code
=
TU
.
get_code
();
out
<<
code
;
out
.
close
();
ngraph
::
codegen
::
execution_state
estate
;
codegen
::
Compiler
compiler
;
codegen
::
ExecutionEngine
execution_engine
;
#if NGCPU_PCH
estate
.
set_precompiled_headers_enabled
(
true
);
compiler
.
set_precompiled_headers_enabled
(
true
);
#endif
#if NGCPU_DEBUGINFO
estate
.
set_debuginfo_enabled
(
true
);
compiler
.
set_debuginfo_enabled
(
true
);
#endif
auto
llvm_module
=
estate
.
compile
(
code
,
function_name
+
"_codegen.cpp"
);
auto
llvm_module
=
compiler
.
compile
(
code
);
if
(
llvm_module
==
nullptr
)
{
throw
runtime_error
(
"function failed to compile"
);
}
e
stat
e
.
add_module
(
llvm_module
);
e
stat
e
.
finalize
();
m_compiled_function
=
e
stat
e
.
find_function
<
EntryPoint_t
>
(
function_name
);
e
xecution_engin
e
.
add_module
(
llvm_module
);
e
xecution_engin
e
.
finalize
();
m_compiled_function
=
e
xecution_engin
e
.
find_function
<
EntryPoint_t
>
(
function_name
);
assert
(
m_compiled_function
);
m_is_compiled
=
true
;
...
...
src/ngraph/runtime/cpu/memory_handler.cpp
0 → 100644
View file @
0ef1c2f9
// ----------------------------------------------------------------------------
// 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 "ngraph/runtime/cpu/memory_handler.hpp"
using
namespace
ngraph
;
runtime
::
cpu
::
MemoryHandler
::
MemoryHandler
(
size_t
byte_size
,
size_t
alignment
)
:
m_allocated_buffer_pool
(
nullptr
)
,
m_aligned_buffer_pool
(
nullptr
)
{
if
(
byte_size
>
0
)
{
size_t
allocation_size
=
byte_size
+
alignment
;
m_allocated_buffer_pool
=
static_cast
<
char
*>
(
malloc
(
allocation_size
));
m_aligned_buffer_pool
=
m_allocated_buffer_pool
;
size_t
mod
=
size_t
(
m_aligned_buffer_pool
)
%
alignment
;
if
(
mod
!=
0
)
{
m_aligned_buffer_pool
+=
(
alignment
-
mod
);
}
}
}
runtime
::
cpu
::
MemoryHandler
::~
MemoryHandler
()
{
if
(
m_allocated_buffer_pool
!=
nullptr
)
{
free
(
m_allocated_buffer_pool
);
}
}
src/ngraph/runtime/cpu/memory_handler.hpp
0 → 100644
View file @
0ef1c2f9
// ----------------------------------------------------------------------------
// 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 <cstddef>
#include <memory>
namespace
ngraph
{
namespace
runtime
{
namespace
cpu
{
class
MemoryHandler
;
}
}
}
class
ngraph
::
runtime
::
cpu
::
MemoryHandler
{
public
:
MemoryHandler
(
size_t
pool_size
,
size_t
alignment
);
~
MemoryHandler
();
void
*
get_ptr
(
size_t
offset
)
const
{
return
m_aligned_buffer_pool
+
offset
;
}
private
:
char
*
m_allocated_buffer_pool
;
char
*
m_aligned_buffer_pool
;
};
src/ngraph/runtime/cpu/tensor_view.cpp
View file @
0ef1c2f9
...
...
@@ -20,35 +20,47 @@
using
namespace
ngraph
;
using
namespace
std
;
extern
"C"
void
allocate_aligned_buffer
(
size_t
size
,
size_t
alignment
,
char
**
allocated
,
char
**
aligned_ptr
);
extern
"C"
void
free_aligned_buffer
(
void
*
allocated
);
runtime
::
cpu
::
CPUTensorView
::
CPUTensorView
(
const
ngraph
::
element
::
Type
&
element_type
,
const
Shape
&
shape
)
:
runtime
::
TensorView
(
std
::
make_shared
<
ngraph
::
descriptor
::
PrimaryTensorView
>
(
std
::
make_shared
<
ngraph
::
TensorViewType
>
(
element_type
,
shape
),
"external"
,
true
,
true
))
,
m_allocated_buffer_pool
(
nullptr
)
,
m_aligned_buffer_pool
(
nullptr
)
{
m_descriptor
->
set_tensor_view_layout
(
std
::
make_shared
<
ngraph
::
descriptor
::
layout
::
DenseTensorViewLayout
>
(
*
m_descriptor
));
m_buffer_size
=
m_descriptor
->
get_tensor_view_layout
()
->
get_size
()
*
element_type
.
size
();
allocate_aligned_buffer
(
m_buffer_size
,
runtime
::
cpu
::
alignment
,
&
m_allocated
,
&
m_buffer
);
if
(
m_buffer_size
>
0
)
{
size_t
allocation_size
=
m_buffer_size
+
runtime
::
cpu
::
alignment
;
m_allocated_buffer_pool
=
static_cast
<
char
*>
(
malloc
(
allocation_size
));
m_aligned_buffer_pool
=
m_allocated_buffer_pool
;
size_t
mod
=
size_t
(
m_aligned_buffer_pool
)
%
alignment
;
if
(
mod
!=
0
)
{
m_aligned_buffer_pool
+=
(
alignment
-
mod
);
}
}
}
runtime
::
cpu
::
CPUTensorView
::~
CPUTensorView
()
{
free_aligned_buffer
(
m_allocated
);
if
(
m_allocated_buffer_pool
!=
nullptr
)
{
free
(
m_allocated_buffer_pool
);
}
}
char
*
runtime
::
cpu
::
CPUTensorView
::
get_data_ptr
()
{
return
m_
buffer
;
return
m_
aligned_buffer_pool
;
}
const
char
*
runtime
::
cpu
::
CPUTensorView
::
get_data_ptr
()
const
{
return
m_
buffer
;
return
m_
aligned_buffer_pool
;
}
void
runtime
::
cpu
::
CPUTensorView
::
write
(
const
void
*
source
,
size_t
tensor_offset
,
size_t
n
)
...
...
src/ngraph/runtime/cpu/tensor_view.hpp
View file @
0ef1c2f9
...
...
@@ -52,7 +52,7 @@ public:
void
read
(
void
*
p
,
size_t
tensor_offset
,
size_t
n
)
const
override
;
private
:
char
*
m_allocated
;
char
*
m_
buffer
;
char
*
m_allocated
_buffer_pool
;
char
*
m_
aligned_buffer_pool
;
size_t
m_buffer_size
;
};
test/codegen.cpp
View file @
0ef1c2f9
...
...
@@ -19,23 +19,26 @@
#include "gtest/gtest.h"
#include "ngraph/codegen/compiler.hpp"
#include "ngraph/codegen/execution_engine.hpp"
using
namespace
std
;
using
namespace
ngraph
;
TEST
(
codegen
,
simple_return
)
{
constexpr
auto
name
=
"test.cpp"
;
constexpr
auto
source
=
R"(extern "C" int test() { return 2+5; })"
;
ngraph
::
codegen
::
execution_state
estate
;
auto
module
=
estate
.
compile
(
source
,
name
);
codegen
::
Compiler
compiler
;
codegen
::
ExecutionEngine
execution_engine
;
auto
module
=
compiler
.
compile
(
source
);
ASSERT_NE
(
nullptr
,
module
);
e
stat
e
.
add_module
(
module
);
e
xecution_engin
e
.
add_module
(
module
);
e
stat
e
.
finalize
();
e
xecution_engin
e
.
finalize
();
auto
func
=
e
stat
e
.
find_function
<
int
()
>
(
"test"
);
auto
func
=
e
xecution_engin
e
.
find_function
<
int
()
>
(
"test"
);
ASSERT_NE
(
nullptr
,
func
);
int
result
=
func
();
...
...
@@ -44,18 +47,19 @@ TEST(codegen, simple_return)
TEST
(
codegen
,
pass_args
)
{
constexpr
auto
name
=
"test.cpp"
;
constexpr
auto
source
=
R"(extern "C" int test(int a, int b) { return a+b; })"
;
ngraph
::
codegen
::
execution_state
estate
;
auto
module
=
estate
.
compile
(
source
,
name
);
codegen
::
Compiler
compiler
;
codegen
::
ExecutionEngine
execution_engine
;
auto
module
=
compiler
.
compile
(
source
);
ASSERT_NE
(
nullptr
,
module
);
e
stat
e
.
add_module
(
module
);
e
xecution_engin
e
.
add_module
(
module
);
e
stat
e
.
finalize
();
e
xecution_engin
e
.
finalize
();
auto
func
=
e
stat
e
.
find_function
<
int
(
int
,
int
)
>
(
"test"
);
auto
func
=
e
xecution_engin
e
.
find_function
<
int
(
int
,
int
)
>
(
"test"
);
ASSERT_NE
(
nullptr
,
func
);
int
result
=
func
(
20
,
22
);
...
...
@@ -64,7 +68,6 @@ TEST(codegen, pass_args)
TEST
(
codegen
,
include
)
{
constexpr
auto
name
=
"test.cpp"
;
constexpr
auto
source
=
R"(
#include <cmath>
...
...
@@ -74,15 +77,17 @@ TEST(codegen, include)
}
)"
;
ngraph
::
codegen
::
execution_state
estate
;
auto
module
=
estate
.
compile
(
source
,
name
);
codegen
::
Compiler
compiler
;
codegen
::
ExecutionEngine
execution_engine
;
auto
module
=
compiler
.
compile
(
source
);
ASSERT_NE
(
nullptr
,
module
);
e
stat
e
.
add_module
(
module
);
e
xecution_engin
e
.
add_module
(
module
);
e
stat
e
.
finalize
();
e
xecution_engin
e
.
finalize
();
auto
func
=
e
stat
e
.
find_function
<
int
(
int
,
int
)
>
(
"test"
);
auto
func
=
e
xecution_engin
e
.
find_function
<
int
(
int
,
int
)
>
(
"test"
);
ASSERT_NE
(
nullptr
,
func
);
int
result
=
func
(
20
,
2
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment