value.go 11.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*
 * 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.
 */

20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328
/*!
 *  Copyright (c) 2018 by Contributors
 * \brief gotvm package source for TVMValue interface
 * \file value.go
 */

package gotvm

//#include "gotvm.h"
import "C"

import (
    "fmt"
    "runtime"
    "unsafe"
)

// KHandle is golang type code for TVM enum kHandle.
var KHandle                 = int32(C.kHandle)
// KNull is golang type code for TVM kNull.
var KNull                   = int32(C.kNull)
// KTVMType is golang type code for TVM kTVMType.
var KTVMType                = int32(C.kTVMType)
// KTVMContext is golang type code for TVM kTVMContext.
var KTVMContext             = int32(C.kTVMContext)
// KArrayHandle is golang type code for TVM kArrayHandle.
var KArrayHandle            = int32(C.kArrayHandle)
// KNodeHandle is golang type code for TVM kNodeHandle.
var KNodeHandle             = int32(C.kNodeHandle)
// KModuleHandle is gonag type code for TVM kModuleHandle.
var KModuleHandle           = int32(C.kModuleHandle)
// KFuncHandle is gonalg type code for TVM kFuncHandle.
var KFuncHandle             = int32(C.kFuncHandle)
// KStr is golang type code for TVM kStr.
var KStr                    = int32(C.kStr)
// KBytes is golang type code for TVM kBytes.
var KBytes                  = int32(C.kBytes)
// KNDArrayContainer is golang typecode for kNDArrayContainer.
var KNDArrayContainer       = int32(C.kNDArrayContainer)
// KExtBegin is golang enum corresponding to TVM kExtBegin.
var KExtBegin               = int32(C.kExtBegin)
// KNNVMFirst is golang enum corresponding to TVM kNNVMFirst.
var KNNVMFirst              = int32(C.kNNVMFirst)
// KNNVMLast is golang enum corresponding to TVM kNNVMLast.
var KNNVMLast               = int32(C.kNNVMLast)
// KExtReserveEnd is golang enum corresponding to TVM kExtReserveEnd.
var KExtReserveEnd          = int32(C.kExtReserveEnd)
// KExtEnd is golang enum corresponding to TVM kExtEnd.
var KExtEnd                 = int32(C.kExtEnd)
// KDLInt is golang type code for TVM kDLInt.
var KDLInt                  = int32(C.kDLInt)
// KDLUInt is golang type code for TVM kDLUInt.
var KDLUInt                 = int32(C.kDLUInt)
// KDLFloat is golang type code for TVM kDLFloat.
var KDLFloat                = int32(C.kDLFloat)

// Value Typemap for union exposed by TVM runtime API.
//
// gotvm maps it to a uintptr and then dynamically allocates memory by newTVMValue method.
type Value struct {
    nptr  uintptr
    dtype int32
    isLocal bool
}

// AsInt64 returns the int64 value inside the Value.
func (tvmval *Value)  AsInt64() (retVal int64) {
    retVal = tvmval.getVInt64()
    return
}

// AsFloat64 returns the Float64 value inside the Value.
func (tvmval *Value)  AsFloat64() (retVal float64) {
    retVal = tvmval.getVFloat64()
    return
}

// AsModule returns the Module inside the Value.
func (tvmval *Value)  AsModule() (retVal *Module) {
    mhandle := tvmval.getVMHandle()
    retVal = &mhandle
    return
}

// AsFunction returns the Function inside the Value.
func (tvmval *Value)  AsFunction() (retVal *Function) {
    fhandle := tvmval.getVFHandle()
    retVal = &fhandle

    return
}

// AsBytes returns the byte slice value inside the Value.
func (tvmval *Value)  AsBytes() (retVal []byte) {
    retVal = tvmval.getVBHandle().getData()
    return
}

// AsStr returns the golang string in the Value.
func (tvmval *Value) AsStr() (retVal string) {
    str := tvmval.getVStr()
    retVal = str
    return
}

// nativeCPtr return the unitptr corresponding to Value type.
func (tvmval *Value) nativeCPtr() (ret uintptr) {
    ret = (uintptr)(tvmval.nptr)
    return
}

