1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20/*
21 * \file tvm/runtime/c_runtime_api.h
22 * \brief TVM runtime library.
23 *
24 * The philosophy of TVM project is to customize the compilation
25 * stage to generate code that can used by other projects transparently.
26 * So this is a minimum runtime code gluing, and some limited
27 * memory management code to enable quick testing.
28 *
29 * The runtime API is independent from TVM compilation stack and can
30 * be linked via libtvm_runtime.
31 *
32 * The common flow is:
33 * - Use TVMFuncListGlobalNames to get global function name
34 * - Use TVMFuncCall to call these functions.
35 *
36 * Possible return values of the API functions:
37 * * 0: success
38 * * -1: the error can be retrieved through TVMGetLastError.
39 * * -2: a frontend error occurred and recorded in the frontend.
40 */
41#ifndef TVM_RUNTIME_C_RUNTIME_API_H_
42#define TVM_RUNTIME_C_RUNTIME_API_H_
43
44// Macros to do weak linking
45#ifdef _MSC_VER
46#define TVM_WEAK __declspec(selectany)
47#else
48#define TVM_WEAK __attribute__((weak))
49#endif
50
51#ifdef __EMSCRIPTEN__
52#include <emscripten/emscripten.h>
53#define TVM_DLL EMSCRIPTEN_KEEPALIVE
54#endif
55
56#ifndef TVM_DLL
57#ifdef _WIN32
58#ifdef TVM_EXPORTS
59#define TVM_DLL __declspec(dllexport)
60#else
61#define TVM_DLL __declspec(dllimport)
62#endif
63#else
64#define TVM_DLL __attribute__((visibility("default")))
65#endif
66#endif
67
68// TVM version
69#define TVM_VERSION "0.11.dev0"
70
71// TVM Runtime is DLPack compatible.
72#include <dlpack/dlpack.h>
73
74#ifdef __cplusplus
75extern "C" {
76#endif
77#include <stddef.h>
78#include <stdint.h>
79
80/*! \brief type of array index. */
81typedef int64_t tvm_index_t;
82
83/*! \brief Extension device types in TVM
84 *
85 * Additional enumerators to supplement those provided by
86 * DLPack's `DLDeviceType` enumeration.
87 *
88 * MAINTAINERS NOTE #1: We need to ensure that the two devices
89 * are identified by the same integer.
90 * Currently this requires manual verification.
91 * Discussed here: https://github.com/dmlc/dlpack/issues/111
92 * As of DLPack v0.7, the highest-valued enumerator in
93 * `DLDeviceType` is kDLHexagon = 16.
94 *
95 * MAINTAINERS NOTE #2: As of DLPack v0.7, the definition for
96 * `DLDeviceType` specifies an underlying storage type of
97 * `int32_t`. That guarantees a variable of type
98 * `DLDeviceType` is capable of holding any integers provided
99 * by *either* of these enumerations.
100 *
101 * However, the `int32_t` specification only applies when the
102 * header file is compiled as C++, and this header file is also
103 * meant to work as C code. So the unspecified storage type
104 * could be a latent bug when compiled as C.
105 */
106#ifdef __cplusplus
107typedef enum : int32_t {
108#else
109typedef enum {
110#endif
111 // To help avoid accidental conflicts between `DLDeviceType`
112 // and this enumeration, start numbering the new enumerators
113 // a little higher than (currently) seems necessary.
114 kDLAOCL = 32,
115 kDLSDAccel,
116 kOpenGL,
117 kDLMicroDev,
118 TVMDeviceExtType_End, // sentinel value
119} TVMDeviceExtType;
120
121#ifdef __cplusplus
122// Some other parts of TVM hardcode the integer identifier for
123// some DLPack / TVM devices, rather then using the symbolic
124// enumerator. E.g., `2` rather than `kDLCUDA`.
125// These asserts should alert us when that mapping breaks.
126#define TVM_HARCODED_INTEGER_CHANGED_MSG \
127 "Change in compile-time integer. Make sure hardcoded uses of this integer throughout TVM are " \
128 "updated."
129static_assert(kDLCPU == 1, TVM_HARCODED_INTEGER_CHANGED_MSG);
130static_assert(kDLCUDA == 2, TVM_HARCODED_INTEGER_CHANGED_MSG);
131static_assert(kDLCUDAHost == 3, TVM_HARCODED_INTEGER_CHANGED_MSG);
132static_assert(kDLOpenCL == 4, TVM_HARCODED_INTEGER_CHANGED_MSG);
133static_assert(kDLVulkan == 7, TVM_HARCODED_INTEGER_CHANGED_MSG);
134static_assert(kDLMetal == 8, TVM_HARCODED_INTEGER_CHANGED_MSG);
135static_assert(kDLVPI == 9, TVM_HARCODED_INTEGER_CHANGED_MSG);
136static_assert(kDLROCM == 10, TVM_HARCODED_INTEGER_CHANGED_MSG);
137static_assert(kDLROCMHost == 11, TVM_HARCODED_INTEGER_CHANGED_MSG);
138static_assert(kDLExtDev == 12, TVM_HARCODED_INTEGER_CHANGED_MSG);
139static_assert(kDLCUDAManaged == 13, TVM_HARCODED_INTEGER_CHANGED_MSG);
140static_assert(kDLOneAPI == 14, TVM_HARCODED_INTEGER_CHANGED_MSG);
141static_assert(kDLWebGPU == 15, TVM_HARCODED_INTEGER_CHANGED_MSG);
142static_assert(kDLHexagon == 16, TVM_HARCODED_INTEGER_CHANGED_MSG);
143
144static_assert(kDLAOCL == 32, TVM_HARCODED_INTEGER_CHANGED_MSG);
145static_assert(kDLSDAccel == 33, TVM_HARCODED_INTEGER_CHANGED_MSG);
146static_assert(kOpenGL == 34, TVM_HARCODED_INTEGER_CHANGED_MSG);
147static_assert(kDLMicroDev == 35, TVM_HARCODED_INTEGER_CHANGED_MSG);
148#undef TVM_HARCODED_INTEGER_CHANGED_MSG
149#endif
150
151/*!
152 * \brief The type code in used and only used in TVM FFI for argument passing.
153 *
154 * DLPack consistency:
155 * 1) kTVMArgInt is compatible with kDLInt
156 * 2) kTVMArgFloat is compatible with kDLFloat
157 * 3) kDLUInt is not in ArgTypeCode, but has a spared slot
158 *
159 * Downstream consistency:
160 * The kDLInt, kDLUInt, kDLFloat are kept consistent with the original ArgType code
161 *
162 * It is only used in argument passing, and should not be confused with
163 * DataType::TypeCode, which is DLPack-compatible.
164 *
165 * \sa tvm::runtime::DataType::TypeCode
166 */
167typedef enum {
168 kTVMArgInt = kDLInt,
169 kTVMArgFloat = kDLFloat,
170 kTVMOpaqueHandle = 3U,
171 kTVMNullptr = 4U,
172 kTVMDataType = 5U,
173 kDLDevice = 6U,
174 kTVMDLTensorHandle = 7U,
175 kTVMObjectHandle = 8U,
176 kTVMModuleHandle = 9U,
177 kTVMPackedFuncHandle = 10U,
178 kTVMStr = 11U,
179 kTVMBytes = 12U,
180 kTVMNDArrayHandle = 13U,
181 kTVMObjectRValueRefArg = 14U,
182 // Extension codes for other frameworks to integrate TVM PackedFunc.
183 // To make sure each framework's id do not conflict, use first and
184 // last sections to mark ranges.
185 // Open an issue at the repo if you need a section of code.
186 kTVMExtBegin = 15U,
187 kTVMNNVMFirst = 16U,
188 kTVMNNVMLast = 20U,
189 // The following section of code is used for non-reserved types.
190 kTVMExtReserveEnd = 64U,
191 kTVMExtEnd = 128U,
192} TVMArgTypeCode;
193
194/*! \brief the array handle */
195typedef DLTensor* TVMArrayHandle;
196
197/*!
198 * \brief Union type of values
199 * being passed through API and function calls.
200 */
201typedef union {
202 int64_t v_int64;
203 double v_float64;
204 void* v_handle;
205 const char* v_str;
206 DLDataType v_type;
207 DLDevice v_device;
208} TVMValue;
209
210/*!
211 * \brief Byte array type used to pass in byte array
212 * When kTVMBytes is used as data type.
213 */
214typedef struct {
215 const char* data;
216 size_t size;
217} TVMByteArray;
218
219/*! \brief Handle to TVM runtime modules. */
220typedef void* TVMModuleHandle;
221/*! \brief Handle to packed function handle. */
222typedef void* TVMFunctionHandle;
223/*! \brief Handle to hold return value. */
224typedef void* TVMRetValueHandle;
225/*!
226 * \brief The stream that is specific to device
227 * can be NULL, which indicates the default one.
228 */
229typedef void* TVMStreamHandle;
230/*! \brief Handle to Object. */
231typedef void* TVMObjectHandle;
232
233/*!
234 * \brief Used for implementing C API function.
235 * Set last error message before return.
236 * \param msg The error message to be set.
237 */
238TVM_DLL void TVMAPISetLastError(const char* msg);
239
240/*!
241 * \brief return str message of the last error
242 * all function in this file will return 0 when success
243 * and nonzero when an error occurred,
244 * TVMGetLastError can be called to retrieve the error
245 *
246 * this function is threadsafe and can be called by different thread
247 * \return error info
248 */
249TVM_DLL const char* TVMGetLastError(void);
250/*!
251 * \brief Load module from file.
252 * \param file_name The file name to load the module from.
253 * \param format The format of the module.
254 * \param out The result module
255 *
256 * \return 0 when success, nonzero when failure happens
257 * \note The resulting module do not contain import relation.
258 * It can be reconstructed by TVMModImport.
259 */
260TVM_DLL int TVMModLoadFromFile(const char* file_name, const char* format, TVMModuleHandle* out);
261
262/*!
263 * \brief Add dep to mod's dependency.
264 * This allows functions in this module to use modules.
265 *
266 * \param mod The module handle.
267 * \param dep The dependent module to be imported.
268 * \return 0 when success, nonzero when failure happens
269 */
270TVM_DLL int TVMModImport(TVMModuleHandle mod, TVMModuleHandle dep);
271
272/*!
273 * \brief Get function from the module.
274 * \param mod The module handle.
275 * \param func_name The name of the function.
276 * \param query_imports Whether to query imported modules
277 * \param out The result function, can be NULL if it is not available.
278 * \return 0 when no error is thrown, nonzero when failure happens
279 */
280TVM_DLL int TVMModGetFunction(TVMModuleHandle mod, const char* func_name, int query_imports,
281 TVMFunctionHandle* out);
282
283/*!
284 * \brief Free the Module
285 * \param mod The module to be freed.
286 *
287 * \note This may not free up the module's resources.
288 * If there is active TVMFunctionHandle uses the module
289 * Or if this module is imported by another active module.
290 *
291 * The all functions remains valid until TVMFuncFree is called.
292 * \return 0 when success, nonzero when failure happens
293 */
294TVM_DLL int TVMModFree(TVMModuleHandle mod);
295
296/*!
297 * \brief Free the function when it is no longer needed.
298 * \param func The function handle
299 * \return 0 when success, nonzero when failure happens
300 */
301TVM_DLL int TVMFuncFree(TVMFunctionHandle func);
302
303/*!
304 * \brief Call a Packed TVM Function.
305 *
306 * \param func node handle of the function.
307 * \param arg_values The arguments
308 * \param type_codes The type codes of the arguments
309 * \param num_args Number of arguments.
310 *
311 * \param ret_val The return value.
312 * \param ret_type_code the type code of return value.
313 *
314 * \return 0 when success, nonzero when failure happens
315 * \note TVM calls always exchanges with type bits=64, lanes=1
316 *
317 * \note API calls always exchanges with type bits=64, lanes=1
318 * If API call returns container handles (e.g. FunctionHandle)
319 * these handles should be managed by the front-end.
320 * The front-end need to call free function (e.g. TVMFuncFree)
321 * to free these handles.
322 */
323TVM_DLL int TVMFuncCall(TVMFunctionHandle func, TVMValue* arg_values, int* type_codes, int num_args,
324 TVMValue* ret_val, int* ret_type_code);
325
326/*!
327 * \brief Set the return value of TVMPackedCFunc.
328 *
329 * This function is called by TVMPackedCFunc to set the return value.
330 * When this function is not called, the function returns null by default.
331 *
332 * \param ret The return value handle, pass by ret in TVMPackedCFunc
333 * \param value The value to be returned.
334 * \param type_code The type of the value to be returned.
335 * \param num_ret Number of return values, for now only 1 is supported.
336 */
337TVM_DLL int TVMCFuncSetReturn(TVMRetValueHandle ret, TVMValue* value, int* type_code, int num_ret);
338
339/*!
340 * \brief Inplace translate callback argument value to return value.
341 * This is only needed for non-POD arguments.
342 *
343 * \param value The value to be translated.
344 * \param code The type code to be translated.
345 * \note This function will do a shallow copy when necessary.
346 *
347 * \return 0 when success, nonzero when failure happens.
348 */
349TVM_DLL int TVMCbArgToReturn(TVMValue* value, int* code);
350
351/*!
352 * \brief C type of packed function.
353 *
354 * \param args The arguments
355 * \param type_codes The type codes of the arguments
356 * \param num_args Number of arguments.
357 * \param ret The return value handle.
358 * \param resource_handle The handle additional resouce handle from front-end.
359 * \return 0 if success, -1 if failure happens, set error via TVMAPISetLastError.
360 * \sa TVMCFuncSetReturn
361 */
362typedef int (*TVMPackedCFunc)(TVMValue* args, int* type_codes, int num_args, TVMRetValueHandle ret,
363 void* resource_handle);
364
365/*!
366 * \brief C callback to free the resource handle in C packed function.
367 * \param resource_handle The handle additional resouce handle from front-end.
368 */
369typedef void (*TVMPackedCFuncFinalizer)(void* resource_handle);
370
371/*!
372 * \brief Signature for extension function declarer.
373 *
374 * TVM call this function to get the extension functions
375 * The declarer will call register_func to register function and their name.
376 *
377 * \param register_func_handle The register function
378 * \return 0 if success, -1 if failure happens
379 */
380typedef int (*TVMExtensionFuncDeclarer)(TVMFunctionHandle register_func_handle);
381
382/*!
383 * \brief Wrap a TVMPackedCFunc to become a FunctionHandle.
384 *
385 * The resource_handle will be managed by TVM API, until the function is no longer used.
386 *
387 * \param func The packed C function.
388 * \param resource_handle The resource handle from front-end, can be NULL.
389 * \param fin The finalizer on resource handle when the FunctionHandle get freed, can be NULL
390 * \param out the result function handle.
391 * \return 0 when success, nonzero when failure happens
392 */
393TVM_DLL int TVMFuncCreateFromCFunc(TVMPackedCFunc func, void* resource_handle,
394 TVMPackedCFuncFinalizer fin, TVMFunctionHandle* out);
395
396/*!
397 * \brief Register the function to runtime's global table.
398 *
399 * The registered function then can be pulled by the backend by the name.
400 *
401 * \param name The name of the function.
402 * \param f The function to be registered.
403 * \param override Whether allow override already registered function.
404 */
405TVM_DLL int TVMFuncRegisterGlobal(const char* name, TVMFunctionHandle f, int override);
406
407/*!
408 * \brief Get a global function.
409 *
410 * \param name The name of the function.
411 * \param out the result function pointer, NULL if it does not exist.
412 *
413 * \note The function handle of global function is managed by TVM runtime,
414 * So TVMFuncFree is should not be called when it get deleted.
415 */
416TVM_DLL int TVMFuncGetGlobal(const char* name, TVMFunctionHandle* out);
417
418/*!
419 * \brief List all the globally registered function name
420 * \param out_size The number of functions
421 * \param out_array The array of function names.
422 * \return 0 when success, nonzero when failure happens
423 */
424TVM_DLL int TVMFuncListGlobalNames(int* out_size, const char*** out_array);
425
426/*!
427 * \brief Remove a global function.
428 * \param name The name of the function.
429 */
430TVM_DLL int TVMFuncRemoveGlobal(const char* name);
431
432// Array related apis for quick proptyping
433/*!
434 * \brief Allocate a nd-array's memory,
435 * including space of shape, of given spec.
436 *
437 * \param shape The shape of the array, the data content will be copied to out
438 * \param ndim The number of dimension of the array.
439 * \param dtype_code The type code of the dtype
440 * \param dtype_bits The number of bits of dtype
441 * \param dtype_lanes The number of lanes in the dtype.
442 * \param device_type The device type.
443 * \param device_id The device id.
444 * \param out The output handle.
445 * \return 0 when success, nonzero when failure happens
446 */
447TVM_DLL int TVMArrayAlloc(const tvm_index_t* shape, int ndim, int dtype_code, int dtype_bits,
448 int dtype_lanes, int device_type, int device_id, TVMArrayHandle* out);
449
450/*!
451 * \brief Free the TVM Array.
452 * \param handle The array handle to be freed.
453 * \return 0 when success, nonzero when failure happens
454 */
455TVM_DLL int TVMArrayFree(TVMArrayHandle handle);
456
457/*!
458 * \brief Copy array data from CPU byte array.
459 * \param handle The array handle.
460 * \param data the data pointer
461 * \param nbytes The number of bytes to copy.
462 * \return 0 when success, nonzero when failure happens
463 */
464TVM_DLL int TVMArrayCopyFromBytes(TVMArrayHandle handle, void* data, size_t nbytes);
465
466/*!
467 * \brief Copy array data to CPU byte array.
468 * \param handle The array handle.
469 * \param data the data pointer
470 * \param nbytes The number of bytes to copy.
471 * \return 0 when success, nonzero when failure happens
472 */
473TVM_DLL int TVMArrayCopyToBytes(TVMArrayHandle handle, void* data, size_t nbytes);
474
475/*!
476 * \brief Copy the array, both from and to must be valid during the copy.
477 * \param from The array to be copied from.
478 * \param to The target space.
479 * \param stream The stream where the copy happens, can be NULL.
480 * \return 0 when success, nonzero when failure happens
481 */
482TVM_DLL int TVMArrayCopyFromTo(TVMArrayHandle from, TVMArrayHandle to, TVMStreamHandle stream);
483
484/*!
485 * \brief Produce an array from the DLManagedTensor that shares data memory
486 * with the DLManagedTensor.
487 * \param from The source DLManagedTensor.
488 * \param out The output array handle.
489 * \return 0 when success, nonzero when failure happens
490 */
491TVM_DLL int TVMArrayFromDLPack(DLManagedTensor* from, TVMArrayHandle* out);
492
493/*!
494 * \brief Produce a DLMangedTensor from the array that shares data memory with
495 * the array.
496 * \param from The source array.
497 * \param out The DLManagedTensor handle.
498 * \return 0 when success, nonzero when failure happens
499 */
500TVM_DLL int TVMArrayToDLPack(TVMArrayHandle from, DLManagedTensor** out);
501
502/*!
503 * \brief Delete (free) a DLManagedTensor's data.
504 * \param dltensor Pointer to the DLManagedTensor.
505 */
506TVM_DLL void TVMDLManagedTensorCallDeleter(DLManagedTensor* dltensor);
507
508/*!
509 * \brief Create a new runtime stream.
510 *
511 * \param device_type The device type.
512 * \param device_id The device id.
513 * \param out The new stream handle.
514 * \return 0 when success, nonzero when failure happens
515 */
516TVM_DLL int TVMStreamCreate(int device_type, int device_id, TVMStreamHandle* out);
517
518/*!
519 * \brief Free a created stream handle.
520 *
521 * \param device_type The device type.
522 * \param device_id The device id.
523 * \param stream The stream to be freed.
524 * \return 0 when success, nonzero when failure happens
525 */
526TVM_DLL int TVMStreamFree(int device_type, int device_id, TVMStreamHandle stream);
527
528/*!
529 * \brief Set the runtime stream of current thread to be stream.
530 * The subsequent calls to the same device_type
531 * will use the setted stream handle.
532 * The specific type of stream is runtime device dependent.
533 *
534 * \param device_type The device type.
535 * \param device_id The device id.
536 * \param handle The stream handle.
537 * \return 0 when success, nonzero when failure happens
538 */
539TVM_DLL int TVMSetStream(int device_type, int device_id, TVMStreamHandle handle);
540
541/*!
542 * \brief Wait until all computations on stream completes.
543 *
544 * \param device_type The device type.
545 * \param device_id The device id.
546 * \param stream The stream to be synchronized.
547 * \return 0 when success, nonzero when failure happens
548 */
549TVM_DLL int TVMSynchronize(int device_type, int device_id, TVMStreamHandle stream);
550
551/*!
552 * \brief Synchronize two streams of execution.
553 *
554 * \param device_type The device type.
555 * \param device_id The device id.
556 * \param src The source stream to synchronize.
557 * \param dst The destination stream to synchronize.
558 * \return 0 when success, nonzero when failure happens
559 */
560TVM_DLL int TVMStreamStreamSynchronize(int device_type, int device_id, TVMStreamHandle src,
561 TVMStreamHandle dst);
562
563/*!
564 * \brief Get the type_index from an object.
565 *
566 * \param obj The object handle.
567 * \param out_tindex the output type index.
568 * \return 0 when success, nonzero when failure happens
569 */
570TVM_DLL int TVMObjectGetTypeIndex(TVMObjectHandle obj, unsigned* out_tindex);
571
572/*!
573 * \brief Convert type key to type index.
574 * \param type_key The key of the type.
575 * \param out_tindex the corresponding type index.
576 * \return 0 when success, nonzero when failure happens
577 */
578TVM_DLL int TVMObjectTypeKey2Index(const char* type_key, unsigned* out_tindex);
579
580/*!
581 * \brief Convert type index to type key.
582 * \param tindex The type index.
583 * \param out_type_key The output type key.
584 * \return 0 when success, nonzero when failure happens
585 */
586TVM_DLL int TVMObjectTypeIndex2Key(unsigned tindex, char** out_type_key);
587
588/*!
589 * \brief Increase the reference count of an object.
590 *
591 * \param obj The object handle.
592 * \note Internally we increase the reference counter of the object.
593 * \return 0 when success, nonzero when failure happens
594 */
595TVM_DLL int TVMObjectRetain(TVMObjectHandle obj);
596
597/*!
598 * \brief Free the object.
599 *
600 * \param obj The object handle.
601 * \note Internally we decrease the reference counter of the object.
602 * The object will be freed when every reference to the object are removed.
603 * \return 0 when success, nonzero when failure happens
604 */
605TVM_DLL int TVMObjectFree(TVMObjectHandle obj);
606
607/*!
608 * \brief Free a TVMByteArray returned from TVMFuncCall, and associated memory.
609 * \param arr The TVMByteArray instance.
610 * \return 0 on success, -1 on failure.
611 */
612TVM_DLL int TVMByteArrayFree(TVMByteArray* arr);
613
614/*!
615 * \brief Allocate a data space on device.
616 * \param dev The device to perform operation.
617 * \param nbytes The number of bytes in memory.
618 * \param alignment The alignment of the memory.
619 * \param type_hint The type of elements. Only needed by certain backends such
620 * as nbytes & alignment are sufficient for most backends.
621 * \param out_data The allocated device pointer.
622 * \return 0 when success, nonzero when failure happens
623 */
624TVM_DLL int TVMDeviceAllocDataSpace(DLDevice dev, size_t nbytes, size_t alignment,
625 DLDataType type_hint, void** out_data);
626
627/*!
628 * \brief Allocate a data space on device with special memory scope.
629 * \note The memory could use a special multi-dimensional memory layout.
630 * That is why we pass shape and dtype instead of raw number of bytes.
631 * \param dev The device to perform operation.
632 * \param ndim The number of dimension of the tensor.
633 * \param shape The shape of the tensor.
634 * \param dtype The type of elements.
635 * \param mem_scope The memory scope of the tensor,
636 * can be nullptr, which indicate the default global DRAM
637 * \param out_data The allocated device pointer.
638 * \return 0 when success, nonzero when failure happens
639 */
640TVM_DLL int TVMDeviceAllocDataSpaceWithScope(DLDevice dev, int ndim, const int64_t* shape,
641 DLDataType dtype, const char* mem_scope,
642 void** out_data);
643
644/*!
645 * \brief Free a data space on device.
646 * \param dev The device to perform operation.
647 * \param ptr The data space.
648 * \return 0 when success, nonzero when failure happens
649 */
650TVM_DLL int TVMDeviceFreeDataSpace(DLDevice dev, void* ptr);
651
652/*!
653 * \brief Copy data from one place to another.
654 * \note This API is designed to support special memory with shape dependent layout.
655 * We pass in DLTensor* with shape information to support these cases.
656 * \param from The source tensor.
657 * \param to The target tensor.
658 * \param stream Optional stream object.
659 * \return 0 when success, nonzero when failure happens.
660 */
661TVM_DLL int TVMDeviceCopyDataFromTo(DLTensor* from, DLTensor* to, TVMStreamHandle stream);
662
663/*!
664 * \brief Check that an object is derived from another.
665 * \param child_type_index The type index of the derived type.
666 * \param parent_type_index The type index of the parent type.
667 * \param is_derived A boolean representing whether this predicate holds.
668 * \return 0 when success, nonzero when failure happens.
669 */
670TVM_DLL int TVMObjectDerivedFrom(uint32_t child_type_index, uint32_t parent_type_index,
671 int* is_derived);
672
673#ifdef __cplusplus
674} // TVM_EXTERN_C
675#endif
676#endif // TVM_RUNTIME_C_RUNTIME_API_H_
677