714 lines
23 KiB
C++
714 lines
23 KiB
C++
// Copyright (c) 2021 CINN Authors. All Rights Reserved.
|
|
//
|
|
// 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.
|
|
|
|
/**
|
|
* This file contains some core runtime concepts, the basic definition is used
|
|
* in C so that it can be deployed in some light-weight devices.
|
|
*/
|
|
#ifndef CINN_RUNTIME_CINN_RUNTIME_H_
|
|
#define CINN_RUNTIME_CINN_RUNTIME_H_
|
|
#ifdef __cplusplus
|
|
#pragma once
|
|
#endif
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#ifdef __cplusplus
|
|
#include <functional>
|
|
#include <vector>
|
|
#endif
|
|
|
|
#ifndef CINN_COMMON_FLOAT16_H
|
|
#include "paddle/cinn/common/float16.h"
|
|
#endif // CINN_COMMON_FLOAT16_H
|
|
|
|
#ifndef CINN_COMMON_BFLOAT16_H
|
|
#include "paddle/cinn/common/bfloat16.h"
|
|
#endif // CINN_COMMON_BFLOAT16_H
|
|
|
|
#ifndef CINN_COMMON_FLOAT8E4M3_H
|
|
#include "paddle/cinn/common/float8e4m3.h"
|
|
#endif // CINN_COMMON_FLOAT8E4M3_H
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#define CINN_ALWAYS_INLINE __attribute__((always_inline)) inline
|
|
|
|
//! Code for the primitive types supported in CINN.
|
|
typedef enum cinn_type_code_t {
|
|
cinn_type_unk = -1, //! Unknown type
|
|
cinn_type_int = 0, //! signed int
|
|
cinn_type_uint = 1, //! unsigned int
|
|
cinn_type_float = 2, //! floating point
|
|
cinn_type_handle = 3, //! void*
|
|
cinn_type_bfloat = 4, //! bfloat16
|
|
cinn_type_float8e4m3 = 5 //! float8e4m3
|
|
} cinn_type_code_t;
|
|
|
|
#ifndef CINN_ATTRIBUTE_ALIGN
|
|
#define CINN_ATTRIBUTE_ALIGN(n) __attribute__((aligned(n)))
|
|
#endif
|
|
|
|
/**
|
|
* A runtime tag for type in CINN system.
|
|
*/
|
|
typedef struct cinn_type_t {
|
|
#if __cplusplus >= 201103L
|
|
CINN_ATTRIBUTE_ALIGN(1) cinn_type_code_t code;
|
|
#else
|
|
uint8_t code;
|
|
#endif
|
|
|
|
//! Number of bits.
|
|
uint8_t bits;
|
|
|
|
//! Number of elements in a vector, 1 for scalar.
|
|
uint16_t lanes;
|
|
|
|
//! Number of '*', e.g. for `float*`, the num_asterisks is 1, `float**` it
|
|
//! is 2.
|
|
uint8_t num_asterisks{0};
|
|
|
|
#ifdef __cplusplus
|
|
CINN_ALWAYS_INLINE cinn_type_t() : code(cinn_type_int), bits(0), lanes(0) {}
|
|
CINN_ALWAYS_INLINE cinn_type_t(cinn_type_code_t code,
|
|
uint8_t bits,
|
|
uint16_t lanes = 1,
|
|
uint8_t num_asterisks = 0)
|
|
: code(code), bits(bits), lanes(lanes), num_asterisks(num_asterisks) {}
|
|
CINN_ALWAYS_INLINE bool operator==(const cinn_type_t& other) const {
|
|
return code == other.code && bits == other.bits && lanes == other.lanes;
|
|
}
|
|
CINN_ALWAYS_INLINE bool operator!=(const cinn_type_t& other) const {
|
|
return !(*this == other);
|
|
}
|
|
CINN_ALWAYS_INLINE uint16_t bytes() const { return (bits + 7) / 8; }
|
|
#endif // __cplusplus
|
|
} cinn_type_t;
|
|
|
|
//! Some primitive types.
|
|
// @{
|
|
extern cinn_type_t cinn_unk_t();
|
|
extern cinn_type_t cinn_bool_t(int num_asterisks = 0);
|
|
|
|
extern cinn_type_t cinn_int8_t(int num_asterisks = 0);
|
|
extern cinn_type_t cinn_int16_t(int num_asterisks = 0);
|
|
extern cinn_type_t cinn_int32_t(int num_asterisks = 0);
|
|
extern cinn_type_t cinn_int64_t(int num_asterisks = 0);
|
|
|
|
extern cinn_type_t cinn_uint8_t(int num_asterisks = 0);
|
|
extern cinn_type_t cinn_uint16_t(int num_asterisks = 0);
|
|
extern cinn_type_t cinn_uint32_t(int num_asterisks = 0);
|
|
extern cinn_type_t cinn_uint64_t(int num_asterisks = 0);
|
|
|
|
extern cinn_type_t cinn_bfloat16_t(int num_asterisks = 0);
|
|
extern cinn_type_t cinn_float8e4m3_t(int num_asterisks = 0);
|
|
extern cinn_type_t cinn_float16_t(int num_asterisks = 0);
|
|
extern cinn_type_t cinn_float32_t(int num_asterisks = 0);
|
|
extern cinn_type_t cinn_float64_t(int num_asterisks = 0);
|
|
extern int cinn_host_abs_int32(int v);
|
|
extern int64_t cinn_host_abs_int64(int64_t v);
|
|
// @}
|
|
|
|
//! Help to define the size of a dimension, due to polyhedral representation, we
|
|
//! no need to record the extend or min(default to 0).
|
|
typedef int cinn_dimension_t;
|
|
|
|
//! Help to tell the kind of the device.
|
|
typedef enum cinn_device_kind_t {
|
|
cinn_unk_device = -1, // Undefined device.
|
|
cinn_x86_device = 0, // X86 device
|
|
cinn_opencl_device = 1, // OpenCL device
|
|
cinn_arm_device = 2, // ARM device
|
|
cinn_nvgpu_device = 3, // NVIDIA GPU device
|
|
cinn_custom_device = 4 // custom device
|
|
} cinn_device_kind_t;
|
|
|
|
//! Help to tell where the buffer locates.
|
|
typedef enum cinn_buffer_kind_t {
|
|
cinn_buffer_on_host = 0, //! buffer on host
|
|
cinn_buffer_on_device = 1 << 1 // ! buffer on device e.g. GPU.
|
|
} cinn_buffer_kind_t;
|
|
|
|
struct cinn_buffer_t;
|
|
|
|
/**
|
|
* All CINN backends implementation should provide an interface to be used.
|
|
*/
|
|
struct cinn_device_interface_impl_t;
|
|
|
|
struct cinn_device_interface_t {
|
|
int (*malloc)(void* context, struct cinn_buffer_t* buf);
|
|
int (*free)(void* context, struct cinn_buffer_t* buf);
|
|
int (*sync)(void* context, struct cinn_buffer_t* buf);
|
|
int (*release)(void* context,
|
|
const struct cinn_device_interface_t* device_interface);
|
|
int (*copy_to_host)(void* context, struct cinn_buffer_t* buf);
|
|
int (*copy_to_device)(void* context, struct cinn_buffer_t* buf);
|
|
int (*buffer_copy)(void* context,
|
|
struct cinn_buffer_t* src,
|
|
struct cinn_buffer_t* dst);
|
|
struct cinn_device_interface_impl_t* impl;
|
|
};
|
|
|
|
/**
|
|
* Release all data associated with the given interface.
|
|
*/
|
|
extern int cinn_device_release(
|
|
void* context, const struct cinn_device_interface_t* device_interface);
|
|
|
|
/*
|
|
* Copy image data from device to host memory.
|
|
*/
|
|
extern int cinn_buffer_copy_to_host(void* context, struct cinn_buffer_t* buf);
|
|
|
|
//! Copy data from host to device memory.
|
|
extern int cinn_buffer_copy_to_device(void* context, struct cinn_buffer_t* buf);
|
|
|
|
//! Copy data from one buffer to another.
|
|
extern int cinn_buffer_copy(void* context,
|
|
struct cinn_buffer_t* src,
|
|
struct cinn_buffer_t* dst);
|
|
|
|
//! Wait for current device operations to complete.
|
|
extern int cinn_device_sync(void* context, struct cinn_buffer_t* buf);
|
|
|
|
//! Allocate device memory.
|
|
extern int cinn_buffer_malloc(void* context, struct cinn_buffer_t* buf);
|
|
|
|
//! Free device memory.
|
|
extern int cinn_buffer_free(void* context, struct cinn_buffer_t* buf);
|
|
|
|
//! Get the memory address in buffer.
|
|
extern void* cinn_buffer_get_data_handle(struct cinn_buffer_t* buf);
|
|
extern void* cinn_buffer_get_data_const_handle(const struct cinn_buffer_t* buf);
|
|
|
|
//! Create a new default cinn_buffer.
|
|
extern cinn_buffer_t* cinn_buffer_new_default(int target,
|
|
uint64_t memory_size,
|
|
int align = 32);
|
|
|
|
//! The raw representation of a buffer,used in the generated code/lib.
|
|
#define CINN_BUFFER_MAX_DIMS 8
|
|
typedef struct cinn_buffer_t {
|
|
//! Tell which kind of device this buffer locates.
|
|
cinn_device_kind_t device;
|
|
|
|
//! The interface used to operate on device.
|
|
const struct cinn_device_interface_t* device_interface;
|
|
|
|
//! A pointer to the memory in host.
|
|
uint8_t* memory;
|
|
|
|
//! Extra flags.
|
|
uint64_t flag;
|
|
|
|
//! Data type.
|
|
cinn_type_t type;
|
|
|
|
//! Number of dimensions.
|
|
int32_t dimensions;
|
|
cinn_dimension_t dims[CINN_BUFFER_MAX_DIMS];
|
|
|
|
//! Allocate and deallocate lazily, default true.
|
|
char lazy;
|
|
|
|
//! The actual memory size(in bytes).
|
|
uint64_t memory_size;
|
|
|
|
uint16_t align;
|
|
|
|
#ifdef __cplusplus
|
|
cinn_buffer_t()
|
|
: device(cinn_unk_device),
|
|
device_interface(NULL),
|
|
memory(NULL),
|
|
flag(0UL),
|
|
type(cinn_type_t()),
|
|
dimensions(0),
|
|
lazy(true),
|
|
memory_size(0),
|
|
align(0),
|
|
external_malloc(NULL),
|
|
external_free(NULL) {}
|
|
|
|
static struct cinn_buffer_t* new_(cinn_device_kind_t device,
|
|
cinn_type_t type,
|
|
const std::vector<int>& shape,
|
|
int align = 0);
|
|
static void delete_(struct cinn_buffer_t* x) { delete x; }
|
|
|
|
~cinn_buffer_t() {
|
|
if (external_malloc != NULL) {
|
|
delete external_malloc;
|
|
}
|
|
if (external_free != NULL) {
|
|
delete external_free;
|
|
}
|
|
}
|
|
|
|
// NOTE the buffer should be resized first.
|
|
static void alloc(struct cinn_buffer_t*);
|
|
|
|
//! Set the shape of the buffer. NOTE this just record the shape, not allocate
|
|
//! the memory.
|
|
CINN_ALWAYS_INLINE void resize(const cinn_dimension_t* dims, int dimensions) {
|
|
this->dimensions = dimensions;
|
|
memcpy(this->dims, dims, dimensions * sizeof(cinn_dimension_t));
|
|
}
|
|
|
|
CINN_ALWAYS_INLINE uint64_t num_elements() const {
|
|
uint64_t res = 1;
|
|
for (int i = 0; i < dimensions; i++) {
|
|
res *= dims[i];
|
|
}
|
|
return res;
|
|
}
|
|
|
|
CINN_ALWAYS_INLINE bool on_host() const {
|
|
return get_flag(cinn_buffer_on_host);
|
|
}
|
|
CINN_ALWAYS_INLINE bool on_device() const {
|
|
return get_flag(cinn_buffer_on_device);
|
|
}
|
|
CINN_ALWAYS_INLINE void set_on_host(bool x = true) {
|
|
set_flag(cinn_buffer_on_host, x);
|
|
}
|
|
CINN_ALWAYS_INLINE void set_on_device(bool x = true) {
|
|
set_flag(cinn_buffer_on_device, x);
|
|
}
|
|
|
|
CINN_ALWAYS_INLINE int device_sync(void* ctx = NULL) {
|
|
if (device_interface && device_interface->sync) {
|
|
return device_interface->sync(ctx, this);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
CINN_ALWAYS_INLINE uint8_t* begin() const { return 0; }
|
|
CINN_ALWAYS_INLINE uint8_t* end() const {
|
|
return memory + num_elements() * type.bytes();
|
|
}
|
|
|
|
CINN_ALWAYS_INLINE bool get_flag(cinn_buffer_kind_t flag) const {
|
|
return (this->flag & flag) != 0;
|
|
}
|
|
CINN_ALWAYS_INLINE void set_flag(cinn_buffer_kind_t flag, bool value) {
|
|
if (value)
|
|
this->flag |= flag;
|
|
else
|
|
this->flag &= ~flag;
|
|
}
|
|
|
|
// The callback to control memory alloc. It is useful in Paddle-CINN
|
|
// where the memory is managed out of CINN.
|
|
std::function<int(void*, struct cinn_buffer_t*)>* external_malloc;
|
|
|
|
// The callback to control memory free. It is useful in Paddle-CINN
|
|
// where the memory is managed out of CINN.
|
|
std::function<int(void*, struct cinn_buffer_t*)>* external_free;
|
|
|
|
#endif // __cplusplus
|
|
} cinn_buffer_t;
|
|
|
|
#ifdef __cplusplus
|
|
//! Create a new cinn_buffer.
|
|
cinn_buffer_t* cinn_buffer_new(cinn_device_kind_t device,
|
|
cinn_type_t type,
|
|
const std::vector<int>& shape,
|
|
int align = 0);
|
|
|
|
struct cinn_device_interface_impl_t {
|
|
int (*malloc)(void* context, struct cinn_buffer_t* buf);
|
|
int (*free)(void* context, struct cinn_buffer_t* buf);
|
|
int (*sync)(void* context, struct cinn_buffer_t* buf);
|
|
int (*release)(void* context);
|
|
int (*copy_to_host)(void* context, struct cinn_buffer_t* buf);
|
|
int (*copy_to_device)(void* context, struct cinn_buffer_t* buf);
|
|
int (*buffer_copy)(void* context,
|
|
struct cinn_buffer_t* src,
|
|
struct cinn_buffer_t* dst);
|
|
};
|
|
|
|
// The device implementations
|
|
extern struct cinn_device_interface_t* cinn_x86_device_interface();
|
|
|
|
inline cinn::common::bfloat16 cinn_buffer_load_bfloat16(
|
|
struct cinn_buffer_t* buf, uint32_t index) {
|
|
return ((cinn::common::bfloat16*)buf->memory)[index]; // NOLINT
|
|
}
|
|
inline cinn::common::float8e4m3 cinn_buffer_load_float8e4m3(
|
|
struct cinn_buffer_t* buf, uint32_t index) {
|
|
return ((cinn::common::float8e4m3*)buf->memory)[index]; // NOLINT
|
|
}
|
|
inline cinn::common::float16 cinn_buffer_load_float16(struct cinn_buffer_t* buf,
|
|
uint32_t index) {
|
|
return ((cinn::common::float16*)buf->memory)[index]; // NOLINT
|
|
}
|
|
inline float cinn_buffer_load_float32(struct cinn_buffer_t* buf,
|
|
uint32_t index) {
|
|
return ((float*)buf->memory)[index]; // NOLINT
|
|
}
|
|
inline double cinn_buffer_load_float64(struct cinn_buffer_t* buf,
|
|
uint32_t index) {
|
|
return ((double*)buf->memory)[index]; // NOLINT
|
|
}
|
|
#endif // __cplusplus
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
CINN_ALWAYS_INLINE void* cinn_buffer_slice(struct cinn_buffer_t* buf,
|
|
uint32_t offset);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
static inline int32_t cinn_min(int32_t a, int32_t b) { return a < b ? a : b; }
|
|
static inline int32_t cinn_max(int32_t a, int32_t b) { return a > b ? a : b; }
|
|
|
|
#ifdef __cplusplus
|
|
} // extern "C"
|
|
#endif
|
|
|
|
#ifndef CINN_RUNTIME_NOT_IMPLEMENTED
|
|
#define CINN_RUNTIME_NOT_IMPLEMENTED \
|
|
do { \
|
|
fprintf(stderr, "Not Implemented!"); \
|
|
abort(); \
|
|
} while (false);
|
|
#endif
|
|
|
|
#define ASSERT_NOT_NULL(v__) \
|
|
if (!v__) { \
|
|
fprintf(stderr, #v__ " is null"); \
|
|
return -1; \
|
|
}
|
|
#define CINN_LOG(fmt, ...) \
|
|
do { \
|
|
fprintf(stderr, \
|
|
"%s:%d:%s(): " fmt, \
|
|
__FILE__, \
|
|
__LINE__, \
|
|
__func__, \
|
|
__VA_ARGS__); \
|
|
} while (0)
|
|
|
|
#define CINN_CHECK(cond) \
|
|
if (!(cond)) { \
|
|
CINN_LOG("check %s failed", #cond); \
|
|
abort(); \
|
|
}
|
|
#define CINN_CHECK_LT(a, b) \
|
|
if (!(a < b)) { \
|
|
cinn_print_debug_string("check %d > %d failed", a, b); \
|
|
abort(); \
|
|
}
|
|
#define CINN_CHECKP(cond, ...) \
|
|
if (!(cond)) { \
|
|
CINN_LOG(__VA_ARGS__); \
|
|
abort(); \
|
|
}
|
|
#define CINN_CHECK_EQ(a, b) \
|
|
{ \
|
|
if ((a) != (b)) { \
|
|
CINN_LOG("check %s == %s failed, %d != %d", #a, #b, (a), b); \
|
|
abort(); \
|
|
} \
|
|
} \
|
|
while (false) \
|
|
; // NOLINT
|
|
|
|
#endif // CINN_RUNTIME_CINN_RUNTIME_H_
|
|
|
|
union cinn_value_t {
|
|
int64_t v_int64;
|
|
double v_float64;
|
|
void* v_handle;
|
|
char* v_str;
|
|
};
|
|
|
|
struct cinn_pod_value_t {
|
|
#ifdef __cplusplus
|
|
// @{ PodValue
|
|
|
|
cinn_pod_value_t() = default;
|
|
|
|
cinn_pod_value_t(cinn_value_t value, int type_code);
|
|
explicit cinn_pod_value_t(cinn_buffer_t* value);
|
|
explicit cinn_pod_value_t(bool value);
|
|
|
|
explicit cinn_pod_value_t(int8_t value);
|
|
explicit cinn_pod_value_t(int16_t value);
|
|
explicit cinn_pod_value_t(int32_t value);
|
|
explicit cinn_pod_value_t(int64_t value);
|
|
|
|
explicit cinn_pod_value_t(uint8_t value);
|
|
explicit cinn_pod_value_t(uint16_t value);
|
|
explicit cinn_pod_value_t(uint32_t value);
|
|
explicit cinn_pod_value_t(uint64_t value);
|
|
|
|
explicit cinn_pod_value_t(float value);
|
|
explicit cinn_pod_value_t(double value);
|
|
explicit cinn_pod_value_t(cinn::common::bfloat16 value);
|
|
explicit cinn_pod_value_t(cinn::common::float8e4m3 value);
|
|
explicit cinn_pod_value_t(cinn::common::float16 value);
|
|
|
|
explicit cinn_pod_value_t(void* value);
|
|
explicit cinn_pod_value_t(const char* value);
|
|
|
|
//! The value getters for the supported types.
|
|
//@{
|
|
operator double() const;
|
|
operator float() const;
|
|
operator cinn::common::bfloat16() const;
|
|
operator cinn::common::float8e4m3() const;
|
|
operator cinn::common::float16() const;
|
|
|
|
operator bool() const;
|
|
|
|
operator int8_t() const;
|
|
operator int16_t() const;
|
|
operator int32_t() const;
|
|
operator int64_t() const;
|
|
|
|
operator uint8_t() const;
|
|
operator uint16_t() const;
|
|
operator uint32_t() const;
|
|
operator uint64_t() const;
|
|
|
|
operator void*() const;
|
|
operator cinn_buffer_t*() const;
|
|
operator char*() const;
|
|
//@}
|
|
|
|
int type_code() const { return type_code_; }
|
|
|
|
void* data_addr() const;
|
|
|
|
void set_type_code(int x) { type_code_ = x; }
|
|
void set_value(union cinn_value_t x) { value_ = x; }
|
|
|
|
protected:
|
|
// @}
|
|
#endif // __cplusplus
|
|
int type_code_;
|
|
union cinn_value_t value_;
|
|
};
|
|
|
|
#ifdef __cplusplus
|
|
template <typename T>
|
|
constexpr int cinn_type_code();
|
|
|
|
//! Implement the type_code for all the supported types.
|
|
// @{
|
|
#define __m(T, code__) \
|
|
template <> \
|
|
constexpr int cinn_type_code<T>() { \
|
|
return code__; \
|
|
}
|
|
__m(int32_t, 0);
|
|
__m(int64_t, 1);
|
|
__m(float, 2);
|
|
__m(double, 3);
|
|
__m(void*, 4);
|
|
__m(char*, 5);
|
|
__m(char const*, 6);
|
|
__m(cinn_buffer_t*, 7);
|
|
__m(int8_t, 8);
|
|
__m(bool, 9);
|
|
__m(cinn::common::float16, 10);
|
|
__m(int16_t, 11);
|
|
__m(uint8_t, 12);
|
|
__m(uint16_t, 13);
|
|
__m(uint32_t, 14);
|
|
__m(uint64_t, 15);
|
|
__m(cinn::common::bfloat16, 16);
|
|
__m(cinn::common::float8e4m3, 17);
|
|
#undef __m
|
|
//@}
|
|
#endif // __cplusplus
|
|
|
|
typedef struct cinn_pod_value_t cinn_pod_value_t;
|
|
|
|
// the LoweredFunc pointer type for JIT usage.
|
|
typedef void (*lower_func_ptr_t)(void*, int32_t);
|
|
typedef void (*lower_func_ptr_g)(void*, int32_t, void*);
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
//! cinn_pod_value to specific types.
|
|
// @{
|
|
float cinn_pod_value_to_float(cinn_pod_value_t* value);
|
|
double cinn_pod_value_to_double(cinn_pod_value_t* value);
|
|
cinn::common::bfloat16 cinn_pod_value_to_bfloat16(cinn_pod_value_t* value);
|
|
cinn::common::float8e4m3 cinn_pod_value_to_float8e4m3(cinn_pod_value_t* value);
|
|
cinn::common::float16 cinn_pod_value_to_float16(cinn_pod_value_t* value);
|
|
|
|
int64_t cinn_pod_value_to_int64(cinn_pod_value_t* value);
|
|
int32_t cinn_pod_value_to_int32(cinn_pod_value_t* value);
|
|
int16_t cinn_pod_value_to_int16(cinn_pod_value_t* value);
|
|
int8_t cinn_pod_value_to_int8(cinn_pod_value_t* value);
|
|
|
|
uint64_t cinn_pod_value_to_uint64(cinn_pod_value_t* value);
|
|
uint32_t cinn_pod_value_to_uint32(cinn_pod_value_t* value);
|
|
uint16_t cinn_pod_value_to_uint16(cinn_pod_value_t* value);
|
|
uint8_t cinn_pod_value_to_uint8(cinn_pod_value_t* value);
|
|
|
|
bool cinn_pod_value_to_bool(cinn_pod_value_t* value);
|
|
|
|
void* cinn_pod_value_to_void_p(cinn_pod_value_t* value);
|
|
int32_t* cinn_pod_value_to_int32_p(cinn_pod_value_t* value);
|
|
cinn_buffer_t* cinn_pod_value_to_buffer_p(cinn_pod_value_t* value);
|
|
// @}
|
|
|
|
//! other specific types to cinn_pod_value
|
|
// @{
|
|
void float_to_cinn_pod_value(float v, cinn_pod_value_t* out);
|
|
void bfloat16_to_cinn_pod_value(cinn::common::bfloat16 v,
|
|
cinn_pod_value_t* out);
|
|
void float8e4m3_to_cinn_pod_value(cinn::common::float8e4m3 v,
|
|
cinn_pod_value_t* out);
|
|
void float16_to_cinn_pod_value(cinn::common::float16 v, cinn_pod_value_t* out);
|
|
void double_to_cinn_pod_value(double v, cinn_pod_value_t* out);
|
|
|
|
void bool_to_cinn_pod_value(bool v, cinn_pod_value_t* out);
|
|
|
|
void int8_to_cinn_pod_value(int8_t v, cinn_pod_value_t* out);
|
|
void int16_to_cinn_pod_value(int16_t v, cinn_pod_value_t* out);
|
|
void int32_to_cinn_pod_value(int32_t v, cinn_pod_value_t* out);
|
|
void int64_to_cinn_pod_value(int64_t v, cinn_pod_value_t* out);
|
|
|
|
void uint8_to_cinn_pod_value(uint8_t v, cinn_pod_value_t* out);
|
|
void uint16_to_cinn_pod_value(uint16_t v, cinn_pod_value_t* out);
|
|
void uint32_to_cinn_pod_value(uint32_t v, cinn_pod_value_t* out);
|
|
void uint64_to_cinn_pod_value(uint64_t v, cinn_pod_value_t* out);
|
|
|
|
void handle_to_cinn_pod_value(void* v, cinn_pod_value_t* out);
|
|
void buffer_p_to_cinn_pod_value(const struct cinn_buffer_t* v,
|
|
cinn_pod_value_t* out);
|
|
// @}
|
|
|
|
void cinn_print_debug_string(const char* s, ...);
|
|
|
|
void cinn_print_debug_args(cinn_pod_value_t* args, int count);
|
|
|
|
/**
|
|
* Construct a Args for LoweredFunc with a list of `cinn_pod_value_t*`
|
|
* @param arr An array of `cinn_pod_value_t`
|
|
* @param count Count of elements in the arg list.
|
|
* @param ... variadic args of `cinn_pod_value_t*`
|
|
*/
|
|
void cinn_args_construct(cinn_pod_value_t* arr, int count, ...);
|
|
|
|
#ifdef __cplusplus
|
|
} // extern "C"
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
template <typename T>
|
|
cinn_type_t cinn_type_of();
|
|
|
|
#endif // __cplusplus
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#define WELFORD_STRUCT_MACRO(TYPENAME, DTYPE) \
|
|
typedef struct { \
|
|
DTYPE mean; \
|
|
DTYPE m2; \
|
|
DTYPE weight; \
|
|
} TYPENAME;
|
|
|
|
WELFORD_STRUCT_MACRO(welford_fp32, float)
|
|
WELFORD_STRUCT_MACRO(welford_fp64, double)
|
|
#undef WELFORD_STRUCT_MACRO
|
|
|
|
#define ARGIDX_STRUCT_MACRO(TYPENAME, DTYPE, ITYPE, IINIT) \
|
|
typedef struct { \
|
|
DTYPE value; \
|
|
ITYPE index; \
|
|
} TYPENAME;
|
|
|
|
#define EXPAND_ARGIDX_DTYPE_MACRO_IMPL(DTYPE, DNAME, ITYPE, INAME, IMAX) \
|
|
ARGIDX_STRUCT_MACRO(argidx_##DNAME##_##INAME, DTYPE, ITYPE, IMAX)
|
|
|
|
#define EXPAND_ARGIDX_DTYPE_MACRO(DTYPE, DNAME) \
|
|
EXPAND_ARGIDX_DTYPE_MACRO_IMPL(DTYPE, DNAME, int, i32, 0) \
|
|
EXPAND_ARGIDX_DTYPE_MACRO_IMPL(DTYPE, DNAME, int64_t, i64, 0LL)
|
|
|
|
EXPAND_ARGIDX_DTYPE_MACRO(float, fp32)
|
|
EXPAND_ARGIDX_DTYPE_MACRO(double, fp64)
|
|
EXPAND_ARGIDX_DTYPE_MACRO(int16_t, i16)
|
|
EXPAND_ARGIDX_DTYPE_MACRO(int, i32)
|
|
EXPAND_ARGIDX_DTYPE_MACRO(int64_t, i64)
|
|
EXPAND_ARGIDX_DTYPE_MACRO(uint8_t, u8)
|
|
|
|
#undef EXPAND_ARGIDX_DTYPE_MACRO
|
|
#undef EXPAND_ARGIDX_DTYPE_MACRO_IMPL
|
|
#undef ARGIDX_STRUCT_MACRO
|
|
|
|
#define ARGIDX_STRUCT_FUNC_MACRO(TYPENAME, DTYPE, ITYPE) \
|
|
ITYPE cast_##TYPENAME(const TYPENAME* argidx); \
|
|
void create_##TYPENAME(TYPENAME* sret, DTYPE val, ITYPE idx);
|
|
|
|
#define ARGIDX_COMBINE_MACRO(TYPENAME) \
|
|
void min_##TYPENAME(TYPENAME* sret, const TYPENAME* a, const TYPENAME* b); \
|
|
void max_##TYPENAME(TYPENAME* sret, const TYPENAME* a, const TYPENAME* b);
|
|
|
|
#define EXPAND_ARGIDX_FUNC_MACRO(DTYPE, DNAME) \
|
|
ARGIDX_COMBINE_MACRO(argidx_##DNAME##_##i32) \
|
|
ARGIDX_COMBINE_MACRO(argidx_##DNAME##_##i64) \
|
|
ARGIDX_STRUCT_FUNC_MACRO(argidx_##DNAME##_##i32, DTYPE, int) \
|
|
ARGIDX_STRUCT_FUNC_MACRO(argidx_##DNAME##_##i64, DTYPE, int64_t)
|
|
|
|
// TODO(heqianyue): fp16 not added
|
|
EXPAND_ARGIDX_FUNC_MACRO(float, fp32)
|
|
EXPAND_ARGIDX_FUNC_MACRO(double, fp64)
|
|
EXPAND_ARGIDX_FUNC_MACRO(int16_t, i16)
|
|
EXPAND_ARGIDX_FUNC_MACRO(int, i32)
|
|
EXPAND_ARGIDX_FUNC_MACRO(int64_t, i64)
|
|
EXPAND_ARGIDX_FUNC_MACRO(uint8_t, u8)
|
|
|
|
#define WELFORD_COMBINE_DEF_MACRO(TYPE_SUFFIX, DTYPE) \
|
|
void sum_welford_##TYPE_SUFFIX(welford_##TYPE_SUFFIX* sret, \
|
|
const welford_##TYPE_SUFFIX* a, \
|
|
const welford_##TYPE_SUFFIX* b); \
|
|
DTYPE cast_welford_##TYPE_SUFFIX(const welford_##TYPE_SUFFIX* wf); \
|
|
void create_welford_##TYPE_SUFFIX( \
|
|
welford_##TYPE_SUFFIX* sret, DTYPE m, DTYPE m2, DTYPE w);
|
|
|
|
WELFORD_COMBINE_DEF_MACRO(fp32, float)
|
|
WELFORD_COMBINE_DEF_MACRO(fp64, double)
|
|
#undef WELFORD_COMBINE_DEF_MACRO
|
|
|
|
#ifdef __cplusplus
|
|
} // extern "C"
|
|
#endif
|
|
|
|
#undef ARGIDX_COMBINE_MACRO
|
|
#undef EXPAND_ARGIDX_FUNC_MACRO
|
|
#undef ARGIDX_STRUCT_FUNC_MACRO
|