Skip to content

test_prof_api.c

This is an example code of DNN profiling and tuning.

Usage

$ test_prof_api DNN RECIPE [TUNED]

Arguments

  • DNN: The input DNN model file (*.dnn) to be profiled and tuned.
  • RECIPE: The output tuning recipe.
  • TUNED: The output tuned DNN file (*.dnn).

If the profiling and tuning succeeds, the recipe file and tuned DNN file will be generated. The tuned DNN file runs faster than the original DNN file.

Example Result

$ ls
mobilenet.dnn  test_prof_api
$ test_prof_api mobilenet.dnn recipe mobilenet_tuned.dnn
Profiling..  0.0%
...
Profiling..100.0%
$ls
mobilenet.dnn  mobilenet_tuned.dnn  recipe  test_prof_api

Sample Code

#include "morapi_softneuro.h"
#include <stdio.h>


/* Command usage. */
void
usage(void)
{
    printf("test_prof_api DNN RECIPE [TUNED]\n"
           "\n"
           "profile, optimize and tune a dnn with 'cpu' and 'cpu:qint8' routines.\n"
           "\n"
           "positional arguments:\n"
           "  DNN     the input dnn.\n"
           "  RECIPE  the output recipe.\n"
           "  TUNED   the tuned dnn.\n");
}


/* Progress function for profiling. */
void
profProgress(void *obj, morapi_DnnProf *i_prof)
{
    morapi_Real progress = morapi_DnnProf_getProgress(i_prof);

    printf("\rProfiling..%5.1f%%", progress*100);
    fflush(stdout);

    if (1.0 <= progress) {
        printf("\n");
    }
}


int
main(int argc, char **argv)
{
    morapi_Result ret = MORAPI_OK;
    morapi_Env *env = NULL;
    morapi_Dnn *dnn = NULL;
    morapi_DnnProf *prof = NULL;
    morapi_DnnOptimizer *optimizer = NULL;
    morapi_DnnRecipe *recipe = NULL;
    const morapi_Char *routines[] = {"cpu", "cpu:qint8"}; /*< routines to be profiled. */
    morapi_Int32 i;

    if (argc != 3 && argc != 4) {
        usage();
        return 0;
    }

    /* create env. */
    env = morapi_create_Env(NULL, 0);
    ret |= morapi_Env_setLogFunc(env, (morapi_LogFunc)&fprintf, stderr);
    ret |= morapi_Env_setMsgFunc(env, (morapi_LogFunc)&fprintf, (morapi_FlushFunc)&fflush, stdout);

    /* create objects. */
    dnn = morapi_create_Dnn(env);
    prof = morapi_create_DnnProf(env);
    optimizer = morapi_create_DnnOptimizer(env);
    recipe = morapi_create_DnnRecipe(env);

    /* load dnn. */
    if (MORAPI_OK != (ret |= morapi_Dnn_load(dnn, argv[1], NULL, 0, MORAPI_TRUE))) {
        goto EXIT;
    }

    /* set up profiler. */
    ret |= morapi_DnnProf_init(prof, dnn);
    for (i = 0; i < sizeof(routines)/sizeof(char*); ++i) {
        ret |= morapi_DnnProf_add(prof, routines[i], NULL);
    }

    /* profile. */
    ret |= morapi_DnnProf_profile(prof, &profProgress, NULL);

    /* optimize. */
    ret |= morapi_DnnOptimizer_init(optimizer, prof);
    ret |= morapi_DnnOptimizer_optimize(optimizer);

    /* make and save recipe. */
    ret |= morapi_DnnRecipe_init(recipe, morapi_DnnOptimizer_getPlan(optimizer));
    ret |= morapi_DnnRecipe_strip(recipe);
    ret |= morapi_DnnRecipe_save(recipe, argv[2]);

    /* tune and save dnn if needed. */
    if (4 <= argc) {
        ret |= morapi_Dnn_tune(dnn, recipe);
        ret |= morapi_Dnn_save(dnn, argv[3], NULL, 0, MORAPI_FALSE);
    }

  EXIT:

    /* destroy objects. */
    ret |= morapi_destroy_DnnRecipe(env, recipe);
    ret |= morapi_destroy_DnnOptimizer(env, optimizer);
    ret |= morapi_destroy_DnnProf(env, prof);
    ret |= morapi_destroy_Dnn(env, dnn);
    ret |= morapi_destroy_Env(env);

    return (int)ret;
}