/// py_wrapper.cpp /// // #include #include "/usr/include/python3.6m/Python.h" #include "/usr/include/python3.6m/numpy/arrayobject.h" #include "/usr/include/python3.6m/numpy/arrayscalars.h" #include #include #include #include "param.hpp" #include "io.hpp" #include "solver.hpp" #include "tools.hpp" using namespace std; #define N 50 // C++ function (Example) void test_func(const char *f_name, int data[N], int *data_count) { int tmp, count = 0; ifstream inputfile(f_name); if(!inputfile) { cout << f_name << ": Cannot open" << endl; exit(1); } while(1) { string line; if(!getline(inputfile, line)) break; // from file if(line.length() == 0) continue; istringstream iss(line); iss >> tmp; data[count++] = tmp; } cout << "#data = " << count << endl; *data_count = count; } // Wrapper static PyObject* test_func_wrapper(PyObject* self, PyObject* args) { char *f_name = NULL; int c_value; // PyObject (char*, int) if(!PyArg_ParseTuple(args, "si", &f_name, &c_value)) { return NULL; } int data[N], data_count; test_func(f_name, data, &data_count); // create dictionary PyObject* dict = PyDict_New(); // create ndarray int ndim = 1; npy_intp *s = (npy_intp*)malloc(ndim * sizeof(npy_intp)); s[0] = N; PyObject* out_list = PyArray_SimpleNew(ndim, s, NPY_INT32); // ndarray free(s); for(npy_intp i = 0; i < N; i++) { *(int*)PyArray_GETPTR1(out_list, i) = data[i] + c_value; } PyObject* out_key = PyUnicode_FromString("out_key"); PyDict_SetItem(dict, out_key, out_list); // PyObject (dictionary) return dict; } static PyObject* seed_generator_wrapper(PyObject* self, PyObject* args) { uint32_t seed_v; // PyObject (unsigned int) if(!PyArg_ParseTuple(args, "I", &seed_v)) { return NULL; } // create ndarray int ndim = 1; npy_intp *s = (npy_intp*)malloc(ndim * sizeof(npy_intp)); s[0] = 3; PyObject* out_list = PyArray_SimpleNew(ndim, s, NPY_UINT32); free(s); srand(seed_v); *(uint32_t*)PyArray_GETPTR1(out_list, 0) = rand(); *(uint32_t*)PyArray_GETPTR1(out_list, 1) = rand(); *(uint32_t*)PyArray_GETPTR1(out_list, 2) = rand(); // PyObject (ndarray) return out_list; } static PyObject* check_problem_wrapper(PyObject* self, PyObject* args) { char *f_name = NULL; // PyObject (char*) if(!PyArg_ParseTuple(args, "s", &f_name)) { return NULL; } // W: Max width of a board (specified in a problem file) // H: Max height of a board (specified in a problem file) // blocks: # of blocks (specified in a problem file) short int W, H, blocks, line_num; // block data short int block_info[MAX_BLOCKS+1][5][3]; // line data short int line_info[MAX_LINES+1][2][5]; // Check problem read_problem(f_name, &W, &H, &blocks, &line_num, block_info, line_info); extract_line_info(line_num, blocks, block_info, line_info); // create dictionary PyObject* dict = PyDict_New(); // W, H, blocks, line_num // PyObject* W_key = PyUnicode_FromString("W"); PyObject* H_key = PyUnicode_FromString("H"); PyObject* blocks_key = PyUnicode_FromString("blocks"); PyObject* line_key = PyUnicode_FromString("line_num"); int ndim = 1; npy_intp *s = (npy_intp*)malloc(ndim * sizeof(npy_intp)); s[0] = 1; PyObject* W_list = PyArray_SimpleNew(ndim, s, NPY_INT16); // ndarray PyObject* H_list = PyArray_SimpleNew(ndim, s, NPY_INT16); // ndarray PyObject* blocks_list = PyArray_SimpleNew(ndim, s, NPY_INT16); // ndarray PyObject* line_list = PyArray_SimpleNew(ndim, s, NPY_INT16); // ndarray free(s); *(short int*)PyArray_GETPTR1(W_list, 0) = W; *(short int*)PyArray_GETPTR1(H_list, 0) = H; *(short int*)PyArray_GETPTR1(blocks_list, 0) = blocks; *(short int*)PyArray_GETPTR1(line_list, 0) = line_num; PyDict_SetItem(dict, W_key, W_list); PyDict_SetItem(dict, H_key, H_list); PyDict_SetItem(dict, blocks_key, blocks_list); PyDict_SetItem(dict, line_key, line_list); // block_info // PyObject* block_info_key = PyUnicode_FromString("block_info"); ndim = 3; s = (npy_intp*)malloc(ndim * sizeof(npy_intp)); s[0] = MAX_BLOCKS+1; s[1] = 5; s[2] = 3; PyObject* block_info_list = PyArray_SimpleNew(ndim, s, NPY_INT16); // ndarray free(s); for(npy_intp i = 0; i < MAX_BLOCKS+1; i++) { for(npy_intp j = 0; j < 5; j++) { for(npy_intp k = 0; k < 3; k++) { *(short int*)PyArray_GETPTR3(block_info_list, i, j, k) = block_info[i][j][k]; } } } PyDict_SetItem(dict, block_info_key, block_info_list); // line_info // PyObject* line_info_key = PyUnicode_FromString("line_info"); ndim = 3; s = (npy_intp*)malloc(ndim * sizeof(npy_intp)); s[0] = MAX_LINES+1; s[1] = 2; s[2] = 5; PyObject* line_info_list = PyArray_SimpleNew(ndim, s, NPY_INT16); // ndarray free(s); for(npy_intp i = 0; i < MAX_LINES+1; i++) { for(npy_intp j = 0; j < 2; j++) { for(npy_intp k = 0; k < 5; k++) { *(short int*)PyArray_GETPTR3(line_info_list, i, j, k) = line_info[i][j][k]; } } } PyDict_SetItem(dict, line_info_key, line_info_list); // PyObject (dictionary) return dict; } static PyObject* placer_wrapper(PyObject* self, PyObject* args) { uint32_t seed[3]; short int W, H, blocks, line_num; short int block_info[MAX_BLOCKS+1][5][3]; short int line_info[MAX_LINES+1][2][5]; PyObject* a_seed; PyObject* a_block_info; PyObject* a_line_info; // PyObject (ndarray, short int, short int, short int, short int, ndarray, ndarray) if(!PyArg_ParseTuple(args, "O!hhhhO!O!", &PyArray_Type, &a_seed, &W, &H, &blocks, &line_num, &PyArray_Type, &a_block_info, &PyArray_Type, &a_line_info)) { return NULL; } seed[0] = *(uint32_t*)PyArray_GETPTR1(a_seed, 0); seed[1] = *(uint32_t*)PyArray_GETPTR1(a_seed, 1); seed[2] = *(uint32_t*)PyArray_GETPTR1(a_seed, 2); for(npy_intp i = 0; i < MAX_BLOCKS+1; i++) { for(npy_intp j = 0; j < 5; j++) { for(npy_intp k = 0; k < 3; k++) { block_info[i][j][k] = *(short int*)PyArray_GETPTR3(a_block_info, i, j, k); } } } for(npy_intp i = 0; i < MAX_LINES+1; i++) { for(npy_intp j = 0; j < 2; j++) { for(npy_intp k = 0; k < 5; k++) { line_info[i][j][k] = *(short int*)PyArray_GETPTR3(a_line_info, i, j, k); } } } // block positions on slot matrix short int block_place_global[MAX_BLOCKS+1][2]; placer(seed, W, H, blocks, line_num, block_info, line_info, block_place_global); // create dictionary PyObject* dict = PyDict_New(); // seed // PyObject* seed_key = PyUnicode_FromString("seed"); *(uint32_t*)PyArray_GETPTR1(a_seed, 0) = seed[0]; *(uint32_t*)PyArray_GETPTR1(a_seed, 1) = seed[1]; *(uint32_t*)PyArray_GETPTR1(a_seed, 2) = seed[2]; PyDict_SetItem(dict, seed_key, a_seed); // block_info // PyObject* block_place_key = PyUnicode_FromString("block_place"); int ndim = 2; npy_intp *s = (npy_intp*)malloc(ndim * sizeof(npy_intp)); s[0] = MAX_BLOCKS+1; s[1] = 2; PyObject* block_place_list = PyArray_SimpleNew(ndim, s, NPY_INT16); // ndarray free(s); for(npy_intp i = 0; i < MAX_BLOCKS+1; i++) { *(short int*)PyArray_GETPTR2(block_place_list, i, 0) = block_place_global[i][0]; *(short int*)PyArray_GETPTR2(block_place_list, i, 1) = block_place_global[i][1]; } PyDict_SetItem(dict, block_place_key, block_place_list); // PyObject (dictionary) return dict; } static PyObject* solver_wrapper(PyObject* self, PyObject* args) { uint32_t seed[3]; short int W, H, blocks, line_num; short int block_info[MAX_BLOCKS+1][5][3]; short int line_info[MAX_LINES+1][2][5]; PyObject* a_seed; PyObject* a_block_info; PyObject* a_line_info; // PyObject (ndarray, short int, short int, short int, short int, ndarray, ndarray) if(!PyArg_ParseTuple(args, "O!hhhhO!O!", &PyArray_Type, &a_seed, &W, &H, &blocks, &line_num, &PyArray_Type, &a_block_info, &PyArray_Type, &a_line_info)) { return NULL; } seed[0] = *(uint32_t*)PyArray_GETPTR1(a_seed, 0); seed[1] = *(uint32_t*)PyArray_GETPTR1(a_seed, 1); seed[2] = *(uint32_t*)PyArray_GETPTR1(a_seed, 2); for(npy_intp i = 0; i < MAX_BLOCKS+1; i++) { for(npy_intp j = 0; j < 5; j++) { for(npy_intp k = 0; k < 3; k++) { block_info[i][j][k] = *(short int*)PyArray_GETPTR3(a_block_info, i, j, k); } } } for(npy_intp i = 0; i < MAX_LINES+1; i++) { for(npy_intp j = 0; j < 2; j++) { for(npy_intp k = 0; k < 5; k++) { line_info[i][j][k] = *(short int*)PyArray_GETPTR3(a_line_info, i, j, k); } } } // W_ext: Width of a current solution // H_ext: Height of a current solution short int W_ext, H_ext; // An opt. result will be stored in the array short int opt_result[MAX_CELLS]; int status = solver(seed, W, H, blocks, line_num, block_info, line_info, &W_ext, &H_ext, opt_result); // create dictionary PyObject* dict = PyDict_New(); // status // PyObject* status_key = PyUnicode_FromString("status"); PyObject* W_ext_key = PyUnicode_FromString("W_ext"); PyObject* H_ext_key = PyUnicode_FromString("H_ext"); int ndim = 1; npy_intp *s = (npy_intp*)malloc(ndim * sizeof(npy_intp)); s[0] = 1; PyObject* status_list = PyArray_SimpleNew(ndim, s, NPY_INT32); // ndarray PyObject* W_ext_list = PyArray_SimpleNew(ndim, s, NPY_INT16); // ndarray PyObject* H_ext_list = PyArray_SimpleNew(ndim, s, NPY_INT16); // ndarray free(s); *(int*)PyArray_GETPTR1(status_list, 0) = status; *(short int*)PyArray_GETPTR1(W_ext_list, 0) = W_ext; *(short int*)PyArray_GETPTR1(H_ext_list, 0) = H_ext; PyDict_SetItem(dict, status_key, status_list); PyDict_SetItem(dict, W_ext_key, W_ext_list); PyDict_SetItem(dict, H_ext_key, H_ext_list); // block_info // PyObject* block_info_key = PyUnicode_FromString("block_info"); ndim = 3; s = (npy_intp*)malloc(ndim * sizeof(npy_intp)); s[0] = MAX_BLOCKS+1; s[1] = 5; s[2] = 3; PyObject* block_info_list = PyArray_SimpleNew(ndim, s, NPY_INT16); // ndarray free(s); for(npy_intp i = 0; i < MAX_BLOCKS+1; i++) { for(npy_intp j = 0; j < 5; j++) { for(npy_intp k = 0; k < 3; k++) { *(short int*)PyArray_GETPTR3(block_info_list, i, j, k) = block_info[i][j][k]; } } } PyDict_SetItem(dict, block_info_key, block_info_list); // opt_result // PyObject* opt_result_key = PyUnicode_FromString("opt_result"); ndim = 1; s = (npy_intp*)malloc(ndim * sizeof(npy_intp)); s[0] = MAX_CELLS; PyObject* opt_result_list = PyArray_SimpleNew(ndim, s, NPY_INT16); // ndarray free(s); for(npy_intp i = 0; i < MAX_CELLS; i++) { *(short int*)PyArray_GETPTR1(opt_result_list, i) = opt_result[i]; } PyDict_SetItem(dict, opt_result_key, opt_result_list); // PyObject (dictionary) return dict; } static PyObject* show_result_wrapper(PyObject* self, PyObject* args) { short int W_ext, H_ext, blocks, line_num; short int block_info[MAX_BLOCKS+1][5][3]; short int opt_result[MAX_CELLS]; PyObject* a_block_info; PyObject* a_opt_result; // PyObject (short int, short int, short int, short int, ndarray, ndarray) if(!PyArg_ParseTuple(args, "hhhhO!O!", &W_ext, &H_ext, &blocks, &line_num, &PyArray_Type, &a_block_info, &PyArray_Type, &a_opt_result)) { return NULL; } for(npy_intp i = 0; i < MAX_BLOCKS+1; i++) { for(npy_intp j = 0; j < 5; j++) { for(npy_intp k = 0; k < 3; k++) { block_info[i][j][k] = *(short int*)PyArray_GETPTR3(a_block_info, i, j, k); } } } for(npy_intp i = 0; i < MAX_CELLS; i++) { opt_result[i] = *(short int*)PyArray_GETPTR1(a_opt_result, i); } cout << "== Answer ==" << endl; cout << "SIZE " << W_ext << "X" << H_ext << endl; pair block_place_basis[MAX_BLOCKS+1]; for(int i = 1; i <= blocks; i++) { block_place_basis[i] = make_pair(block_info[i][0][0], block_info[i][0][1]); } show_result(line_num, blocks, W_ext, H_ext, opt_result, block_place_basis); return Py_None; } static PyObject* output_to_file_wrapper(PyObject* self, PyObject* args) { char *f_name = NULL; short int W_ext, H_ext, blocks, line_num; short int block_info[MAX_BLOCKS+1][5][3]; short int opt_result[MAX_CELLS]; PyObject* a_block_info; PyObject* a_opt_result; // PyObject (char* short int, short int, short int, short int, ndarray, ndarray) if(!PyArg_ParseTuple(args, "shhhhO!O!", &f_name, &W_ext, &H_ext, &blocks, &line_num, &PyArray_Type, &a_block_info, &PyArray_Type, &a_opt_result)) { return NULL; } for(npy_intp i = 0; i < MAX_BLOCKS+1; i++) { for(npy_intp j = 0; j < 5; j++) { for(npy_intp k = 0; k < 3; k++) { block_info[i][j][k] = *(short int*)PyArray_GETPTR3(a_block_info, i, j, k); } } } for(npy_intp i = 0; i < MAX_CELLS; i++) { opt_result[i] = *(short int*)PyArray_GETPTR1(a_opt_result, i); } cout << "Output to " << f_name << endl; pair block_place_basis[MAX_BLOCKS+1]; for(int i = 1; i <= blocks; i++) { block_place_basis[i] = make_pair(block_info[i][0][0], block_info[i][0][1]); } output_to_file(f_name, line_num, blocks, W_ext, H_ext, opt_result, block_place_basis); return Py_None; } // Module definition static PyMethodDef mySolverMethods[] = { {"test_func", test_func_wrapper, METH_VARARGS, "test function"}, {"seed_generator", seed_generator_wrapper, METH_VARARGS, "generate seed values"}, {"check_problem", check_problem_wrapper, METH_VARARGS, "read problem"}, {"placer", placer_wrapper, METH_VARARGS, "placer"}, {"solver", solver_wrapper, METH_VARARGS, "solver"}, {"show_result", show_result_wrapper, METH_VARARGS, "show result"}, {"output_to_file", output_to_file_wrapper, METH_VARARGS, "output result to file"}, {NULL} }; static struct PyModuleDef mySolverModule = { PyModuleDef_HEAD_INIT, "mySolverModule", "Python3 C API Module(test)", -1, mySolverMethods }; // Init. myModule PyMODINIT_FUNC PyInit_mySolverModule(void) { import_array(); return PyModule_Create(&mySolverModule); }