// moveFrom copies the tvmval from other Value object.
func (tvmval *Value) moveFrom(fromval *Value) () {
    C.memcpy(unsafe.Pointer(tvmval.nativeCPtr()),
             unsafe.Pointer(fromval.nativeCPtr()),
             C.sizeof_TVMValue)

    // Move the dtype too.
    tvmval.dtype = fromval.dtype
    fromval.dtype = KNull
    return
}

// setVInt64 initializes the Value object with given int64 value.
//
// `val` is the int64 value to initialize the Value
func (tvmval *Value) setVInt64(val int64) {
    valp := (*C.int64_t)(unsafe.Pointer(tvmval.nativeCPtr()))
    *valp = C.int64_t(val)
    tvmval.dtype = KDLInt
    return
}


// getVInt64 returns the int64 value inside the Value.
func (tvmval *Value) getVInt64() (retVal int64) {
    valp := (*C.int64_t)(unsafe.Pointer(tvmval.nativeCPtr()))
    retVal = int64(*valp)
    return
}

// setVFloat64 initializes the Value object with given float64 value.
//
// `val` is the float64 value to initialize the Value.
func (tvmval *Value) setVFloat64(val float64) {
    valp := (*C.double)(unsafe.Pointer(tvmval.nativeCPtr()))
    *valp = C.double(val)
    tvmval.dtype = KDLFloat
    return
}

// getVFloat64 returns the float64 value inside Value.
func (tvmval *Value) getVFloat64() (retVal float64) {
    valp := (*C.double)(unsafe.Pointer(tvmval.nativeCPtr()))
    retVal = float64(*valp)
    return
}

// setVHandle initializes the handle inside the Value.
//
// Can be used to store any uintptr type object like
// module handle, function handle and any object's nativeCPtr.
//
// `val` is the uintptr type of given handle.
func (tvmval *Value) setVHandle(val uintptr) {
    valp := (**C.void)(unsafe.Pointer(tvmval.nativeCPtr()))
    *valp = (*C.void)(unsafe.Pointer(val))
}

// getVHandle returns the uintptr handle
func (tvmval *Value) getVHandle() (retVal uintptr) {
    valp := (**C.void)(unsafe.Pointer(tvmval.nativeCPtr()))
    retVal = uintptr(unsafe.Pointer(*valp))
    return
}

// setVStr intializes the Value with given golang string object.
//
// `val` is the golang string object used to initialize the Value.
func (tvmval *Value) setVStr(val string) {
    valp := (**C.char)(unsafe.Pointer(tvmval.nativeCPtr()))
    *valp = C.CString(val)
    tvmval.dtype = KStr
    return
}


// getVStr returns the golang string for the native string inside Value.
func (tvmval *Value) getVStr() (retVal string) {
    valp := (**C.char)(unsafe.Pointer(tvmval.nativeCPtr()))
    retVal = C.GoString(*valp)
    return
}

// unSetVStr release the memory allocated in setVStr
func (tvmval *Value) unSetVStr() {
    valp := (**C.char)(unsafe.Pointer(tvmval.nativeCPtr()))
	C.free(unsafe.Pointer(*valp))
    tvmval.dtype = KNull
}

// setVAHandle is used to set Array handle in Value.
//
// Application can call the setVHandle with nativeCPtr instead too.
// This is a wrapper to accept Array directly.
func (tvmval *Value) setVAHandle(ptvmarray Array) {
    tvmval.setVHandle(ptvmarray.nativeCPtr())
    tvmval.dtype = KArrayHandle
    return
}

// getVAHandle is used to get Array handle in Value.
func (tvmval *Value) getVAHandle() (retVal Array) {
	retVal = (Array)(tvmval.getVHandle())
    return
}

// setVMHandle is used to set Module handle in Value.
//
// Application can call the setVHandle with nativeCPtr instead too.
// This is a wrapper to accept Module directly.
func (tvmval *Value) setVMHandle(tvmmodule Module) {
    tvmval.setVHandle(tvmmodule.nativeCPtr())
    tvmval.dtype = KModuleHandle
    return
}

// getVMHandle is used to get Module handle in Value.
func (tvmval *Value) getVMHandle() (retVal Module) {
	retVal = (Module)(tvmval.getVHandle())
    return
}

// setVFHandle is used to set Function handle in Value.
//
// Application can call the setVHandle with nativeCPtr instead.
// This is a wrapper to accept Function directly.
func (tvmval *Value) setVFHandle(tvmfunction Function) {
    tvmval.setVHandle(tvmfunction.nativeCPtr())
    tvmval.dtype = KFuncHandle
    return
}

