Unverified Commit 956f66ad authored by Robert Kimball's avatar Robert Kimball Committed by GitHub

Initial backend for non-IA CPUs (#2268)

* first cut at raspberry pi backend

* rename rpi to generic cpu

* disable cursed test
parent 20bd8bbc
...@@ -105,13 +105,14 @@ option(NGRAPH_GPU_ENABLE "Control the building of the GPU backend" FALSE) ...@@ -105,13 +105,14 @@ option(NGRAPH_GPU_ENABLE "Control the building of the GPU backend" FALSE)
option(NGRAPH_INTERPRETER_ENABLE "Control the building of the INTERPRETER backend" TRUE) option(NGRAPH_INTERPRETER_ENABLE "Control the building of the INTERPRETER backend" TRUE)
option(NGRAPH_NOP_ENABLE "Control the building of the NOP backend" TRUE) option(NGRAPH_NOP_ENABLE "Control the building of the NOP backend" TRUE)
option(NGRAPH_GPUH_ENABLE "Control the building of the Hybrid GPU backend" FALSE) option(NGRAPH_GPUH_ENABLE "Control the building of the Hybrid GPU backend" FALSE)
option(NGRAPH_GENERIC_CPU_ENABLE "Enable build nGraph for generic CPU backend" FALSE)
option(NGRAPH_DISTRIBUTED_ENABLE "Add distributed mode to the CPU backend" FALSE) option(NGRAPH_DISTRIBUTED_ENABLE "Add distributed mode to the CPU backend" FALSE)
option(NGRAPH_DEBUG_ENABLE "Enable output for NGRAPH_DEBUG statements" FALSE) option(NGRAPH_DEBUG_ENABLE "Enable output for NGRAPH_DEBUG statements" FALSE)
option(NGRAPH_ONNX_IMPORT_ENABLE "Enable ONNX importer" FALSE) option(NGRAPH_ONNX_IMPORT_ENABLE "Enable ONNX importer" FALSE)
option(NGRAPH_DEX_ONLY "Build CPU DEX without codegen" FALSE) option(NGRAPH_DEX_ONLY "Build CPU DEX without codegen" FALSE)
option(NGRAPH_CODE_COVERAGE_ENABLE "Enable code coverage data collection" FALSE) option(NGRAPH_CODE_COVERAGE_ENABLE "Enable code coverage data collection" FALSE)
option(NGRAPH_LIB_VERSIONING_ENABLE "Enable shared library versioning" FALSE) option(NGRAPH_LIB_VERSIONING_ENABLE "Enable shared library versioning" FALSE)
option(NGRAPH_PYTHON_BUILD_ENABLE "Enable build nGraph python package wheel" FALSE) option(NGRAPH_PYTHON_BUILD_ENABLE "Enable build nGraph python package wheel" FALSE)
if (NGRAPH_GPUH_ENABLE) if (NGRAPH_GPUH_ENABLE)
set(NGRAPH_GPU_ENABLE TRUE) set(NGRAPH_GPU_ENABLE TRUE)
...@@ -125,6 +126,7 @@ message(STATUS "NGRAPH_GPU_ENABLE: ${NGRAPH_GPU_ENABLE}") ...@@ -125,6 +126,7 @@ message(STATUS "NGRAPH_GPU_ENABLE: ${NGRAPH_GPU_ENABLE}")
message(STATUS "NGRAPH_INTERPRETER_ENABLE: ${NGRAPH_INTERPRETER_ENABLE}") message(STATUS "NGRAPH_INTERPRETER_ENABLE: ${NGRAPH_INTERPRETER_ENABLE}")
message(STATUS "NGRAPH_NOP_ENABLE: ${NGRAPH_NOP_ENABLE}") message(STATUS "NGRAPH_NOP_ENABLE: ${NGRAPH_NOP_ENABLE}")
message(STATUS "NGRAPH_GPUH_ENABLE: ${NGRAPH_GPUH_ENABLE}") message(STATUS "NGRAPH_GPUH_ENABLE: ${NGRAPH_GPUH_ENABLE}")
message(STATUS "NGRAPH_GENERIC_CPU_ENABLE: ${NGRAPH_GENERIC_CPU_ENABLE}")
message(STATUS "NGRAPH_DISTRIBUTED_ENABLE: ${NGRAPH_DISTRIBUTED_ENABLE}") message(STATUS "NGRAPH_DISTRIBUTED_ENABLE: ${NGRAPH_DISTRIBUTED_ENABLE}")
message(STATUS "NGRAPH_DEBUG_ENABLE: ${NGRAPH_DEBUG_ENABLE}") message(STATUS "NGRAPH_DEBUG_ENABLE: ${NGRAPH_DEBUG_ENABLE}")
message(STATUS "NGRAPH_ONNX_IMPORT_ENABLE: ${NGRAPH_ONNX_IMPORT_ENABLE}") message(STATUS "NGRAPH_ONNX_IMPORT_ENABLE: ${NGRAPH_ONNX_IMPORT_ENABLE}")
......
...@@ -30,7 +30,7 @@ using namespace ngraph; ...@@ -30,7 +30,7 @@ using namespace ngraph;
void ngraph::default_logger_handler_func(const string& s) void ngraph::default_logger_handler_func(const string& s)
{ {
cout << s << endl; cout << s + "\n";
} }
LogHelper::LogHelper(LOG_TYPE type, LogHelper::LogHelper(LOG_TYPE type,
......
...@@ -37,6 +37,10 @@ if (NGRAPH_GPUH_ENABLE) ...@@ -37,6 +37,10 @@ if (NGRAPH_GPUH_ENABLE)
add_subdirectory(gpuh) add_subdirectory(gpuh)
endif() endif()
if (NGRAPH_GENERIC_CPU_ENABLE)
add_subdirectory(generic_cpu)
endif()
if (NGRAPH_PLAIDML_ENABLE) if (NGRAPH_PLAIDML_ENABLE)
add_subdirectory(plaidml) add_subdirectory(plaidml)
endif() endif()
# ******************************************************************************
# Copyright 2017-2018 Intel Corporation
#
# 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.
# ******************************************************************************
if (NGRAPH_GENERIC_CPU_ENABLE)
find_package(OpenMP)
if (OPENMP_FOUND)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
endif()
add_library(gcpu_backend SHARED gcpu_backend.cpp node_wrapper.cpp)
if(NGRAPH_LIB_VERSIONING_ENABLE)
set_target_properties(gcpu_backend PROPERTIES
VERSION ${NGRAPH_VERSION}
SOVERSION ${NGRAPH_API_VERSION})
endif()
target_link_libraries(gcpu_backend PRIVATE ngraph libeigen hybrid_base interpreter_backend)
target_compile_options(gcpu_backend PUBLIC -fopenmp)
set_target_properties(gcpu_backend PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${NGRAPH_BUILD_DIR})
install(TARGETS gcpu_backend
LIBRARY DESTINATION "${NGRAPH_INSTALL_LIB}"
ARCHIVE DESTINATION "${NGRAPH_INSTALL_LIB}"
)
endif()
This diff is collapsed.
This diff is collapsed.
//*****************************************************************************
// Copyright 2017-2018 Intel Corporation
//
// 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.
//*****************************************************************************
#pragma once
#include <Eigen/Dense>
#include <cmath>
#include <omp.h>
#include <utility>
#include "ngraph/runtime/reference/broadcast.hpp"
#include "ngraph/shape_util.hpp"
#include "ngraph/util.hpp"
namespace ngraph
{
namespace runtime
{
namespace gcpu
{
namespace kernel
{
std::tuple<size_t, size_t> get_start_finish(size_t size)
{
const size_t nthreads = omp_get_num_threads();
const size_t ithread = omp_get_thread_num();
const size_t start = ithread * size / nthreads;
const size_t finish = (ithread + 1) * size / nthreads;
return std::make_tuple(start, finish);
}
template <typename T>
void broadcast_2d(const T* in,
T* out,
const Shape& in_shape,
const Shape& out_shape,
const AxisSet& broadcast_axes)
{
size_t index[2];
size_t* out_index =
(broadcast_axes.find(0) == broadcast_axes.end() ? &index[0] : &index[1]);
for (index[0] = 0; index[0] < out_shape[0]; ++index[0])
{
for (index[1] = 0; index[1] < out_shape[1]; ++index[1])
{
out[index[0] * out_shape[1] + index[1]] = in[*out_index];
}
}
}
// #define PARALLEL
template <typename T>
void broadcast_3d(const T* in,
T* out,
const Shape& in_shape,
const Shape& out_shape,
const AxisSet& broadcast_axes)
{
#ifdef PARALLEL
#pragma omp parallel
#endif
{
size_t start;
size_t finish;
#ifdef PARALLEL
std::tie(start, finish) = get_start_finish(out_shape[0]);
#else
start = 0;
finish = out_shape[0];
#endif
size_t index[3];
size_t* out_index = 0;
for (size_t i = 0; i < 3; i++)
{
if (broadcast_axes.count(i) == 0)
{
out_index = &index[i];
break;
}
}
for (index[0] = start; index[0] < finish; ++index[0])
{
for (index[1] = 0; index[1] < out_shape[1]; ++index[1])
{
for (index[2] = 0; index[2] < out_shape[2]; ++index[2])
{
out[index[0] * out_shape[1] * out_shape[2] +
index[1] * out_shape[2] + index[2]] = in[*out_index];
}
}
}
}
}
template <typename T>
void broadcast_4d(const T* in,
T* out,
const Shape& in_shape,
const Shape& out_shape,
const AxisSet& broadcast_axes)
{
size_t index[4];
size_t* out_index = 0;
for (size_t i = 0; i < 4; i++)
{
if (broadcast_axes.count(i) == 0)
{
out_index = &index[i];
break;
}
}
for (index[0] = 0; index[0] < out_shape[0]; ++index[0])
{
for (index[1] = 0; index[1] < out_shape[1]; ++index[1])
{
for (index[2] = 0; index[2] < out_shape[2]; ++index[2])
{
for (index[3] = 0; index[3] < out_shape[3]; ++index[3])
{
out[index[0] * out_shape[1] * out_shape[2] * out_shape[3] +
index[1] * out_shape[2] * out_shape[3] +
index[2] * out_shape[3] + index[3]] = in[*out_index];
}
}
}
}
}
template <typename T>
void broadcast(const T* in,
T* out,
const Shape& in_shape,
const Shape& out_shape,
const AxisSet& broadcast_axes)
{
if (in_shape.size() == 0)
{
for (size_t i = 0; i < shape_size(out_shape); ++i)
{
out[i] = in[0];
}
}
else if (in_shape.size() == 1)
{
switch (out_shape.size())
{
case 2:
broadcast_2d<T>(in, out, in_shape, out_shape, broadcast_axes);
break;
case 3:
broadcast_3d<T>(in, out, in_shape, out_shape, broadcast_axes);
break;
case 4:
broadcast_4d<T>(in, out, in_shape, out_shape, broadcast_axes);
break;
}
}
else
{
runtime::reference::broadcast<T>(
in, out, in_shape, out_shape, broadcast_axes);
}
}
}
}
}
}
//*****************************************************************************
// Copyright 2017-2018 Intel Corporation
//
// 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.
//*****************************************************************************
#pragma once
#include <Eigen/Dense>
#include <cmath>
#include <omp.h>
#include <utility>
#include "ngraph/coordinate_transform.hpp"
#include "ngraph/shape_util.hpp"
namespace ngraph
{
namespace runtime
{
namespace gcpu
{
namespace kernel
{
template <typename T>
void dot(const T* arg0,
const T* arg1,
T* out,
const Shape& arg0_shape,
const Shape& arg1_shape,
const Shape& out_shape,
size_t reduction_axes_count)
{
if (arg0_shape.size() == 2 && arg1_shape.size() == 2 && out_shape.size() == 2)
{
Eigen::Map<
Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>>
a0(const_cast<T*>(arg0), arg0_shape[0], arg0_shape[1]);
Eigen::Map<
Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>>
a1(const_cast<T*>(arg1), arg1_shape[0], arg1_shape[1]);
Eigen::Map<
Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>>
o(const_cast<T*>(out), out_shape[0], out_shape[1]);
o = a0 * a1;
}
else
{
// Get the sizes of the dot axes. It's easiest to pull them from arg1 because they're
// right up front.
Shape dot_axis_sizes(reduction_axes_count);
std::copy(arg1_shape.begin(),
arg1_shape.begin() + reduction_axes_count,
dot_axis_sizes.begin());
CoordinateTransform arg0_transform(arg0_shape);
CoordinateTransform arg1_transform(arg1_shape);
CoordinateTransform output_transform(out_shape);
// Create coordinate transforms for arg0 and arg1 that throw away the dotted axes.
size_t arg0_projected_rank = arg0_shape.size() - reduction_axes_count;
size_t arg1_projected_rank = arg1_shape.size() - reduction_axes_count;
Shape arg0_projected_shape(arg0_projected_rank);
std::copy(arg0_shape.begin(),
arg0_shape.begin() + arg0_projected_rank,
arg0_projected_shape.begin());
Shape arg1_projected_shape(arg1_projected_rank);
std::copy(arg1_shape.begin() + reduction_axes_count,
arg1_shape.end(),
arg1_projected_shape.begin());
CoordinateTransform arg0_projected_transform(arg0_projected_shape);
CoordinateTransform arg1_projected_transform(arg1_projected_shape);
// Create a coordinate transform that allows us to iterate over all possible values
// for the dotted axes.
CoordinateTransform dot_axes_transform(dot_axis_sizes);
for (const Coordinate& arg0_projected_coord : arg0_projected_transform)
{
for (const Coordinate& arg1_projected_coord : arg1_projected_transform)
{
// The output coordinate is just the concatenation of the projected coordinates.
Coordinate out_coord(arg0_projected_coord.size() +
arg1_projected_coord.size());
auto out_coord_it = std::copy(arg0_projected_coord.begin(),
arg0_projected_coord.end(),
out_coord.begin());
std::copy(arg1_projected_coord.begin(),
arg1_projected_coord.end(),
out_coord_it);
// Zero out to start the sum.
T sum = 0;
size_t out_index = output_transform.index(out_coord);
// Walk along the dotted axes.
Coordinate arg0_coord(arg0_shape.size());
Coordinate arg1_coord(arg1_shape.size());
auto arg0_it = std::copy(arg0_projected_coord.begin(),
arg0_projected_coord.end(),
arg0_coord.begin());
for (const Coordinate& dot_axis_positions : dot_axes_transform)
{
// In order to find the points to multiply together, we need to inject our current
// positions along the dotted axes back into the projected arg0 and arg1 coordinates.
std::copy(dot_axis_positions.begin(),
dot_axis_positions.end(),
arg0_it);
auto arg1_it = std::copy(dot_axis_positions.begin(),
dot_axis_positions.end(),
arg1_coord.begin());
std::copy(arg1_projected_coord.begin(),
arg1_projected_coord.end(),
arg1_it);
// Multiply and add to the sum.
sum += arg0[arg0_transform.index(arg0_coord)] *
arg1[arg1_transform.index(arg1_coord)];
}
// Write the sum back.
out[out_index] = sum;
}
}
}
}
}
}
}
}
This diff is collapsed.
//*****************************************************************************
// Copyright 2017-2018 Intel Corporation
//
// 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.
//*****************************************************************************
#pragma once
#include <algorithm>
#include <cmath>
#include <numeric>
#include <vector>
#include "ngraph/shape.hpp"
namespace ngraph
{
namespace runtime
{
namespace gcpu
{
namespace kernel
{
template <typename T>
void result(const T* arg, T* out, size_t count)
{
memcpy(out, arg, sizeof(T) * count);
}
}
}
}
}
//*****************************************************************************
// Copyright 2017-2018 Intel Corporation
//
// 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.
//*****************************************************************************
#include "ngraph/runtime/generic_cpu/node_wrapper.hpp"
using namespace ngraph;
using namespace std;
runtime::gcpu::NodeWrapper::NodeWrapper(const shared_ptr<const Node>& node)
: m_node{node}
{
// This expands the op list in op_tbl.hpp into a list of enumerations that look like this:
// {"Abs", runtime::gcpu::OP_TYPEID::Abs},
// {"Acos", runtime::gcpu::OP_TYPEID::Acos},
// ...
#define NGRAPH_OP(a, b) {#a, runtime::gcpu::OP_TYPEID::a},
static unordered_map<string, runtime::gcpu::OP_TYPEID> typeid_map{
#include "ngraph/op/op_tbl.hpp"
};
#undef NGRAPH_OP
auto it = typeid_map.find(m_node->description());
if (it != typeid_map.end())
{
m_typeid = it->second;
}
else
{
throw unsupported_op("Unsupported op '" + m_node->description() + "'");
}
}
//*****************************************************************************
// Copyright 2017-2018 Intel Corporation
//
// 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.
//*****************************************************************************
#pragma once
#include <memory>
#include "ngraph/node.hpp"
namespace ngraph
{
namespace runtime
{
namespace gcpu
{
enum class OP_TYPEID;
class NodeWrapper;
}
}
}
// This expands the op list in op_tbl.hpp into a list of enumerations that look like this:
// Abs,
// Acos,
// ...
#define NGRAPH_OP(a, b) a,
enum class ngraph::runtime::gcpu::OP_TYPEID
{
#include "ngraph/op/op_tbl.hpp"
};
#undef NGRAPH_OP
/// \brief This class allows adding an enum typeid to each Node. This makes dealing with
/// collections of Nodes a little easier and faster as we can use switch() instead of
/// if/else statements
class ngraph::runtime::gcpu::NodeWrapper
{
public:
NodeWrapper(const std::shared_ptr<const ngraph::Node>& node);
const Node& get_node() const { return *m_node; }
ngraph::runtime::gcpu::OP_TYPEID get_typeid() const { return m_typeid; }
private:
std::shared_ptr<const ngraph::Node> m_node;
OP_TYPEID m_typeid;
};
...@@ -20,6 +20,7 @@ batch_norm_inference_f64 ...@@ -20,6 +20,7 @@ batch_norm_inference_f64
batch_norm_training_0eps_f64 batch_norm_training_0eps_f64
batch_norm_one_output batch_norm_one_output
batch_norm_three_outputs batch_norm_three_outputs
batch_norm_bprop_n4c3h2w2
dequantize dequantize
dequantize_axes dequantize_axes
dequantize_int32 dequantize_int32
......
...@@ -45,6 +45,9 @@ endif() ...@@ -45,6 +45,9 @@ endif()
if (NGRAPH_PLAIDML_ENABLE) if (NGRAPH_PLAIDML_ENABLE)
target_link_libraries(nbench plaidml_backend) target_link_libraries(nbench plaidml_backend)
endif() endif()
if (NGRAPH_GENERIC_CPU_ENABLE)
target_link_libraries(nbench gcpu_backend)
endif()
if (NGRAPH_DISTRIBUTED_ENABLE) if (NGRAPH_DISTRIBUTED_ENABLE)
target_compile_definitions(nbench PRIVATE NGRAPH_DISTRIBUTED) target_compile_definitions(nbench PRIVATE NGRAPH_DISTRIBUTED)
......
...@@ -15,7 +15,9 @@ ...@@ -15,7 +15,9 @@
//***************************************************************************** //*****************************************************************************
#include <random> #include <random>
#ifdef __i386__
#include <xmmintrin.h> #include <xmmintrin.h>
#endif
#include "benchmark.hpp" #include "benchmark.hpp"
#include "ngraph/file_util.hpp" #include "ngraph/file_util.hpp"
...@@ -107,53 +109,20 @@ void init_real_tv(shared_ptr<runtime::Tensor> tv, T min, T max) ...@@ -107,53 +109,20 @@ void init_real_tv(shared_ptr<runtime::Tensor> tv, T min, T max)
static void random_init(shared_ptr<runtime::Tensor> tv) static void random_init(shared_ptr<runtime::Tensor> tv)
{ {
element::Type et = tv->get_element_type(); element::Type et = tv->get_element_type();
if (et == element::boolean) switch (et.get_type_enum())
{ {
init_int_tv<char>(tv, 0, 1); case element::Type_t::boolean: init_int_tv<char>(tv, 0, 1); break;
} case element::Type_t::f32: init_real_tv<float>(tv, -1, 1); break;
else if (et == element::f32) case element::Type_t::f64: init_real_tv<double>(tv, -1, 1); break;
{ case element::Type_t::i8: init_int_tv<int8_t>(tv, -1, 1); break;
init_real_tv<float>(tv, -1, 1); case element::Type_t::i16: init_int_tv<int16_t>(tv, -1, 1); break;
} case element::Type_t::i32: init_int_tv<int32_t>(tv, 0, 1); break;
else if (et == element::f64) case element::Type_t::i64: init_int_tv<int64_t>(tv, -1, 1); break;
{ case element::Type_t::u8: init_int_tv<uint8_t>(tv, 0, 1); break;
init_real_tv<double>(tv, -1, 1); case element::Type_t::u16: init_int_tv<uint16_t>(tv, 0, 1); break;
} case element::Type_t::u32: init_int_tv<uint32_t>(tv, 0, 1); break;
else if (et == element::i8) case element::Type_t::u64: init_int_tv<uint64_t>(tv, 0, 1); break;
{ default: throw runtime_error("unsupported type");
init_int_tv<int8_t>(tv, -1, 1);
}
else if (et == element::i16)
{
init_int_tv<int16_t>(tv, -1, 1);
}
else if (et == element::i32)
{
init_int_tv<int32_t>(tv, 0, 1);
}
else if (et == element::i64)
{
init_int_tv<int64_t>(tv, -1, 1);
}
else if (et == element::u8)
{
init_int_tv<uint8_t>(tv, 0, 1);
}
else if (et == element::u16)
{
init_int_tv<uint16_t>(tv, 0, 1);
}
else if (et == element::u32)
{
init_int_tv<uint32_t>(tv, 0, 1);
}
else if (et == element::u64)
{
init_int_tv<uint64_t>(tv, 0, 1);
}
else
{
throw runtime_error("unsupported type");
} }
} }
......
...@@ -106,6 +106,10 @@ if (NGRAPH_PLAIDML_ENABLE) ...@@ -106,6 +106,10 @@ if (NGRAPH_PLAIDML_ENABLE)
set(ACTIVE_BACKEND_LIST ${ACTIVE_BACKEND_LIST} PlaidML) set(ACTIVE_BACKEND_LIST ${ACTIVE_BACKEND_LIST} PlaidML)
endif() endif()
if (NGRAPH_GENERIC_CPU_ENABLE)
set(ACTIVE_BACKEND_LIST ${ACTIVE_BACKEND_LIST} GCPU)
endif()
add_subdirectory(models) add_subdirectory(models)
add_subdirectory(files) add_subdirectory(files)
add_subdirectory(util) add_subdirectory(util)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment