c_runtime_api.h 17.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

/*
tqchen committed
21
 * \file tvm/runtime/c_runtime_api.h
22 23 24 25 26 27
 * \brief TVM runtime library.
 *
 *  The philosophy of TVM project is to customize the compilation
 *  stage to generate code that can used by other projects transparently.
 *  So this is a minimum runtime code gluing, and some limited
 *  memory management code to enable quick testing.
28 29 30 31 32 33 34
 *
 *  The runtime API is independent from TVM compilation stack and can
 *  be linked via libtvm_runtime.
 *
 *  The common flow is:
 *   - Use TVMFuncListGlobalNames to get global function name
 *   - Use TVMFuncCall to call these functions.
35
 */
36 37
#ifndef TVM_RUNTIME_C_RUNTIME_API_H_
#define TVM_RUNTIME_C_RUNTIME_API_H_
38

39 40 41 42 43 44 45
// Macros to do weak linking
#ifdef _MSC_VER
#define TVM_WEAK __declspec(selectany)
#else
#define TVM_WEAK __attribute__((weak))
#endif

46 47 48 49 50 51
#ifdef __EMSCRIPTEN__
#include <emscripten/emscripten.h>
#define TVM_DLL EMSCRIPTEN_KEEPALIVE
#endif

#ifndef TVM_DLL
52 53 54 55 56 57 58
#ifdef _WIN32
#ifdef TVM_EXPORTS
#define TVM_DLL __declspec(dllexport)
#else
#define TVM_DLL __declspec(dllimport)
#endif
#else
59
#define TVM_DLL __attribute__((visibility("default")))
60
#endif
61
#endif
62

63
// TVM version
64
#define TVM_VERSION "0.6.0"
65 66


67 68
// TVM Runtime is DLPack compatible.
#include <dlpack/dlpack.h>
69

