blob: 52f1c690e0e2918f1ab7d6f1d1b182bc4497f9b1 [file] [log] [blame]
/*
* Copyright (c) 2020 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* 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
*
* 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.
*/
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <cstdint>
#include <vector>
#include "search_allocator.h"
/**
* C++ extension wrapper for allocate
*
* This method is exposed directly in python with the arguments with a
* prototype of the form:
*
* output = tensor_allocator.allocate(input, available_size=0)
*
* input: [int]
* available_size: int
* output: [int]
*/
static PyObject *method_allocate (PyObject *self, PyObject *args)
{
/* Object to hold the input integer list. */
PyObject *input_list_object;
/* Object to hold the available size */
int available_size = 0;
/* Arguments to the method are delivered as a tuple, unpack the
* tuple to get the individual arguments, note the second is
* optional.
*/
if (!PyArg_ParseTuple(args, "O|i", &input_list_object, &available_size)) {
return NULL;
}
/* Unpack the length of the input integer list. */
auto input_length = PyObject_Length(input_list_object);
if (input_length < 0) {
return NULL;
}
if (input_length % 3 != 0) {
PyErr_SetString(PyExc_ValueError, "Input length must be multiple of 3");
return NULL;
}
std::vector<uint32_t> input;
std::vector<uint32_t> output;
for (int i = 0; i < input_length; ++i) {
PyObject *obj = PyList_GetItem(input_list_object, i);
if (!PyLong_Check(obj)) {
PyErr_SetString(PyExc_ValueError, "Illegal value in input");
return NULL;
}
auto value = PyLong_AsLong(obj);
if (value < 0 || value > UINT32_MAX) {
PyErr_SetString(PyExc_ValueError, "Input value out of bounds");
return NULL;
}
input.push_back(value);
}
allocate(input, available_size, output);
PyObject *output_list = PyList_New(output.size());
for (size_t i = 0; i < output.size(); ++i) {
PyList_SetItem(output_list, i, PyLong_FromLong(output[i]));
}
return output_list;
}
/** tensor_allocator method descriptors. */
static PyMethodDef tensor_allocator_methods[] = {
{"allocate", method_allocate, METH_VARARGS, "Python interface for allocate"},
{NULL, NULL, 0, NULL}
};
/** tensor_allocator module descriptor. */
static struct PyModuleDef tensor_allocatormodule = {
PyModuleDef_HEAD_INIT,
"tensor_allocator",
"Python interface for tensor_allocator",
-1,
tensor_allocator_methods
};
PyMODINIT_FUNC PyInit_tensor_allocator(void) {
return PyModule_Create(&tensor_allocatormodule);
}