Skip to content

Commit

Permalink
Roll nomnigraph build into caffe2 (pytorch#11303)
Browse files Browse the repository at this point in the history
Summary:
We need to remove nomnigraph from the list of public libraries in order to support libtorch extensions. Easiest way to do this is to include it into the Caffe2 source like all other caffe2/core/ code.

However, because the headers are in a different place, we need to include them for linked libraries (pybind, tests, etc).

On an upside, this means that nomnigraph is now default hidden visibility too.

FYI peterjc123 xkszltl goldsborough bwasti Yangqing
Pull Request resolved: pytorch#11303

Reviewed By: pjh5

Differential Revision: D9694932

Pulled By: orionr

fbshipit-source-id: 5db3eb20bc5ddc873ce9151236b74663fbb33ed8
  • Loading branch information
orionr authored and facebook-github-bot committed Sep 7, 2018
1 parent 9de2085 commit 0f419ab
Showing 8 changed files with 59 additions and 57 deletions.
13 changes: 13 additions & 0 deletions caffe2/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -397,6 +397,8 @@ if (BUILD_TEST)
get_filename_component(test_name ${test_src} NAME_WE)
add_executable(${test_name} "${test_src}")
target_link_libraries(${test_name} ${Caffe2_MAIN_LIBS} gtest_main)
target_include_directories(${test_name} PRIVATE $<INSTALL_INTERFACE:include>)
target_include_directories(${test_name} PRIVATE ${Caffe2_CPU_INCLUDE})
if (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 3.0)
target_compile_features(${test_name} PRIVATE cxx_range_for)
endif()
@@ -412,6 +414,8 @@ if (BUILD_TEST)
get_filename_component(test_name ${test_src} NAME_WE)
hip_add_executable(${test_name} "${test_src}")
target_link_libraries(${test_name} ${Caffe2_MAIN_LIBS} gtest_main)
target_include_directories(${test_name} PRIVATE $<INSTALL_INTERFACE:include>)
target_include_directories(${test_name} PRIVATE ${Caffe2_CPU_INCLUDE})
if (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 3.0)
target_compile_features(${test_name} PRIVATE cxx_range_for)
endif()
@@ -428,6 +432,7 @@ if (NOT USE_ROCM)
foreach(test_src ${ATen_CPU_TEST_SRCS})
get_filename_component(test_name ${test_src} NAME_WE)
add_executable(${test_name} "${test_src}")
target_include_directories(${test_name} PRIVATE $<INSTALL_INTERFACE:include>)
target_include_directories(${test_name} PRIVATE ${Caffe2_CPU_INCLUDE})
target_include_directories(${test_name} SYSTEM PRIVATE ${Caffe2_DEPENDENCY_INCLUDE})
target_link_libraries(${test_name} ${Caffe2_MAIN_LIBS})
@@ -439,6 +444,7 @@ if (NOT USE_ROCM)
foreach(test_src ${ATen_CUDA_TEST_SRCS})
get_filename_component(test_name ${test_src} NAME_WE)
torch_cuda_based_add_executable(${test_name} "${test_src}")
target_include_directories(${test_name} PRIVATE $<INSTALL_INTERFACE:include>)
target_include_directories(${test_name} PRIVATE ${Caffe2_CPU_INCLUDE})
target_include_directories(${test_name} SYSTEM PRIVATE ${Caffe2_DEPENDENCY_INCLUDE})
target_link_libraries(${test_name} ${Caffe2_MAIN_LIBS})
@@ -504,6 +510,9 @@ if (BUILD_PYTHON)
if (APPLE)
set_target_properties(caffe2_pybind11_state PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
endif()
target_include_directories(caffe2_pybind11_state PRIVATE $<INSTALL_INTERFACE:include>)
target_include_directories(caffe2_pybind11_state PRIVATE ${Caffe2_CPU_INCLUDE})

target_link_libraries(
caffe2_pybind11_state caffe2_library)
if (WIN32)
@@ -526,6 +535,8 @@ if (BUILD_PYTHON)
if (APPLE)
set_target_properties(caffe2_pybind11_state_gpu PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
endif()
target_include_directories(caffe2_pybind11_state_gpu PRIVATE $<INSTALL_INTERFACE:include>)
target_include_directories(caffe2_pybind11_state_gpu PRIVATE ${Caffe2_CPU_INCLUDE})
target_link_libraries(
caffe2_pybind11_state_gpu caffe2_library caffe2_gpu_library)
if (WIN32)
@@ -549,6 +560,8 @@ if (BUILD_PYTHON)
if (APPLE)
set_target_properties(caffe2_pybind11_state_hip PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
endif()
target_include_directories(caffe2_pybind11_state_hip PRIVATE $<INSTALL_INTERFACE:include>)
target_include_directories(caffe2_pybind11_state_hip PRIVATE ${Caffe2_CPU_INCLUDE})
target_link_libraries(
caffe2_pybind11_state_hip caffe2_library caffe2_hip_library)
if (WIN32)
30 changes: 8 additions & 22 deletions caffe2/core/nomnigraph/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -3,29 +3,15 @@ file(GLOB_RECURSE NOMNI_SRCS *.cc)
file(GLOB_RECURSE NOMNI_TEST_SRCS *Test.cc)
exclude(NOMNI_SRCS "${NOMNI_SRCS}" "${NOMNI_TEST_SRCS}")

# TODO(orionr): The nomnigraph source should likely just be included
# in the Caffe2 source list, since this won't live separately
add_library(nomnigraph STATIC "${NOMNI_SRCS}")
target_compile_options(nomnigraph PRIVATE "-DCAFFE2_BUILD_MAIN_LIB")
add_dependencies(nomnigraph Caffe2_PROTO)
list(APPEND Caffe2_CPU_SRCS ${NOMNI_SRCS})
list(APPEND Caffe2_CPU_INCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/include)
list(APPEND Caffe2_CPU_TEST_SRCS ${NOMNI_TEST_SRCS})

target_include_directories(nomnigraph PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
$<INSTALL_INTERFACE:include>)
list(APPEND Caffe2_PUBLIC_DEPENDENCY_LIBS nomnigraph)
set(Caffe2_PUBLIC_DEPENDENCY_LIBS ${Caffe2_PUBLIC_DEPENDENCY_LIBS} PARENT_SCOPE)

install(TARGETS nomnigraph EXPORT Caffe2Targets DESTINATION lib)
install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/include
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include
DESTINATION include
FILES_MATCHING PATTERN "*.h")

if (BUILD_TEST)
foreach(test_src ${NOMNI_TEST_SRCS})
get_filename_component(test_name ${test_src} NAME_WE)
add_executable(${test_name} "${test_src}")
target_link_libraries(${test_name} nomnigraph gtest_main)
add_test(NAME ${test_name} COMMAND $<TARGET_FILE:${test_name}>)
install(TARGETS ${test_name} DESTINATION test)
endforeach()
endif()
# ---[ Send the lists to the parent scope.
set(Caffe2_CPU_SRCS ${Caffe2_CPU_SRCS} PARENT_SCOPE)
set(Caffe2_CPU_INCLUDE ${Caffe2_CPU_INCLUDE} PARENT_SCOPE)
set(Caffe2_CPU_TEST_SRCS ${Caffe2_CPU_TEST_SRCS} PARENT_SCOPE)
8 changes: 4 additions & 4 deletions caffe2/core/nomnigraph/include/nomnigraph/Graph/Graph.h
Original file line number Diff line number Diff line change
@@ -39,7 +39,7 @@ class Node;

// \brief Edge within a Graph.
template <typename T, typename... U>
class Edge : public StorageType<U...> {
class CAFFE2_API Edge : public StorageType<U...> {
public:
using NodeRef = typename Graph<T, U...>::NodeRef;
Edge(NodeRef tail, NodeRef head, U... args)
@@ -73,7 +73,7 @@ class Edge : public StorageType<U...> {

// \brief Node within a Graph.
template <typename T, typename... U>
class Node : public StorageType<T>, public Notifier<Node<T, U...>> {
class CAFFE2_API Node : public StorageType<T>, public Notifier<Node<T, U...>> {
public:
using NodeRef = typename Graph<T, U...>::NodeRef;
using EdgeRef = typename Graph<T, U...>::EdgeRef;
@@ -152,7 +152,7 @@ class Node : public StorageType<T>, public Notifier<Node<T, U...>> {
/// for example.
///
template <typename T, typename... U>
class Subgraph {
class CAFFE2_API Subgraph {
public:
Subgraph() {
DEBUG_PRINT("Creating instance of Subgraph: %p\n", this);
@@ -219,7 +219,7 @@ class Subgraph {
/// Everything is owned by the graph to simplify storage concerns.
///
template <typename T, typename... U>
class Graph {
class CAFFE2_API Graph {
public:
using SubgraphType = Subgraph<T, U...>;
using NodeRef = Node<T, U...>*;
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@
namespace nom {
namespace repr {

class Value {
class CAFFE2_API Value {
public:
enum class ValueKind { Value, Instruction, Data };
Value(ValueKind K) : kind_(K) {}
@@ -22,7 +22,7 @@ class Value {
const ValueKind kind_;
};

class Data : public Value {
class CAFFE2_API Data : public Value {
public:
Data() : Value(ValueKind::Data) {}
static bool classof(const Value* V) {
@@ -41,7 +41,7 @@ class Data : public Value {
size_t version_ = 0;
};

class Instruction : public Value {
class CAFFE2_API Instruction : public Value {
public:
/// \brief All the different types of execution.
enum class Opcode {
@@ -66,7 +66,7 @@ class Instruction : public Value {
Opcode op_;
};

class Terminator : public Instruction {
class CAFFE2_API Terminator : public Instruction {
public:
Terminator(Instruction::Opcode op) : Instruction(op) {}

@@ -80,17 +80,17 @@ class Terminator : public Instruction {
}
};

class Branch : public Terminator {
class CAFFE2_API Branch : public Terminator {
public:
Branch() : Terminator(Instruction::Opcode::Branch) {}
};

class Return : public Terminator {
class CAFFE2_API Return : public Terminator {
public:
Return() : Terminator(Instruction::Opcode::Return) {}
};

class Phi : public Instruction {
class CAFFE2_API Phi : public Instruction {
public:
Phi() : Instruction(Instruction::Opcode::Phi) {}
};
Original file line number Diff line number Diff line change
@@ -41,7 +41,7 @@ class NeuralNetData;
/// a saved void* pointer for external use. Derived classes
/// add richer semantics to the annotation and it is encouraged
/// to use them.
class Annotation {
class CAFFE2_API Annotation {
public:
enum class AnnotationKind { Generic, Caffe2 };

@@ -60,7 +60,7 @@ class Annotation {
const AnnotationKind kind_;
};

class NeuralNetOperator : public Instruction {
class CAFFE2_API NeuralNetOperator : public Instruction {
public:
/// Discriminator for LLVM-style RTTI (isa<>)
enum class NNKind {
@@ -135,7 +135,7 @@ class NeuralNetOperator : public Instruction {
std::unique_ptr<Annotation> extraAnnotation_;
};

class NeuralNetData : public Data {
class CAFFE2_API NeuralNetData : public Data {
public:
/// Discriminator for LLVM-style RTTI (isa<>)
enum class NNDataKind { Generic, Tensor };
@@ -159,7 +159,7 @@ class NeuralNetData : public Data {
size_t version_ = 0;
};

class Tensor : public NeuralNetData {
class CAFFE2_API Tensor : public NeuralNetData {
public:
enum class DataType { Generic, Float, Half, Int8 };
enum class Layout { Generic, NCHW, NHWC };
@@ -207,21 +207,21 @@ class Tensor : public NeuralNetData {

#include "nomnigraph/Generated/OpClasses.h"

class While : public NeuralNetOperator {
class CAFFE2_API While : public NeuralNetOperator {
public:
While() : NeuralNetOperator(NNKind::While, Opcode::Branch) {}
NOMNIGRAPH_DEFINE_NN_RTTI(While);
~While() {}
};

class NNPhi : public NeuralNetOperator {
class CAFFE2_API NNPhi : public NeuralNetOperator {
public:
NNPhi() : NeuralNetOperator(NNKind::NNPhi, Opcode::Phi) {}
NOMNIGRAPH_DEFINE_NN_RTTI(NNPhi);
~NNPhi() {}
};

class GenericOperator : public NeuralNetOperator {
class CAFFE2_API GenericOperator : public NeuralNetOperator {
public:
GenericOperator() : NeuralNetOperator(NNKind::GenericOperator) {}
GenericOperator(std::string name)
@@ -243,7 +243,7 @@ using NNGraph = nom::Graph<std::unique_ptr<nom::repr::Value>>;
using NNSubgraph = nom::Subgraph<std::unique_ptr<nom::repr::Value>>;
using NNCFGraph = nom::repr::ControlFlowGraph<NNGraph>;

struct NNModule {
struct CAFFE2_API NNModule {
NNGraph dataFlow;
NNCFGraph controlFlow;
std::unordered_set<NNGraph::NodeRef> inputs;
@@ -262,22 +262,22 @@ template <bool B, class T = void>
using enable_if_t = typename std::enable_if<B, T>::type;

template <typename T, typename U>
struct inheritedFrom {
struct CAFFE2_EXPORT inheritedFrom {
static constexpr bool value =
std::is_base_of<U, T>::value && !std::is_same<U, T>::value;
};

// This is just a way to fix issues when the isa<> implementation
// can't automatically downcast.
template <typename T, typename N, typename = void>
struct is_impl {
struct CAFFE2_EXPORT is_impl {
inline static bool impl(N n) {
return isa<T>(n->data());
}
};

template <typename T, typename N>
struct is_impl<T, N, enable_if_t<inheritedFrom<T, NeuralNetOperator>::value>> {
struct CAFFE2_EXPORT is_impl<T, N, enable_if_t<inheritedFrom<T, NeuralNetOperator>::value>> {
inline static bool impl(N n) {
if (!isa<NeuralNetOperator>(n->data().get())) {
return false;
@@ -288,7 +288,7 @@ struct is_impl<T, N, enable_if_t<inheritedFrom<T, NeuralNetOperator>::value>> {
};

template <typename T, typename N>
struct is_impl<T, N, enable_if_t<inheritedFrom<T, NeuralNetData>::value>> {
struct CAFFE2_EXPORT is_impl<T, N, enable_if_t<inheritedFrom<T, NeuralNetData>::value>> {
inline static bool impl(N n) {
if (!isa<NeuralNetData>(n->data().get())) {
return false;
@@ -306,14 +306,14 @@ inline bool is(N n) {
// This is just a way to fix issues when the dyn_cast<> implementation
// can't automatically downcast.
template <typename T, typename N, typename = void>
struct get_impl {
struct CAFFE2_EXPORT get_impl {
inline static T* impl(N n) {
return dyn_cast<T>(n->data().get());
}
};

template <typename T, typename N>
struct get_impl<T, N, enable_if_t<inheritedFrom<T, NeuralNetOperator>::value>> {
struct CAFFE2_EXPORT get_impl<T, N, enable_if_t<inheritedFrom<T, NeuralNetOperator>::value>> {
inline static T* impl(N n) {
if (!is<T>(n)) {
assert(0 && "Cannot get type from node");
@@ -325,7 +325,7 @@ struct get_impl<T, N, enable_if_t<inheritedFrom<T, NeuralNetOperator>::value>> {
};

template <typename T, typename N>
struct get_impl<T, N, enable_if_t<inheritedFrom<T, NeuralNetData>::value>> {
struct CAFFE2_EXPORT get_impl<T, N, enable_if_t<inheritedFrom<T, NeuralNetData>::value>> {
inline static T* impl(N n) {
if (!is<T>(n)) {
assert(0 && "Cannot get type from node");
@@ -425,9 +425,9 @@ CAFFE2_API std::vector<NNGraph::NodeRef> getOutputs(NNGraph::NodeRef n);
CAFFE2_API void coalesceInsertedDataDependencies(repr::NNModule* m);

template <NNGraph* G>
struct NodeHelper {};
struct CAFFE2_EXPORT NodeHelper {};

struct NNNodeMatchCriteria {
struct CAFFE2_API NNNodeMatchCriteria {
std::function<bool(NNGraph::NodeRef)> predicate;
std::string debugString;

@@ -452,7 +452,7 @@ struct NNNodeMatchCriteria {
}
};

std::ostream& operator<<(
CAFFE2_API std::ostream& operator<<(
std::ostream& oss,
const NNNodeMatchCriteria& criteria);

@@ -489,7 +489,7 @@ NNNodeMatchCriteria matchOp(
debugString);
};

struct NNNodeMatch {
struct CAFFE2_API NNNodeMatch {
static bool isMatch(
const NNGraph::NodeRef& node,
const NNNodeMatchCriteria& criteria) {
@@ -503,7 +503,7 @@ using NNSubgraphMatcher =
// This helper method makes it easy to create matching criteria in NNGraph.
// For example, operatorSubgraph(opMatch, ...) will refer to a tree like this:
// ... -> opMatch -> opMatch_Output
NNMatchGraph::NodeRef operatorSubgraph(
CAFFE2_API NNMatchGraph::NodeRef operatorSubgraph(
NNMatchGraph& g,
const NNNodeMatchCriteria& root,
const std::vector<NNMatchGraph::NodeRef>& childrenCriteria = {},
5 changes: 3 additions & 2 deletions caffe2/core/nomnigraph/tests/test_util.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef NOM_TESTS_TEST_UTIL_H
#define NOM_TESTS_TEST_UTIL_H

#include "caffe2/core/common.h"
#include "nomnigraph/Graph/Graph.h"
#include "nomnigraph/Graph/Algorithms.h"
#include "nomnigraph/Representations/NeuralNet.h"
@@ -101,9 +102,9 @@ class TestRandom {
* return labelMap;
* });
*/
nom::Graph<std::string> createGraph();
CAFFE2_API nom::Graph<std::string> createGraph();

nom::Graph<std::string> createGraphWithCycle();
CAFFE2_API nom::Graph<std::string> createGraphWithCycle();

std::map<std::string, std::string> BBPrinter(typename nom::repr::NNCFGraph::NodeRef node);

2 changes: 1 addition & 1 deletion caffe2/opt/fusion.h
Original file line number Diff line number Diff line change
@@ -37,7 +37,7 @@ CAFFE2_API void fuseConvBN(repr::NNModule* nn, caffe2::Workspace* ws);
// \param postprocess Functor to postprocess the conv node,
// attaching additional attributes if necessary
template <typename OperationT, typename ActivationT>
void fuseActivation(
CAFFE2_EXPORT void fuseActivation(
repr::NNModule* nn,
std::function<bool(const OperationT& conv)> should_fuse,
std::function<void(repr::NNGraph::NodeRef conv_node)> postprocess) {
4 changes: 3 additions & 1 deletion caffe2/opt/onnx_convert.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
class OnnxAnnotation : public nom::repr::Annotation {
#include "caffe2/core/common.h"

class CAFFE2_API OnnxAnnotation : public nom::repr::Annotation {
public:
OnnxAnnotation() : Annotation(AnnotationKind::Onnx) {}
OnnxAnnotation(std::string device)

0 comments on commit 0f419ab

Please sign in to comment.