// getVFHandle is used to get Function handle in Value.
func (tvmval *Value) getVFHandle() (retVal Function) {
	retVal = (Function)(tvmval.getVHandle())
    return
}

// setVBHandle is used to set ByteArray handle in Value.
//
// Application can call the setVHandle with nativeCPtr instead.
// This is a wrapper to accept ByteArray directly.
func (tvmval *Value) setVBHandle(tbytearray ByteArray) {
    tvmval.setVHandle(tbytearray.nativeCPtr())
    tvmval.dtype = KBytes
    return
}

// getVBHandle is used to get ByteArray handle in Value.
func (tvmval *Value) getVBHandle() (retVal ByteArray) {
	retVal = (ByteArray)(tvmval.getVHandle())
    return
}

// setValue is used to set the given value in Value.
//
// `val` is value of types accepted by Value container or native union.
func (tvmval *Value) setValue(val interface{}) (retVal int32, err error) {
    retVal = KNull
    switch val.(type) {
        case string:
            tvmval.setVStr(val.(string))
        case uint8:
            tvmval.setVInt64(int64(val.(uint8)))
        case uint16:
            tvmval.setVInt64(int64(val.(uint16)))
        case uint32:
            tvmval.setVInt64(int64(val.(uint32)))
        case uint64:
            tvmval.setVInt64(int64(val.(uint64)))
        case int:
            tvmval.setVInt64(int64(val.(int)))
        case int8:
            tvmval.setVInt64(int64(val.(int8)))
        case int16:
            tvmval.setVInt64(int64(val.(int16)))
        case int32:
            tvmval.setVInt64(int64(val.(int32)))
        case int64:
            tvmval.setVInt64(val.(int64))
        case float32:
            tvmval.setVFloat64(float64(val.(float32)))
        case float64:
            tvmval.setVFloat64(val.(float64))
        case *Module:
            tvmval.setVMHandle(*(val.(*Module)))
        case *Function:
            tvmval.setVFHandle(*(val.(*Function)))
        case *ByteArray:
            tvmval.setVBHandle(*(val.(*ByteArray)))
        case []byte:
            barray := newByteArray(val.([]byte))
            tvmval.setVBHandle(barray)
        case *Array:
            tvmval.setVAHandle(*(val.(*Array)))
        case func (args ...*Value) (interface{}, error):
            fhandle, apierr := ConvertFunction(val)
            if apierr != nil {
Siva committed
329
                err = fmt.Errorf("Given value Type not defined for Value: %v : %T", val, val);
330 331 332 333 334 335 336 337 338 339 340 341
                return
            }
            tvmval.setVFHandle(*fhandle)

            // Clear the finalizer as we don't need to control it anymore.
            runtime.SetFinalizer(fhandle, nil)
        case *Value:
            tvmval.moveFrom(val.(*Value))
        case Value:
            fromval := val.(Value)
            tvmval.moveFrom(&fromval)
        default:
Siva committed
342
            err = fmt.Errorf("Given value Type not defined for Value: %v : %T", val, val);
343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379
    }
    retVal = tvmval.dtype
    return
}

// newTVMValue initialize the TVMValue native object.
//
// This is intended to use as intermediate type between native and golang types.
// Allocated from FuncCall or Callback to handle conversions.
func newTVMValue() (retVal *Value) {
    handle := new(Value)

    handle.nptr = (uintptr(C.malloc(C.sizeof_TVMValue)))
    handle.dtype = KNull
    handle.isLocal = true
    finalizer := func(vhandle *Value) {
        vhandle.deleteTVMValue()
        vhandle = nil
    }
    runtime.SetFinalizer(handle, finalizer)
    retVal = handle
    return
}

// deleteTVMValue free the native Value object which is allocated in newTVMValue.
func (tvmval Value) deleteTVMValue() {
    if tvmval.isLocal == true {
        if tvmval.dtype == KStr {
            tvmval.unSetVStr()
        }
        if tvmval.dtype == KBytes {
            tvmval.getVBHandle().deleteTVMByteArray()
        }
    }

	C.free(unsafe.Pointer(tvmval.nativeCPtr()))
}