coding_load.c 6.68 KB
Newer Older
1 2 3 4 5
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
6
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * 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.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */

/*! \file openair1/PHY/CODING
 * \brief: load library implementing coding/decoding algorithms
 * \author Francois TABURET
 * \date 2017
 * \version 0.1
 * \company NOKIA BellLabs France
 * \email: francois.taburet@nokia-bell-labs.com
 * \note
 * \warning
 */
32
#define _GNU_SOURCE 
33
#include <sys/types.h>
34 35


36 37
#include "PHY/defs_common.h"
#include "PHY/phy_extern.h"
38
#include "common/utils/load_module_shlib.h" 
39
#include "common/utils/telnetsrv/telnetsrv.h" 
40

41 42 43 44 45 46 47 48 49 50 51 52 53
static int coding_setmod_cmd(char *buff, int debug, telnet_printfunc_t prnt);
static telnetshell_cmddef_t coding_cmdarray[] = {
   {"mode","[sse,avx2,stdc,none]",coding_setmod_cmd},
   {"","",NULL},
};
telnetshell_vardef_t coding_vardef[] = {
{"maxiter",TELNET_VARTYPE_INT32,&max_turbo_iterations},
{"",0,NULL}
};
/* PHY/defs.h contains MODE_DECODE_XXX macros, following table must match */
static char *modedesc[] = {"none","sse","C","avx2"};
static int curmode;
/* function description array, to be used when loading the encoding/decoding shared lib */
54 55
loader_shlibfunc_t shlib_fdesc[DECODE_NUM_FPTR];

56 57
/* encoding decoding functions pointers, filled here and used when encoding/decoding */
/*defined as extern in PHY?CODING/extern.h */
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
decoder_if_t    decoder16;
decoder_if_t    decoder8;
encoder_if_t    encoder;

extern int _may_i_use_cpu_feature(unsigned __int64);
uint8_t  nodecod(short *y,
    short *y2,
    unsigned char *decoded_bytes,
    unsigned char *decoded_bytes2,
    unsigned short n,
    unsigned short f1,
    unsigned short f2,
    unsigned char max_iterations,
    unsigned char crc_type,
    unsigned char F,
    time_stats_t *init_stats,
    time_stats_t *alpha_stats,
    time_stats_t *beta_stats,
    time_stats_t *gamma_stats,
    time_stats_t *ext_stats,
    time_stats_t *intl1_stats,
    time_stats_t *intl2_stats)
{
 return max_iterations+1;
};

void decoding_setmode (int mode) {
   switch (mode) {
       case MODE_DECODE_NONE:
          decoder8=nodecod;
          decoder16=nodecod;
          encoder=(encoder_if_t)shlib_fdesc[ENCODE_C_FPTRIDX].fptr;
       break;
       case MODE_DECODE_C:
          decoder16=(decoder_if_t)shlib_fdesc[DECODE_TD_C_FPTRIDX].fptr;
          decoder8=(decoder_if_t)shlib_fdesc[DECODE_TD_C_FPTRIDX].fptr;
          encoder=(encoder_if_t)shlib_fdesc[ENCODE_C_FPTRIDX].fptr;   
       break;
       case MODE_DECODE_AVX2:
          decoder16=(decoder_if_t)shlib_fdesc[DECODE_TD16_AVX2_FPTRIDX].fptr;
          decoder8=(decoder_if_t)shlib_fdesc[DECODE_TD8_SSE_FPTRIDX].fptr; 
          encoder=(encoder_if_t)shlib_fdesc[ENCODE_SSE_FPTRIDX].fptr;  
       break;
101 102 103 104 105 106 107
       default:
           mode=MODE_DECODE_SSE;
       case MODE_DECODE_SSE:
          decoder8=(decoder_if_t)shlib_fdesc[DECODE_TD8_SSE_FPTRIDX].fptr; 
          decoder16=(decoder_if_t)shlib_fdesc[DECODE_TD16_SSE_FPTRIDX].fptr;
          encoder=(encoder_if_t)shlib_fdesc[ENCODE_SSE_FPTRIDX].fptr;
       break;
108
   }
109
   curmode=mode;
110 111 112 113 114 115
}