70
#ifdef __cplusplus
71
extern "C" {
72 73 74 75
#endif
#include <stdint.h>
#include <stddef.h>

76
/*! \brief type of array index. */
77
typedef int64_t tvm_index_t;
78 79 80

/*! \brief Extension device types in TVM */
typedef enum {
81
  kDLAOCL = 5,
82
  kDLSDAccel = 6,
83
  kOpenGL = 11,
84
  kDLMicroDev = 13,
85
  // AddExtraTVMType which is not in DLPack here
86 87
} TVMDeviceExtType;

88
/*!
89 90
 * \brief The type code in TVMType
 * \note TVMType is used in two places.
91 92
 */
typedef enum {
93
  // The type code of other types are compatible with DLPack.
94 95
  // The next few fields are extension types
  // that is used by TVM API calls.
96
  kHandle = 3U,
97
  kNull = 4U,
98 99 100
  kTVMType = 5U,
  kTVMContext = 6U,
  kArrayHandle = 7U,
101
  kObjectHandle = 8U,
102 103 104
  kModuleHandle = 9U,
  kFuncHandle = 10U,
  kStr = 11U,
105
  kBytes = 12U,
106
  kNDArrayContainer = 13U,
107 108 109 110 111 112 113 114 115
  // Extension codes for other frameworks to integrate TVM PackedFunc.
  // To make sure each framework's id do not conflict, use first and
  // last sections to mark ranges.
  // Open an issue at the repo if you need a section of code.
  kExtBegin = 15U,
  kNNVMFirst = 16U,
  kNNVMLast = 20U,
  // The following section of code is used for non-reserved types.
  kExtReserveEnd = 64U,
116
  kExtEnd = 128U,
117
  // The rest of the space is used for custom, user-supplied datatypes
118
  kCustomBegin = 129U,
119 120 121 122 123 124 125 126 127 128 129 130
} TVMTypeCode;

/*!
 * \brief The data type used in TVM Runtime.
 *
 *  Examples
 *   - float: type_code = 2, bits = 32, lanes=1
 *   - float4(vectorized 4 float): type_code = 2, bits = 32, lanes=4
 *   - int8: type_code = 0, bits = 8, lanes=1
 *
 * \note Arguments TVM API function always takes bits=64 and lanes=1
 */
131 132 133 134 135 136 137 138
typedef DLDataType TVMType;

/*!
 * \brief The Device information, abstract away common device types.
 */
typedef DLContext TVMContext;

/*!
139
 * \brief The tensor array structure to TVM API.
140 141
 */
typedef DLTensor TVMArray;
142

143 144 145
/*! \brief the array handle */
typedef TVMArray* TVMArrayHandle;

146
/*!
147 148 149 150 151 152 153 154 155
 * \brief Union type of values
 *  being passed through API and function calls.
 */
typedef union {
  int64_t v_int64;
  double v_float64;
  void* v_handle;
  const char* v_str;
  TVMType v_type;
156
  TVMContext v_ctx;
157 158 159
} TVMValue;

/*!
160 161 162 163 164 165 166 167
 * \brief Byte array type used to pass in byte array
 *  When kBytes is used as data type.
 */
typedef struct {
  const char* data;
  size_t size;
} TVMByteArray;

168 169
/*! \brief Handle to TVM runtime modules. */
typedef void* TVMModuleHandle;
170
/*! \brief Handle to packed function handle. */
171
typedef void* TVMFunctionHandle;
172 173
/*! \brief Handle to hold return value. */
typedef void* TVMRetValueHandle;
174 175 176 177 178
/*!
 * \brief The stream that is specific to device
 * can be NULL, which indicates the default one.
 */
typedef void* TVMStreamHandle;
179 180
/*! \brief Handle to Object. */
typedef void* TVMObjectHandle;
181 182

/*!
183 184 185 186 187 188 189
 * \brief Used for implementing C API function.
 *  Set last error message before return.
 * \param msg The error message to be set.
 */
TVM_DLL void TVMAPISetLastError(const char* msg);

/*!
190 191
 * \brief return str message of the last error
 *  all function in this file will return 0 when success
192
 *  and -1 when an error occurred,
193 194 195 196 197 198 199
 *  TVMGetLastError can be called to retrieve the error
 *
 *  this function is threadsafe and can be called by different thread
 *  \return error info
 */
TVM_DLL const char *TVMGetLastError(void);
/*!
200 201 202 203
 * \brief Load module from file.
 * \param file_name The file name to load the module from.
 * \param format The format of the module.
 * \param out The result module
204
 *
205
 * \return 0 when success, -1 when failure happens
206 207
 * \note The resulting module do not contain import relation.
 *  It can be reconstructed by TVMModImport.
208
 */
209 210 211
TVM_DLL int TVMModLoadFromFile(const char* file_name,
                               const char* format,
                               TVMModuleHandle* out);
212 213

/*!
214 215
 * \brief Add dep to mod's dependency.
 *  This allows functions in this module to use modules.
216
 *
217 218 219
 * \param mod The module handle.
 * \param dep The dependent module to be imported.
 * \return 0 when success, -1 when failure happens
220
 */
221 222
TVM_DLL int TVMModImport(TVMModuleHandle mod,
                         TVMModuleHandle dep);
223 224

/*!
225 226 227 228 229 230
 * \brief Get function from the module.
 * \param mod The module handle.
 * \param func_name The name of the function.
 * \param query_imports Whether to query imported modules
 * \param out The result function, can be NULL if it is not available.
 * \return 0 when no error is thrown, -1 when failure happens
231
 */
232 233 234 235 236
TVM_DLL int TVMModGetFunction(TVMModuleHandle mod,
                              const char* func_name,
                              int query_imports,
                              TVMFunctionHandle *out);

237
/*!
238 239 240 241 242 243 244 245
 * \brief Free the Module
 * \param mod The module to be freed.
 *
 * \note This may not free up the module's resources.
 *  If there is active TVMFunctionHandle uses the module
 *  Or if this module is imported by another active module.
 *
 *  The all functions remains valid until TVMFuncFree is called.
246
 * \return 0 when success, -1 when failure happens
247 248 249 250
 */
TVM_DLL int TVMModFree(TVMModuleHandle mod);

/*!
251 252
 * \brief Free the function when it is no longer needed.
 * \param func The function handle
253
 * \return 0 when success, -1 when failure happens
254
 */
255
TVM_DLL int TVMFuncFree(TVMFunctionHandle func);
256 257

/*!
258
 * \brief Call a Packed TVM Function.
259
 *
260
 * \param func node handle of the function.
261
 * \param arg_values The arguments
262
 * \param type_codes The type codes of the arguments
263
 * \param num_args Number of arguments.
264
 *
265 266 267
 * \param ret_val The return value.
 * \param ret_type_code the type code of return value.
 *
268 269
 * \return 0 when success, -1 when failure happens
 * \note TVM calls always exchanges with type bits=64, lanes=1
270 271 272 273 274 275
 *
 * \note API calls always exchanges with type bits=64, lanes=1
 *   If API call returns container handles (e.g. FunctionHandle)
 *   these handles should be managed by the front-end.
 *   The front-end need to call free function (e.g. TVMFuncFree)
 *   to free these handles.
276
 */
277
TVM_DLL int TVMFuncCall(TVMFunctionHandle func,
278
                        TVMValue* arg_values,
279
                        int* type_codes,
280 281 282 283 284 285 286 287 288 289 290 291 292
                        int num_args,
                        TVMValue* ret_val,
                        int* ret_type_code);

/*!
 * \brief Set the return value of TVMPackedCFunc.
 *
 *  This function is called by TVMPackedCFunc to set the return value.
 *  When this function is not called, the function returns null by default.
 *
 * \param ret The return value handle, pass by ret in TVMPackedCFunc
 * \param value The value to be returned.
 * \param type_code The type of the value to be returned.
293
 * \param num_ret Number of return values, for now only 1 is supported.
294 295
 */
TVM_DLL int TVMCFuncSetReturn(TVMRetValueHandle ret,
296 297 298
                              TVMValue* value,
                              int* type_code,
                              int num_ret);
299 300

/*!
301 302 303 304 305 306 307 308 309 310 311 312
 * \brief Inplace translate callback argument value to return value.
 *  This is only needed for non-POD arguments.
 *
 * \param value The value to be translated.
 * \param code The type code to be translated.
 * \note This function will do a shallow copy when necessary.
 *
 * \return 0 when success, -1 when failure happens.
 */
TVM_DLL int TVMCbArgToReturn(TVMValue* value, int code);

/*!
313 314 315 316 317
 * \brief C type of packed function.
 *
 * \param args The arguments
 * \param type_codes The type codes of the arguments
 * \param num_args Number of arguments.
318
 * \param ret The return value handle.
319
 * \param resource_handle The handle additional resouce handle from fron-end.
320
 * \return 0 if success, -1 if failure happens, set error via TVMAPISetLastError.
321
 * \sa TVMCFuncSetReturn
322
 */
323
typedef int (*TVMPackedCFunc)(
324 325 326 327 328
    TVMValue* args,
    int* type_codes,
    int num_args,
    TVMRetValueHandle ret,
    void* resource_handle);
329 330 331 332 333 334 335 336

/*!
 * \brief C callback to free the resource handle in C packed function.
 * \param resource_handle The handle additional resouce handle from fron-end.
 */
typedef void (*TVMPackedCFuncFinalizer)(void* resource_handle);

/*!
337 338 339 340 341
 * \brief Signature for extension function declarer.
 *
 *  TVM call this function to get the extension functions
 *  The declarer will call register_func to register function and their name.
 *
342
 * \param register_func_handle The register function
343 344 345 346 347
 * \return 0 if success, -1 if failure happens
 */
typedef int (*TVMExtensionFuncDeclarer)(TVMFunctionHandle register_func_handle);

/*!
348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369
 * \brief Wrap a TVMPackedCFunc to become a FunctionHandle.
 *
 * The resource_handle will be managed by TVM API, until the function is no longer used.
 *
 * \param func The packed C function.
 * \param resource_handle The resource handle from front-end, can be NULL.
 * \param fin The finalizer on resource handle when the FunctionHandle get freed, can be NULL
 * \param out the result function handle.
 * \return 0 when success, -1 when failure happens
 */
TVM_DLL int TVMFuncCreateFromCFunc(TVMPackedCFunc func,
                                   void* resource_handle,
                                   TVMPackedCFuncFinalizer fin,
                                   TVMFunctionHandle *out);

/*!
 * \brief Register the function to runtime's global table.
 *
 * The registered function then can be pulled by the backend by the name.
 *
 * \param name The name of the function.
 * \param f The function to be registered.
370
 * \param override Whether allow override already registered function.
371
 */
372 373
TVM_DLL int TVMFuncRegisterGlobal(
    const char* name, TVMFunctionHandle f, int override);
374 375 376 377 378

/*!
 * \brief Get a global function.
 *
 * \param name The name of the function.
379
 * \param out the result function pointer, NULL if it does not exist.
380 381 382
 *
 * \note The function handle of global function is managed by TVM runtime,
 *  So TVMFuncFree is should not be called when it get deleted.
383 384
 */
TVM_DLL int TVMFuncGetGlobal(const char* name, TVMFunctionHandle* out);
385 386 387 388 389 390 391

/*!
 * \brief List all the globally registered function name
 * \param out_size The number of functions
 * \param out_array The array of function names.
 * \return 0 when success, -1 when failure happens
 */
392
TVM_DLL int TVMFuncListGlobalNames(int* out_size,
393
                                   const char*** out_array);
394

395
// Array related apis for quick proptyping
396 397 398 399 400 401
/*!
 * \brief Allocate a nd-array's memory,
 *  including space of shape, of given spec.
 *
 * \param shape The shape of the array, the data content will be copied to out
 * \param ndim The number of dimension of the array.
402 403 404 405 406
 * \param dtype_code The type code of the dtype
 * \param dtype_bits The number of bits of dtype
 * \param dtype_lanes The number of lanes in the dtype.
 * \param device_type The device type of context
 * \param device_id The device id of context.
407 408 409 410
 * \param out The output handle.
 * \return 0 when success, -1 when failure happens
 */
TVM_DLL int TVMArrayAlloc(const tvm_index_t* shape,
411
                          int ndim,
412 413 414 415 416
                          int dtype_code,
                          int dtype_bits,
                          int dtype_lanes,
                          int device_type,
                          int device_id,
417
                          TVMArrayHandle* out);
418

419 420 421 422 423 424 425 426
/*!
 * \brief Free the TVM Array.
 * \param handle The array handle to be freed.
 * \return 0 when success, -1 when failure happens
 */
TVM_DLL int TVMArrayFree(TVMArrayHandle handle);

/*!
427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448
 * \brief Copy array data from CPU byte array.
 * \param handle The array handle.
 * \param data the data pointer
 * \param nbytes The number of bytes to copy.
 * \return 0 when success, -1 when failure happens
 */
TVM_DLL int TVMArrayCopyFromBytes(TVMArrayHandle handle,
                                  void* data,
                                  size_t nbytes);

/*!
 * \brief Copy array data to CPU byte array.
 * \param handle The array handle.
 * \param data the data pointer
 * \param nbytes The number of bytes to copy.
 * \return 0 when success, -1 when failure happens
 */
TVM_DLL int TVMArrayCopyToBytes(TVMArrayHandle handle,
                                void* data,
                                size_t nbytes);

/*!
449 450 451 452 453 454 455 456 457
 * \brief Copy the array, both from and to must be valid during the copy.
 * \param from The array to be copied from.
 * \param to The target space.
 * \param stream The stream where the copy happens, can be NULL.
 * \return 0 when success, -1 when failure happens
 */
TVM_DLL int TVMArrayCopyFromTo(TVMArrayHandle from,
                               TVMArrayHandle to,
                               TVMStreamHandle stream);
458 459

/*!
eqy committed
460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480
 * \brief Produce an array from the DLManagedTensor that shares data memory
 * with the DLManagedTensor.
 * \param from The source DLManagedTensor.
 * \param out The output array handle.
 * \return 0 when success, -1 when failure happens
 */
TVM_DLL int TVMArrayFromDLPack(DLManagedTensor* from,
                               TVMArrayHandle* out);

/*!
 * \brief Produce a DLMangedTensor from the array that shares data memory with
 * the array.
 * \param from The source array.
 * \param out The DLManagedTensor handle.
 * \return 0 when success, -1 when failure happens
 */
TVM_DLL int TVMArrayToDLPack(TVMArrayHandle from,
                             DLManagedTensor** out);

/*!
 * \brief Delete (free) a DLManagedTensor's data.
481
 * \param dltensor Pointer to the DLManagedTensor.
eqy committed
482 483 484 485
 */
TVM_DLL void TVMDLManagedTensorCallDeleter(DLManagedTensor* dltensor);

/*!
tqchen committed
486
 * \brief Create a new runtime stream.
487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505
 *
 * \param device_type The device type of context
 * \param device_id The device id of context
 * \param out The new stream handle
 * \return 0 when success, -1 when failure happens
 */
TVM_DLL int TVMStreamCreate(int device_type, int device_id, TVMStreamHandle* out);

/*!
 * \brief Free a created stream handle.
 *
 * \param device_type The device type of context
 * \param device_id The device id of context
 * \param stream The stream to be freed
 * \return 0 when success, -1 when failure happens
 */
TVM_DLL int TVMStreamFree(int device_type, int device_id, TVMStreamHandle stream);

/*!
506 507 508 509 510
 * \brief Set the runtime stream of current thread to be stream.
 *  The subsequent calls to the same device_type
 *  will use the setted stream handle.
 *  The specific type of stream is runtime device dependent.
 *
511 512
 * \param device_type The device type of context
 * \param device_id The device id of context.
513 514 515
 * \param handle The stream handle.
 * \return 0 when success, -1 when failure happens
 */
516
TVM_DLL int TVMSetStream(int device_type, int device_id, TVMStreamHandle handle);
517

518 519
/*!
 * \brief Wait until all computations on stream completes.
520 521 522
 *
 * \param device_type The device type of context
 * \param device_id The device id of context.
523 524 525
 * \param stream The stream to be synchronized.
 * \return 0 when success, -1 when failure happens
 */
526
TVM_DLL int TVMSynchronize(int device_type, int device_id, TVMStreamHandle stream);
527

528 529 530 531 532 533 534 535 536 537 538 539 540 541
/*!
 * \brief Synchronize two streams of execution.
 *
 * \param device_type The device type of context
 * \param device_id The device id of context
 * \param src The source stream to synchronize.
 * \param dst The destination stream to synchronize.
 * \return 0 when success, -1 when failure happens
 */
TVM_DLL int TVMStreamStreamSynchronize(int device_type,
                                       int device_id,
                                       TVMStreamHandle src,
                                       TVMStreamHandle dst);

542
/*!
543
 * \brief Get the type_index from an object.
544 545
 *
 * \param obj The object handle.
546
 * \param out_tindex the output type index.
547 548
 * \return 0 when success, -1 when failure happens
 */
549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567
TVM_DLL int TVMObjectGetTypeIndex(TVMObjectHandle obj, unsigned* out_tindex);

/*!
 * \brief Convert type key to type index.
 * \param type_key The key of the type.
 * \param out_tindex the corresponding type index.
 * \return 0 when success, -1 when failure happens
 */
TVM_DLL int TVMObjectTypeKey2Index(const char* type_key, unsigned* out_tindex);

/*!
 * \brief Free the object.
 *
 * \param obj The object handle.
 * \note Internally we decrease the reference counter of the object.
 *       The object will be freed when every reference to the object are removed.
 * \return 0 when success, -1 when failure happens
 */
TVM_DLL int TVMObjectFree(TVMObjectHandle obj);
568

569
#ifdef __cplusplus
570
}  // TVM_EXTERN_C
571
#endif
572
#endif  // TVM_RUNTIME_C_RUNTIME_API_H_