coding_load.c 7.03 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 "PHY/CODING/coding_extern.h"
39
#include "common/utils/load_module_shlib.h" 
40
#include "common/utils/telnetsrv/telnetsrv.h" 
41

42 43 44 45 46 47 48 49 50 51 52 53 54
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 */
55 56
loader_shlibfunc_t shlib_fdesc[DECODE_NUM_FPTR];

57 58
/* encoding decoding functions pointers, filled here and used when encoding/decoding */
/*defined as extern in PHY?CODING/extern.h */
59 60 61
decoder_if_t    *decoder16;
decoder_if_t    *decoder8;
encoder_if_t    *encoder;
62 63

extern int _may_i_use_cpu_feature(unsigned __int64);
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
uint8_t  nodecod(int16_t *y,
                               int16_t *y2,
                               uint8_t *decoded_bytes,
                               uint8_t *decoded_bytes2,
                               uint16_t n,
                               uint8_t max_iterations,
                               uint8_t crc_type,
                               uint8_t 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)
79 80 81 82 83 84 85 86 87
{
 return max_iterations+1;
};

void decoding_setmode (int mode) {
   switch (mode) {
       case MODE_DECODE_NONE:
          decoder8=nodecod;
          decoder16=nodecod;
88
          encoder=(encoder_if_t*)shlib_fdesc[ENCODE_C_FPTRIDX].fptr;
89 90
       break;
       case MODE_DECODE_C:
91 92 93
          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;   
94 95
       break;
       case MODE_DECODE_AVX2:
96 97 98
          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;  
99
       break;
100 101 102
       default:
           mode=MODE_DECODE_SSE;
       case MODE_DECODE_SSE:
103 104 105
          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;
106
       break;
107
   }
108
   curmode=mode;
109 110 111 112 113 114
}


int load_codinglib(void) {
 int ret;
 
115
     memset(shlib_fdesc,0,sizeof(shlib_fdesc));
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
     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";
133
     ret=load_module_shlib("coding",shlib_fdesc,DECODE_NUM_FPTR,NULL);
134 135 136 137 138
     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();
139 140 141 142 143 144
     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();
     }
145
     decoding_setmode(MODE_DECODE_SSE);
146 147 148 149 150
/* 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); 
     }
151 152 153 154 155 156 157 158 159 160 161
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();


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

/* 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;
}