int load_codinglib(void) {
 int ret;
 
116
     memset(shlib_fdesc,0,sizeof(shlib_fdesc));
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
     shlib_fdesc[DECODE_INITTD8_SSE_FPTRIDX].fname = "init_td8";
     shlib_fdesc[DECODE_INITTD16_SSE_FPTRIDX].fname= "init_td16";
     shlib_fdesc[DECODE_INITTD_AVX2_FPTRIDX].fname="init_td16avx2";

     shlib_fdesc[DECODE_TD8_SSE_FPTRIDX].fname=   "phy_threegpplte_turbo_decoder8";
     shlib_fdesc[DECODE_TD16_SSE_FPTRIDX].fname=  "phy_threegpplte_turbo_decoder16";
     shlib_fdesc[DECODE_TD_C_FPTRIDX].fname=      "phy_threegpplte_turbo_decoder_scalar";
     shlib_fdesc[DECODE_TD16_AVX2_FPTRIDX].fname= "phy_threegpplte_turbo_decoder16avx2";


     shlib_fdesc[DECODE_FREETD8_FPTRIDX].fname =    "free_td8";
     shlib_fdesc[DECODE_FREETD16_FPTRIDX].fname=    "free_td16";
     shlib_fdesc[DECODE_FREETD_AVX2_FPTRIDX].fname= "free_td16avx2";    

     shlib_fdesc[ENCODE_SSE_FPTRIDX].fname=    "threegpplte_turbo_encoder_sse";
     shlib_fdesc[ENCODE_C_FPTRIDX].fname=      "threegpplte_turbo_encoder";
     shlib_fdesc[ENCODE_INIT_SSE_FPTRIDX].fname=       "init_encoder_sse";
     ret=load_module_shlib("coding",shlib_fdesc,DECODE_NUM_FPTR);
     if (ret < 0) exit_fun("Error loading coding library");

/* execute encoder/decoder init functions */     
     shlib_fdesc[DECODE_INITTD8_SSE_FPTRIDX].fptr();
     shlib_fdesc[DECODE_INITTD16_SSE_FPTRIDX].fptr();
140 141 142 143 144 145
     if(shlib_fdesc[DECODE_INITTD_AVX2_FPTRIDX].fptr != NULL) {
        shlib_fdesc[DECODE_INITTD_AVX2_FPTRIDX].fptr();
     }
     if(shlib_fdesc[ENCODE_INIT_SSE_FPTRIDX].fptr != NULL) {
        shlib_fdesc[ENCODE_INIT_SSE_FPTRIDX].fptr();
     }
146
     decoding_setmode(MODE_DECODE_SSE);
147 148 149 150 151
/* look for telnet server, if it is loaded, add the coding commands to it */
     add_telnetcmd_func_t addcmd = (add_telnetcmd_func_t)get_shlibmodule_fptr("telnetsrv", TELNET_ADDCMD_FNAME);
     if (addcmd != NULL) {
         addcmd("coding",coding_vardef,coding_cmdarray); 
     }
152 153 154 155 156 157 158 159 160 161 162
return 0;
}

void free_codinglib(void) {

     shlib_fdesc[DECODE_FREETD8_FPTRIDX].fptr();
     shlib_fdesc[DECODE_FREETD16_FPTRIDX].fptr();
     shlib_fdesc[DECODE_FREETD_AVX2_FPTRIDX].fptr();


}
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183

/* functions for telnet support, when telnet server is loaded */
int coding_setmod_cmd(char *buff, int debug, telnet_printfunc_t prnt)
{
   if (debug > 0)
       prnt( "coding_setmod_cmd received %s\n",buff);

      if (strcasestr(buff,"sse") != NULL) {
         decoding_setmode(MODE_DECODE_SSE);
      } else if (strcasestr(buff,"avx2") != NULL) {
         decoding_setmode(MODE_DECODE_AVX2);
      } else if (strcasestr(buff,"stdc") != NULL) {
         decoding_setmode(MODE_DECODE_C);
      } else if (strcasestr(buff,"none") != NULL) {
         decoding_setmode(MODE_DECODE_NONE);
      } else {
          prnt("%s: wrong setmod parameter...\n",buff);
      }
   prnt("Coding and decoding current mode: %s\n",modedesc[curmode]);
   return 0;
}