Unverified Commit b949da7f authored by Paul Fultz II's avatar Paul Fultz II Committed by GitHub
Browse files

Add C and C++ api (#430)



* Add initial api

* Formatting

* Add more api

* Formatting

* Add auto api generation

* Formatting

* Fix some compilation errors

* Change handle struct

* Formatting

* Fix reamining compilation errors

* Formatting

* Simplify using ctype

* Formatting

* Initial c++ generation

* Formatting

* Add C++header

* Formatting

* Add test

* Formatting

* Add initial tests

* Formatting

* Try to fix formatting

* Cleanup formatting

* Formatting

* Fix constructors on the same line

* Fix tests

* Formatting

* Fix tidy issues

* Fix tidy issues

* Fix naming issue

* Add onnx API to parse buffer

* Formatting

* Add arguments api

* Formatting

* Fix verify parameters

* Fix cppcheck issues

* Formatting

* Add method to get output shapes and bytes

* Formatting

* Try formatting

* Formatting

* Improve the test coverage

* Formatting

* Add print method

* Formatting

* Fix cppcheck issue

* Fix package dependency

* Add nolint

* Try fix formatting

* Formatting

* formatting

* formatting

* Fix formatting
Co-authored-by: default avatarShucai Xiao <shucai.xiao@amd.com>
Co-authored-by: default avatarkahmed10 <15948690+kahmed10@users.noreply.github.com>
parent 24f74e72
......@@ -57,6 +57,15 @@ TEST_CASE(operation_copy_test)
EXPECT(op2 == op1);
}
TEST_CASE(operation_copy_assign_test)
{
simple_operation s{};
migraphx::operation op;
op = s;
// cppcheck-suppress duplicateExpression
EXPECT(s == op);
}
TEST_CASE(operation_equal_test)
{
simple_operation s{};
......
This diff is collapsed.
#include <migraphx/migraphx.h>
#include <migraphx/rank.hpp>
#include <migraphx/shape.hpp>
#include <migraphx/program.hpp>
#include <migraphx/onnx.hpp>
#include <migraphx/target.hpp>
#include <migraphx/generate.hpp>
#include <migraphx/cpu/target.hpp>
#ifdef HAVE_GPU
#include <migraphx/gpu/target.hpp>
#endif
namespace migraphx {
template <class F>
migraphx_status try_(F f, bool output = true) // NOLINT
{
try
{
f();
}
catch(const migraphx::exception& ex)
{
if(output)
std::cerr << "MIGraphX Error: " << ex.what() << std::endl;
if(ex.error > 0)
return migraphx_status(ex.error);
else
return migraphx_status_unknown_error;
}
catch(const std::exception& ex)
{
if(output)
std::cerr << "MIGraphX Error: " << ex.what() << std::endl;
return migraphx_status_unknown_error;
}
catch(...)
{
return migraphx_status_unknown_error;
}
return migraphx_status_success;
}
shape::type_t to_shape_type(migraphx_shape_datatype_t t)
{
switch(t)
{
#define MIGRAPHX_DETAIL_SHAPE_CASE_CONVERT(x, y) \
case migraphx_shape_##x: return shape::x;
MIGRAPHX_SHAPE_VISIT_TYPES(MIGRAPHX_DETAIL_SHAPE_CASE_CONVERT)
#undef MIGRAPHX_DETAIL_SHAPE_CASE_CONVERT
}
MIGRAPHX_THROW(migraphx_status_bad_param, "Unknown type");
}
migraphx_shape_datatype_t to_shape_type(shape::type_t t)
{
switch(t)
{
#define MIGRAPHX_DETAIL_SHAPE_CASE_CONVERT(x, y) \
case shape::x: return migraphx_shape_##x;
MIGRAPHX_SHAPE_VISIT_TYPES(MIGRAPHX_DETAIL_SHAPE_CASE_CONVERT)
#undef MIGRAPHX_DETAIL_SHAPE_CASE_CONVERT
}
MIGRAPHX_THROW(migraphx_status_bad_param, "Unknown type");
}
target get_target(const std::string& name)
{
migraphx::target t;
if(name == "cpu")
t = migraphx::cpu::target();
#ifdef HAVE_GPU
else if(name == "gpu")
t = migraphx::gpu::target();
#endif
else
MIGRAPHX_THROW(migraphx_status_unknown_target, "Unknown target: " + name);
return t;
}
migraphx::compile_options to_compile_options(const migraphx_compile_options& options)
{
migraphx::compile_options result{};
result.offload_copy = options.offload_copy;
return result;
}
migraphx::onnx_options to_onnx_options(const migraphx_onnx_options& options)
{
migraphx::onnx_options result{};
result.batch_size = options.batch_size;
return result;
}
template <class Value>
std::vector<const char*> get_names(const std::unordered_map<std::string, Value>& m)
{
std::vector<const char*> result;
std::transform(
m.begin(), m.end(), std::back_inserter(result), [](auto&& p) { return p.first.c_str(); });
return result;
}
template <class T>
bool equal(const T& x, const T& y)
{
return x == y;
}
std::vector<argument> run(program& p, const program::parameter_map& params)
{
auto a = p.eval(params);
return {a};
}
std::vector<shape> get_output_shapes(program& p)
{
auto a = p.get_shape();
return {a};
}
void print(const program& p) { std::cout << p << std::endl; }
} // namespace migraphx
<% generate_c_api_body() %>
#ifndef MIGRAPHX_GUARD_C_API_MIGRAPHX_H
#define MIGRAPHX_GUARD_C_API_MIGRAPHX_H
#include <stdlib.h>
// Add new types here
// clang-format off
#define MIGRAPHX_SHAPE_VISIT_TYPES(m) \
m(half_type, half) \
m(float_type, float) \
m(double_type, double) \
m(uint8_type, uint8_t) \
m(int8_type, int8_t) \
m(uint16_type, uint16_t) \
m(int16_type, int16_t) \
m(int32_type, int32_t) \
m(int64_type, int64_t) \
m(uint32_type, uint32_t) \
m(uint64_type, uint64_t)
// clang-format on
#ifdef __cplusplus
extern "C" {
#endif
// return code, more to be added later
typedef enum {
migraphx_status_success = 0,
migraphx_status_bad_param = 1,
migraphx_status_unknown_target = 3,
migraphx_status_unknown_error = 4,
} migraphx_status;
#define MIGRAPHX_SHAPE_GENERATE_ENUM_TYPES(x, t) migraphx_shape_##x,
typedef enum {
MIGRAPHX_SHAPE_VISIT_TYPES(MIGRAPHX_SHAPE_GENERATE_ENUM_TYPES)
} migraphx_shape_datatype_t;
#undef MIGRAPHX_SHAPE_GENERATE_ENUM_TYPES
typedef struct
{
bool offload_copy;
} migraphx_compile_options;
typedef struct
{
size_t batch_size;
} migraphx_onnx_options;
<% generate_c_header() %>
#ifdef __cplusplus
}
#endif
#endif
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
ls -1 $DIR/include/ | xargs -n 1 -P $(nproc) -I{} -t bash -c "python3.6 $DIR/te.py $DIR/include/{} | clang-format-5.0 -style=file > $DIR/../src/include/migraphx/{}"
SRC_DIR=$DIR/../src
ls -1 $DIR/include/ | xargs -n 1 -P $(nproc) -I{} -t bash -c "python3.6 $DIR/te.py $DIR/include/{} | clang-format-5.0 -style=file > $SRC_DIR/include/migraphx/{}"
function api {
python3.6 $DIR/api.py $SRC_DIR/api/migraphx.py $1 | clang-format-5.0 -style=file > $2
}
api $DIR/api/migraphx.h $SRC_DIR/api/include/migraphx/migraphx.h
api $DIR/api/api.cpp $SRC_DIR/api/api.cpp
......@@ -41,10 +41,17 @@ struct ${struct_name}
template <typename PrivateDetailTypeErasedT>
${struct_name} & operator= (PrivateDetailTypeErasedT value)
{
if (private_detail_te_handle_mem_var.unique())
*private_detail_te_handle_mem_var = std::forward<PrivateDetailTypeErasedT>(value);
else if (!private_detail_te_handle_mem_var)
private_detail_te_handle_mem_var = std::make_shared<PrivateDetailTypeErasedT>(std::forward<PrivateDetailTypeErasedT>(value));
using std::swap;
auto * derived = this->any_cast<PrivateDetailTypeErasedT>();
if(derived and private_detail_te_handle_mem_var.unique())
{
*derived = std::forward<PrivateDetailTypeErasedT>(value);
}
else
{
${struct_name} rhs(value);
swap(private_detail_te_handle_mem_var, rhs.private_detail_te_handle_mem_var);
}
return *this;
}
......@@ -52,7 +59,7 @@ struct ${struct_name}
template<typename PrivateDetailTypeErasedT>
PrivateDetailTypeErasedT * any_cast()
{
return private_detail_te_get_handle().type() == typeid(PrivateDetailTypeErasedT) ?
return this->type_id() == typeid(PrivateDetailTypeErasedT) ?
std::addressof(static_cast<private_detail_te_handle_type<typename std::remove_cv<PrivateDetailTypeErasedT>::type> &>(private_detail_te_get_handle()).private_detail_te_value) :
nullptr;
}
......@@ -60,7 +67,7 @@ struct ${struct_name}
template<typename PrivateDetailTypeErasedT>
const typename std::remove_cv<PrivateDetailTypeErasedT>::type * any_cast() const
{
return private_detail_te_get_handle().type() == typeid(PrivateDetailTypeErasedT) ?
return this->type_id() == typeid(PrivateDetailTypeErasedT) ?
std::addressof(static_cast<const private_detail_te_handle_type<typename std::remove_cv<PrivateDetailTypeErasedT>::type> &>(private_detail_te_get_handle()).private_detail_te_value) :
nullptr;
}
......
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