c_api.cpp 13.4 KB
Newer Older
N
nihui 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/* Tencent is pleased to support the open source community by making ncnn available.
 *
 * Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
 *
 * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * https://opensource.org/licenses/BSD-3-Clause
 *
 * 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.
 */

#include "c_api.h"

N
nihuini 已提交
18 19 20
#include "blob.h"
#include "datareader.h"
#include "layer.h"
N
nihui 已提交
21
#include "mat.h"
N
nihuini 已提交
22
#include "modelbin.h"
N
nihui 已提交
23
#include "net.h"
N
nihuini 已提交
24 25
#include "option.h"
#include "paramdict.h"
N
nihui 已提交
26 27

using ncnn::Blob;
N
nihuini 已提交
28
using ncnn::DataReader;
N
nihui 已提交
29 30 31
using ncnn::Extractor;
using ncnn::Layer;
using ncnn::Mat;
N
nihuini 已提交
32
using ncnn::ModelBin;
N
nihui 已提交
33 34
using ncnn::Net;
using ncnn::Option;
N
nihuini 已提交
35
using ncnn::ParamDict;
N
nihui 已提交
36 37 38 39 40

#ifdef __cplusplus
extern "C" {
#endif

N
nihui 已提交
41 42 43 44 45
const char* ncnn_version()
{
    return NCNN_VERSION_STRING;
}

N
nihui 已提交
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
/* mat api */
ncnn_mat_t ncnn_mat_create()
{
    return (ncnn_mat_t)(new Mat());
}

ncnn_mat_t ncnn_mat_create_1d(int w)
{
    return (ncnn_mat_t)(new Mat(w));
}

ncnn_mat_t ncnn_mat_create_2d(int w, int h)
{
    return (ncnn_mat_t)(new Mat(w, h));
}

ncnn_mat_t ncnn_mat_create_3d(int w, int h, int c)
{
    return (ncnn_mat_t)(new Mat(w, h, c));
}

ncnn_mat_t ncnn_mat_create_1d_packed(int w, size_t elemsize, int elempack)
{
    return (ncnn_mat_t)(new Mat(w, elemsize, elempack));
}

ncnn_mat_t ncnn_mat_create_2d_packed(int w, int h, size_t elemsize, int elempack)
{
    return (ncnn_mat_t)(new Mat(w, h, elemsize, elempack));
}

ncnn_mat_t ncnn_mat_create_3d_packed(int w, int h, int c, size_t elemsize, int elempack)
{
    return (ncnn_mat_t)(new Mat(w, h, c, elemsize, elempack));
}

void ncnn_mat_destroy(ncnn_mat_t mat)
{
    delete (Mat*)mat;
}

N
nihuini 已提交
87
int ncnn_mat_get_dims(const ncnn_mat_t mat)
N
nihui 已提交
88
{
N
nihuini 已提交
89
    return ((const Mat*)mat)->dims;
N
nihui 已提交
90 91
}

N
nihuini 已提交
92
int ncnn_mat_get_w(const ncnn_mat_t mat)
N
nihui 已提交
93
{
N
nihuini 已提交
94
    return ((const Mat*)mat)->w;
N
nihui 已提交
95 96
}

N
nihuini 已提交
97
int ncnn_mat_get_h(const ncnn_mat_t mat)
N
nihui 已提交
98
{
N
nihuini 已提交
99
    return ((const Mat*)mat)->h;
N
nihui 已提交
100 101
}

N
nihuini 已提交
102
int ncnn_mat_get_c(const ncnn_mat_t mat)
N
nihui 已提交
103
{
N
nihuini 已提交
104
    return ((const Mat*)mat)->c;
N
nihui 已提交
105 106
}

N
nihuini 已提交
107
size_t ncnn_mat_get_elemsize(const ncnn_mat_t mat)
N
nihui 已提交
108
{
N
nihuini 已提交
109
    return ((const Mat*)mat)->elemsize;
N
nihui 已提交
110 111
}

N
nihuini 已提交
112
int ncnn_mat_get_elempack(const ncnn_mat_t mat)
N
nihui 已提交
113
{
N
nihuini 已提交
114
    return ((const Mat*)mat)->elempack;
N
nihui 已提交
115 116
}

N
nihuini 已提交
117
size_t ncnn_mat_get_cstep(const ncnn_mat_t mat)
N
nihui 已提交
118
{
N
nihuini 已提交
119
    return ((const Mat*)mat)->cstep;
N
nihui 已提交
120 121
}

N
nihuini 已提交
122
void* ncnn_mat_get_data(const ncnn_mat_t mat)
N
nihui 已提交
123
{
N
nihuini 已提交
124
    return ((const Mat*)mat)->data;
N
nihui 已提交
125 126
}

127 128
#if NCNN_PIXEL

N
nihui 已提交
129 130 131 132 133 134 135 136 137 138 139
/* mat pixel api */
ncnn_mat_t ncnn_mat_from_pixels(const unsigned char* pixels, int type, int w, int h, int stride)
{
    return (ncnn_mat_t)(new Mat(Mat::from_pixels(pixels, type, w, h, stride)));
}

ncnn_mat_t ncnn_mat_from_pixels_resize(const unsigned char* pixels, int type, int w, int h, int stride, int target_width, int target_height)
{
    return (ncnn_mat_t)(new Mat(Mat::from_pixels_resize(pixels, type, w, h, stride, target_width, target_height)));
}

N
nihuini 已提交
140
void ncnn_mat_to_pixels(const ncnn_mat_t mat, unsigned char* pixels, int type, int stride)
N
nihui 已提交
141
{
N
nihuini 已提交
142
    ((const Mat*)mat)->to_pixels(pixels, type, stride);
N
nihui 已提交
143 144
}

N
nihuini 已提交
145
void ncnn_mat_to_pixels_resize(const ncnn_mat_t mat, unsigned char* pixels, int type, int target_width, int target_height, int target_stride)
N
nihui 已提交
146
{
N
nihuini 已提交
147
    ((const Mat*)mat)->to_pixels_resize(pixels, type, target_width, target_height, target_stride);
N
nihui 已提交
148 149
}

150 151
#endif

N
nihui 已提交
152 153 154 155 156
void ncnn_mat_substract_mean_normalize(ncnn_mat_t mat, const float* mean_vals, const float* norm_vals)
{
    ((Mat*)mat)->substract_mean_normalize(mean_vals, norm_vals);
}

N
nihuini 已提交
157 158 159 160 161
void ncnn_mat_fill_float(ncnn_mat_t mat, float v)
{
    ((Mat*)mat)->fill(v);
}

N
nihui 已提交
162 163 164 165 166 167 168 169 170 171 172
/* option api */
ncnn_option_t ncnn_option_create()
{
    return (ncnn_option_t)(new Option());
}

void ncnn_option_destroy(ncnn_option_t opt)
{
    delete (Option*)opt;
}

N
nihuini 已提交
173
int ncnn_option_get_num_threads(const ncnn_option_t opt)
N
nihui 已提交
174
{
N
nihuini 已提交
175
    return ((const Option*)opt)->num_threads;
N
nihui 已提交
176 177 178 179 180 181 182
}

void ncnn_option_set_num_threads(ncnn_option_t opt, int num_threads)
{
    ((Option*)opt)->num_threads = num_threads;
}

N
nihuini 已提交
183
int ncnn_option_get_use_vulkan_compute(const ncnn_option_t opt)
N
nihui 已提交
184 185
{
#if NCNN_VULKAN
N
nihuini 已提交
186
    return ((const Option*)opt)->use_vulkan_compute;
N
nihui 已提交
187
#else
188
    (void)opt;
N
nihui 已提交
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
    return 0;
#endif
}

void ncnn_option_set_use_vulkan_compute(ncnn_option_t opt, int use_vulkan_compute)
{
#if NCNN_VULKAN
    ((Option*)opt)->use_vulkan_compute = use_vulkan_compute;
#else
    (void)opt;
    (void)use_vulkan_compute;
#endif
}

/* blob api */
N
nihuini 已提交
204
const char* ncnn_blob_get_name(const ncnn_blob_t blob)
N
nihui 已提交
205 206
{
#if NCNN_STRING
N
nihuini 已提交
207
    return ((const Blob*)blob)->name.c_str();
N
nihui 已提交
208
#else
209
    (void)blob;
N
nihui 已提交
210 211 212 213
    return "";
#endif
}

N
nihuini 已提交
214
int ncnn_blob_get_producer(const ncnn_blob_t blob)
N
nihui 已提交
215
{
N
nihuini 已提交
216
    return ((const Blob*)blob)->producer;
N
nihui 已提交
217 218
}

N
nihuini 已提交
219
int ncnn_blob_get_consumer(const ncnn_blob_t blob)
N
nihui 已提交
220
{
N
nihuini 已提交
221
    return ((const Blob*)blob)->consumer;
N
nihui 已提交
222 223
}

N
nihuini 已提交
224
void ncnn_blob_get_shape(const ncnn_blob_t blob, int* dims, int* w, int* h, int* c)
N
nihui 已提交
225
{
N
nihuini 已提交
226
    const Mat& shape = ((const Blob*)blob)->shape;
N
nihui 已提交
227 228 229 230 231 232
    *dims = shape.dims;
    *w = shape.w;
    *h = shape.h;
    *c = shape.c;
}

N
nihuini 已提交
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 329 330 331 332
/* paramdict api */
ncnn_paramdict_t ncnn_paramdict_create()
{
    return (ncnn_paramdict_t)(new ParamDict());
}

void ncnn_paramdict_destroy(ncnn_paramdict_t pd)
{
    delete (ParamDict*)pd;
}

int ncnn_paramdict_get_type(const ncnn_paramdict_t pd, int id)
{
    return ((const ParamDict*)pd)->type(id);
}

int ncnn_paramdict_get_int(const ncnn_paramdict_t pd, int id, int def)
{
    return ((const ParamDict*)pd)->get(id, def);
}

int ncnn_paramdict_get_float(const ncnn_paramdict_t pd, int id, float def)
{
    return ((const ParamDict*)pd)->get(id, def);
}

ncnn_mat_t ncnn_paramdict_get_array(ncnn_paramdict_t pd, int id, const ncnn_mat_t def)
{
    return (ncnn_mat_t)(new Mat(((const ParamDict*)pd)->get(id, *(const Mat*)def)));
}

void ncnn_paramdict_set_int(ncnn_paramdict_t pd, int id, int i)
{
    return ((ParamDict*)pd)->set(id, i);
}

void ncnn_paramdict_set_float(ncnn_paramdict_t pd, int id, float f)
{
    return ((ParamDict*)pd)->set(id, f);
}

void ncnn_paramdict_set_array(ncnn_paramdict_t pd, int id, ncnn_mat_t v)
{
    return ((ParamDict*)pd)->set(id, *(const Mat*)v);
}

/* datareader api */
#if NCNN_STDIO
ncnn_datareader_t ncnn_datareader_from_stdio(FILE* fp)
{
    return (ncnn_datareader_t)(new ncnn::DataReaderFromStdio(fp));
}
#endif

ncnn_datareader_t ncnn_datareader_from_memory(const unsigned char** mem)
{
    return (ncnn_datareader_t)(new ncnn::DataReaderFromMemory(*mem));
}

void ncnn_datareader_destroy(ncnn_datareader_t dr)
{
    delete (DataReader*)dr;
}

/* modelbin api */
ncnn_modelbin_t ncnn_modelbin_from_datareader(const ncnn_datareader_t dr)
{
    return (ncnn_modelbin_t)(new ncnn::ModelBinFromDataReader(*(const DataReader*)dr));
}

ncnn_modelbin_t ncnn_modelbin_from_mat_array(const ncnn_mat_t* weights, int n)
{
    std::vector<Mat> matarray(n);
    for (int i = 0; i < n; i++)
    {
        matarray[i] = *(const Mat*)weights[i];
    }
    return (ncnn_modelbin_t)(new ncnn::ModelBinFromMatArray(&matarray[0]));
}

void ncnn_modelbin_destroy(ncnn_modelbin_t mb)
{
    delete (ModelBin*)mb;
}

ncnn_mat_t ncnn_modelbin_load_1d(const ncnn_modelbin_t mb, int w, int type)
{
    return (ncnn_mat_t)(new Mat(((const ModelBin*)mb)->load(w, type)));
}

ncnn_mat_t ncnn_modelbin_load_2d(const ncnn_modelbin_t mb, int w, int h, int type)
{
    return (ncnn_mat_t)(new Mat(((const ModelBin*)mb)->load(w, h, type)));
}

ncnn_mat_t ncnn_modelbin_load_3d(const ncnn_modelbin_t mb, int w, int h, int c, int type)
{
    return (ncnn_mat_t)(new Mat(((const ModelBin*)mb)->load(w, h, c, type)));
}

N
nihui 已提交
333
/* layer api */
N
nihuini 已提交
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349
ncnn_layer_t ncnn_layer_create_by_typeindex(int typeindex)
{
    return (ncnn_layer_t)(ncnn::create_layer(typeindex));
}

ncnn_layer_t ncnn_layer_create_by_type(const char* type)
{
    return (ncnn_layer_t)(ncnn::create_layer(type));
}

void ncnn_layer_destroy(ncnn_layer_t layer)
{
    delete (Layer*)layer;
}

const char* ncnn_layer_get_name(const ncnn_layer_t layer)
N
nihui 已提交
350 351
{
#if NCNN_STRING
N
nihuini 已提交
352
    return ((const Layer*)layer)->name.c_str();
N
nihui 已提交
353
#else
354
    (void)layer;
N
nihui 已提交
355 356 357 358
    return "";
#endif
}

N
nihuini 已提交
359
int ncnn_layer_get_typeindex(const ncnn_layer_t layer)
N
nihui 已提交
360
{
N
nihuini 已提交
361
    return ((const Layer*)layer)->typeindex;
N
nihui 已提交
362 363
}

N
nihuini 已提交
364
const char* ncnn_layer_get_type(const ncnn_layer_t layer)
N
nihui 已提交
365 366
{
#if NCNN_STRING
N
nihuini 已提交
367
    return ((const Layer*)layer)->type.c_str();
N
nihui 已提交
368
#else
369
    (void)layer;
N
nihui 已提交
370 371 372 373
    return "";
#endif
}

N
nihuini 已提交
374
int ncnn_layer_get_bottom_count(const ncnn_layer_t layer)
N
nihui 已提交
375
{
N
nihuini 已提交
376
    return (int)((const Layer*)layer)->bottoms.size();
N
nihui 已提交
377 378
}

N
nihuini 已提交
379
int ncnn_layer_get_bottom(const ncnn_layer_t layer, int i)
N
nihui 已提交
380
{
N
nihuini 已提交
381
    return ((const Layer*)layer)->bottoms[i];
N
nihui 已提交
382 383
}

N
nihuini 已提交
384
int ncnn_layer_get_top_count(const ncnn_layer_t layer)
N
nihui 已提交
385
{
N
nihuini 已提交
386
    return (int)((const Layer*)layer)->tops.size();
N
nihui 已提交
387 388
}

N
nihuini 已提交
389
int ncnn_layer_get_top(const ncnn_layer_t layer, int i)
N
nihui 已提交
390
{
N
nihuini 已提交
391
    return ((const Layer*)layer)->tops[i];
N
nihui 已提交
392 393
}

N
nihuini 已提交
394
void ncnn_blob_get_bottom_shape(const ncnn_layer_t layer, int i, int* dims, int* w, int* h, int* c)
N
nihui 已提交
395
{
N
nihuini 已提交
396
    const Mat& shape = ((const Layer*)layer)->bottom_shapes[i];
N
nihui 已提交
397 398 399 400 401 402
    *dims = shape.dims;
    *w = shape.w;
    *h = shape.h;
    *c = shape.c;
}

N
nihuini 已提交
403
void ncnn_blob_get_top_shape(const ncnn_layer_t layer, int i, int* dims, int* w, int* h, int* c)
N
nihui 已提交
404
{
N
nihuini 已提交
405
    const Mat& shape = ((const Layer*)layer)->top_shapes[i];
N
nihui 已提交
406 407 408 409 410 411
    *dims = shape.dims;
    *w = shape.w;
    *h = shape.h;
    *c = shape.c;
}

N
nihuini 已提交
412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470
int ncnn_layer_load_param(ncnn_layer_t layer, const ncnn_paramdict_t pd)
{
    return ((Layer*)layer)->load_param(*(const ParamDict*)pd);
}

int ncnn_layer_load_model(ncnn_layer_t layer, const ncnn_modelbin_t mb)
{
    return ((Layer*)layer)->load_model(*(const ModelBin*)mb);
}

int ncnn_layer_create_pipeline(ncnn_layer_t layer, const ncnn_option_t opt)
{
    return ((Layer*)layer)->create_pipeline(*(const Option*)opt);
}

int ncnn_layer_destroy_pipeline(ncnn_layer_t layer, const ncnn_option_t opt)
{
    return ((Layer*)layer)->destroy_pipeline(*(const Option*)opt);
}

int ncnn_layer_forward_1(const ncnn_layer_t layer, const ncnn_mat_t bottom_blob, ncnn_mat_t* top_blob, const ncnn_option_t opt)
{
    Mat _top_blob;
    int ret = ((const Layer*)layer)->forward(*(const Mat*)bottom_blob, _top_blob, *(const Option*)opt);
    *top_blob = (ncnn_mat_t)(new Mat(_top_blob));
    return ret;
}

int ncnn_layer_forward_n(const ncnn_layer_t layer, const ncnn_mat_t* bottom_blobs, int n, ncnn_mat_t** top_blobs, int n2, const ncnn_option_t opt)
{
    std::vector<Mat> _bottom_blobs(n);
    std::vector<Mat> _top_blobs(n2);
    for (int i = 0; i < n; i++)
    {
        _bottom_blobs[i] = *(Mat*)bottom_blobs[i];
    }
    int ret = ((const Layer*)layer)->forward(_bottom_blobs, _top_blobs, *(const Option*)opt);
    for (int i = 0; i < n2; i++)
    {
        *top_blobs[i] = (ncnn_mat_t)(new Mat(_top_blobs[i]));
    }
    return ret;
}

int ncnn_layer_forward_inplace_1(const ncnn_layer_t layer, ncnn_mat_t bottom_top_blob, const ncnn_option_t opt)
{
    return ((const Layer*)layer)->forward_inplace(*(Mat*)bottom_top_blob, *(const Option*)opt);
}

int ncnn_layer_forward_inplace_n(const ncnn_layer_t layer, ncnn_mat_t* bottom_top_blobs, int n, const ncnn_option_t opt)
{
    std::vector<Mat> _bottom_top_blobs(n);
    for (int i = 0; i < n; i++)
    {
        _bottom_top_blobs[i] = *(Mat*)bottom_top_blobs[i];
    }
    return ((const Layer*)layer)->forward_inplace(_bottom_top_blobs, *(const Option*)opt);
}

N
nihui 已提交
471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491
/* net api */
ncnn_net_t ncnn_net_create()
{
    return (ncnn_net_t)(new Net);
}

void ncnn_net_destroy(ncnn_net_t net)
{
    delete (Net*)net;
}

void ncnn_net_set_option(ncnn_net_t net, ncnn_option_t opt)
{
    ((Net*)net)->opt = *((Option*)opt);
}

int ncnn_net_load_param(ncnn_net_t net, const char* path)
{
#if NCNN_STDIO && NCNN_STRING
    return ((Net*)net)->load_param(path);
#else
492 493
    (void)path;
    (void)net;
N
nihui 已提交
494 495 496 497 498 499 500 501 502
    return -1;
#endif
}

int ncnn_net_load_model(ncnn_net_t net, const char* path)
{
#if NCNN_STDIO && NCNN_STRING
    return ((Net*)net)->load_model(path);
#else
503 504
    (void)path;
    (void)net;
N
nihui 已提交
505 506 507 508
    return -1;
#endif
}

N
nihuini 已提交
509
int ncnn_net_get_layer_count(const ncnn_net_t net)
N
nihui 已提交
510
{
N
nihuini 已提交
511
    return (int)((const Net*)net)->layers.size();
N
nihui 已提交
512 513
}

N
nihuini 已提交
514
ncnn_layer_t ncnn_net_get_layer(const ncnn_net_t net, int i)
N
nihui 已提交
515
{
N
nihuini 已提交
516
    return (ncnn_layer_t)((const Net*)net)->layers[i];
N
nihui 已提交
517 518
}

N
nihuini 已提交
519
int ncnn_net_get_blob_count(const ncnn_net_t net)
N
nihui 已提交
520
{
N
nihuini 已提交
521
    return (int)((const Net*)net)->blobs.size();
N
nihui 已提交
522 523
}

N
nihuini 已提交
524
ncnn_blob_t ncnn_net_get_blob(const ncnn_net_t net, int i)
N
nihui 已提交
525
{
N
nihuini 已提交
526
    return (ncnn_blob_t)(&((const Net*)net)->blobs[i]);
N
nihui 已提交
527 528 529 530 531 532 533 534 535 536 537 538 539
}

/* extractor api */
ncnn_extractor_t ncnn_extractor_create(ncnn_net_t net)
{
    return (ncnn_extractor_t)(new Extractor(((Net*)net)->create_extractor()));
}

void ncnn_extractor_destroy(ncnn_extractor_t ex)
{
    delete (Extractor*)ex;
}

N
nihuini 已提交
540
void ncnn_extractor_set_option(ncnn_extractor_t ex, const ncnn_option_t opt)
N
nihui 已提交
541
{
N
nihuini 已提交
542
    ((Extractor*)ex)->set_num_threads(((const Option*)opt)->num_threads);
N
nihui 已提交
543
#if NCNN_VULKAN
N
nihuini 已提交
544
    ((Extractor*)ex)->set_vulkan_compute(((const Option*)opt)->use_vulkan_compute);
N
nihui 已提交
545 546 547
#endif
}

N
nihuini 已提交
548
int ncnn_extractor_input(ncnn_extractor_t ex, const char* name, const ncnn_mat_t mat)
N
nihui 已提交
549 550
{
#if NCNN_STRING
N
nihuini 已提交
551
    return ((Extractor*)ex)->input(name, *((const Mat*)mat));
N
nihui 已提交
552
#else
553 554 555
    (void)ex;
    (void)name;
    (void)mat;
N
nihui 已提交
556 557 558 559 560 561 562 563 564 565 566 567
    return -1;
#endif
}

int ncnn_extractor_extract(ncnn_extractor_t ex, const char* name, ncnn_mat_t* mat)
{
#if NCNN_STRING
    Mat mat0;
    int ret = ((Extractor*)ex)->extract(name, mat0);
    *mat = (ncnn_mat_t)(new Mat(mat0));
    return ret;
#else
568 569 570
    (void)ex;
    (void)name;
    (void)mat;
N
nihui 已提交
571 572 573 574 575 576 577
    return -1;
#endif
}

#ifdef __cplusplus
} /* extern "C" */
#endif