From a6dd62a50fbae5b75e294eb0f0180f99a0f295af Mon Sep 17 00:00:00 2001
From: frtabu <francois.taburet@nokia-bell-labs.com>
Date: Fri, 10 Sep 2021 17:17:31 +0200
Subject: [PATCH] Enhance loader to allow library version selection for
 executables, as ldcptest which do not use the config module.

---
 common/utils/DOC/loader/devusage/api.md       |  4 ++++
 common/utils/load_module_shlib.c              | 11 +++++----
 common/utils/load_module_shlib.h              |  5 ++--
 executables/nr-uesoftmodem.c                  |  2 +-
 openair1/PHY/CODING/TESTBENCH/ldpctest.c      |  6 +++--
 openair1/PHY/CODING/nrLDPC_extern.h           |  2 +-
 openair1/PHY/CODING/nrLDPC_load.c             | 24 ++++++++-----------
 openair1/PHY/INIT/nr_init.c                   |  2 +-
 .../PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c   |  3 +++
 9 files changed, 34 insertions(+), 25 deletions(-)

diff --git a/common/utils/DOC/loader/devusage/api.md b/common/utils/DOC/loader/devusage/api.md
index a6e59c5938..41a0807a24 100644
--- a/common/utils/DOC/loader/devusage/api.md
+++ b/common/utils/DOC/loader/devusage/api.md
@@ -10,6 +10,10 @@ int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf)
 * If the farray pointer is null,  looks for `< modname >_getfarray` symbol, calls the corresponding function when the symbol is found. `< modname >_getfarray` takes one argument, a pointer to a  `loader_shlibfunc_t` array, and returns the number of items in this array, as defined by the `getfarrayfunc_t` type. The `loader_shlibfunc_t` array returned by the shared library must be fully filled (both `fname` and `fptr` fields).
 * looks for the `numf` function symbols listed in the `farray[i].fname` arguments and set the corresponding `farray[i].fptr`function pointers
 
+```c
+int load_module_version_shlib(char *modname, char *version, loader_shlibfunc_t *farray, int numf)
+```
+Allows loading a specific library version, as specified by the `version` parameter. When version is not NULL the version that is possibly specified as a config module parameter is ignored. This call has been introduced for phy simulators executables which do not use the config module. It is used, for example,  by the ldcp initialization (`load_nrLDPClib` function in [nrLDPC_load.c](../../../../../openair1/PHY/CODING/nrLDPC_load.c)  to allow the `ldpctest` simulator to select the cuda accelerated ldcp implementation. `load_module_shlib` is just a define macro to switch to a `load_module_version_shlib` call,  adding a NULL pointer for the version parameter.
 
 ```c
 void * get_shlibmodule_fptr(char *modname, char *fname)
diff --git a/common/utils/load_module_shlib.c b/common/utils/load_module_shlib.c
index a4b4742c94..2b0d339358 100644
--- a/common/utils/load_module_shlib.c
+++ b/common/utils/load_module_shlib.c
@@ -63,7 +63,7 @@ void loader_init(void) {
 }
 
 /* build the full shared lib name from the module name */
-char *loader_format_shlibpath(char *modname)
+char *loader_format_shlibpath(char *modname, char *version)
 {
 
 char *tmpstr;
@@ -97,7 +97,10 @@ int ret;
        shlibpath =  loader_data.shlibpath ;
    } 
 /* no specific shared lib version */
-   if (shlibversion == NULL) {
+   if (version != NULL) {    // version specified as a function parameter
+	   shlibversion=version;
+   }
+   if (shlibversion == NULL) {  // no specific version specified, neither as a config param or as a function param
        shlibversion = "" ;
    } 
 /* alloc memory for full module shared lib file name */
@@ -118,7 +121,7 @@ int ret;
    return tmpstr; 
 }
 
-int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf, void *autoinit_arg)
+int load_module_version_shlib(char *modname, char *version, loader_shlibfunc_t *farray, int numf, void *autoinit_arg)
 {
   void *lib_handle = NULL;
   initfunc_t fpi;
@@ -138,7 +141,7 @@ int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf, void *
      loader_init();
   }
 
-  shlib_path = loader_format_shlibpath(modname);
+  shlib_path = loader_format_shlibpath(modname, version);
 
   for (int i = 0; i < loader_data.numshlibs; i++) {
     if (strcmp(loader_data.shlibs[i].name, modname) == 0) {
diff --git a/common/utils/load_module_shlib.h b/common/utils/load_module_shlib.h
index 685b3d1b65..0e80a5353c 100644
--- a/common/utils/load_module_shlib.h
+++ b/common/utils/load_module_shlib.h
@@ -84,10 +84,11 @@ loader_data_t loader_data;
 
 /*-------------------------------------------------------------------------------------------------------------*/
 #else  /* LOAD_MODULE_SHLIB_MAIN */
-extern int load_module_shlib(char *modname, loader_shlibfunc_t *farray, int numf, void *initfunc_arg);
+
+extern int load_module_version_shlib(char *modname, char *version, loader_shlibfunc_t *farray, int numf, void *initfunc_arg);
 extern void * get_shlibmodule_fptr(char *modname, char *fname);
 extern loader_data_t loader_data;
 #endif /* LOAD_MODULE_SHLIB_MAIN */
-
+#define load_module_shlib(M, F, N, I) load_module_version_shlib(M, NULL, F, N, I)
 #endif
 
diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c
index f9088dcc74..fca9c72f42 100644
--- a/executables/nr-uesoftmodem.c
+++ b/executables/nr-uesoftmodem.c
@@ -436,7 +436,7 @@ int main( int argc, char **argv ) {
   itti_init(TASK_MAX, tasks_info);
 
   init_opt() ;
-  load_nrLDPClib(0);
+  load_nrLDPClib(NULL);
 
   if (ouput_vcd) {
     vcd_signal_dumper_init("/tmp/openair_dump_nrUE.vcd");
diff --git a/openair1/PHY/CODING/TESTBENCH/ldpctest.c b/openair1/PHY/CODING/TESTBENCH/ldpctest.c
index af38c22cfc..17dcc1d0c9 100644
--- a/openair1/PHY/CODING/TESTBENCH/ldpctest.c
+++ b/openair1/PHY/CODING/TESTBENCH/ldpctest.c
@@ -601,8 +601,10 @@ int main(int argc, char *argv[])
   printf("n_trials %d: \n", n_trials);
   printf("SNR0 %f: \n", SNR0);
 
-
-  load_nrLDPClib(run_cuda);
+  if(run_cuda)
+    load_nrLDPClib("_cuda");
+  else
+    load_nrLDPClib(NULL); 
   load_nrLDPClib_ref("_orig", &encoder_orig);
   //for (block_length=8;block_length<=MAX_BLOCK_LENGTH;block_length+=8)
 
diff --git a/openair1/PHY/CODING/nrLDPC_extern.h b/openair1/PHY/CODING/nrLDPC_extern.h
index 5d4c6aebb9..b75b38fc76 100644
--- a/openair1/PHY/CODING/nrLDPC_extern.h
+++ b/openair1/PHY/CODING/nrLDPC_extern.h
@@ -26,7 +26,7 @@ nrLDPC_encoderfunc_t nrLDPC_encoder;
 nrLDPC_initcallfunc_t nrLDPC_initcall;
 #else
 /* functions to load the LDPC shared lib, implemented in openair1/PHY/CODING/nrLDPC_load.c */
-extern int load_nrLDPClib(int) ;
+extern int load_nrLDPClib(char *version) ;
 extern int load_nrLDPClib_ref(char *libversion, nrLDPC_encoderfunc_t * nrLDPC_encoder_ptr); // for ldpctest
 /* ldpc coder/decoder functions, as loaded by load_nrLDPClib(). */
 extern nrLDPC_initcallfunc_t nrLDPC_initcall;
diff --git a/openair1/PHY/CODING/nrLDPC_load.c b/openair1/PHY/CODING/nrLDPC_load.c
index 295368c459..23e5032bad 100644
--- a/openair1/PHY/CODING/nrLDPC_load.c
+++ b/openair1/PHY/CODING/nrLDPC_load.c
@@ -48,24 +48,22 @@ static loader_shlibfunc_t shlib_fdesc[3];
 /* arg is used to initialize the config module so that the loader works as expected */
 char *arg[64]={"ldpctest","-O","cmdlineonly::dbgl0",NULL,NULL};
 
-int load_nrLDPClib(int run_cuda) {
+int load_nrLDPClib(char *version) {
 	 char *ptr = (char*)config_get_if();
 	 char libname[64]="ldpc";
-	 int argc=3;
-	 if (run_cuda) {
-         arg[3]="--loader.ldpc.shlibversion";
-         argc++;
-         arg[4]="_cuda";
-         argc++;
-     }
+
      if ( ptr==NULL )  {// phy simulators, config module possibly not loaded
-     	 load_configmodule(argc,(char **)arg,CONFIG_ENABLECMDLINEONLY) ;
+     	 load_configmodule(0,(char **)NULL,CONFIG_ENABLECMDLINEONLY) ;
      	 logInit();
      }	 
      shlib_fdesc[0].fname = "nrLDPC_decod";
      shlib_fdesc[1].fname = "nrLDPC_encod";
      shlib_fdesc[2].fname = "nrLDPC_initcall";
-     int ret=load_module_shlib(libname,shlib_fdesc,sizeof(shlib_fdesc)/sizeof(loader_shlibfunc_t),NULL);
+     int ret;
+     if (version)
+       ret=load_module_version_shlib(libname,version,shlib_fdesc,sizeof(shlib_fdesc)/sizeof(loader_shlibfunc_t),NULL);
+     else
+       ret=load_module_shlib(libname,shlib_fdesc,sizeof(shlib_fdesc)/sizeof(loader_shlibfunc_t),NULL);
      AssertFatal( (ret >= 0),"Error loading ldpc decoder");
      nrLDPC_decoder = (nrLDPC_decoderfunc_t)shlib_fdesc[0].fptr;
      nrLDPC_encoder = (nrLDPC_encoderfunc_t)shlib_fdesc[1].fptr;
@@ -77,10 +75,8 @@ int load_nrLDPClib_ref(char *libversion, nrLDPC_encoderfunc_t * nrLDPC_encoder_p
 	loader_shlibfunc_t shlib_encoder_fdesc;
 
      shlib_encoder_fdesc.fname = "nrLDPC_encod";
-     char libpath[64];
-     sprintf(libpath,"ldpc%s",libversion);
-     int ret=load_module_shlib(libpath,&shlib_encoder_fdesc,1,NULL);
-     AssertFatal( (ret >= 0),"Error loading ldpc encoder %s\n",libpath);
+     int ret=load_module_version_shlib("ldpc",libversion,&shlib_encoder_fdesc,1,NULL);
+     AssertFatal( (ret >= 0),"Error loading ldpc encoder %s\n",(libversion==NULL)?"":libversion);
      *nrLDPC_encoder_ptr = (nrLDPC_encoderfunc_t)shlib_encoder_fdesc.fptr;
 return 0;
 }
diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c
index 8dc0fa6e11..cd4848ea8c 100644
--- a/openair1/PHY/INIT/nr_init.c
+++ b/openair1/PHY/INIT/nr_init.c
@@ -108,7 +108,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
   crcTableInit();
   init_scrambling_luts();
   init_pucch2_luts();
-  load_nrLDPClib(0);
+  load_nrLDPClib(NULL);
   // PBCH DMRS gold sequences generation
   nr_init_pbch_dmrs(gNB);
   //PDCCH DMRS init
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
index 816b025d34..975d7077a0 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
@@ -497,6 +497,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
       }
 
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_IN);
+      p_decParams->block_length=length_dec;
       nrLDPC_initcall(p_decParams, (int8_t*)&pl[0], llrProcBuf);
       no_iteration_ldpc = nrLDPC_decoder(p_decParams,
                                          (int8_t *)&pl[0],
@@ -957,6 +958,7 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
     for (i=0, j=0; j < ((kc*harq_process->Z)>>4)+1;  i+=2, j++) {
       pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
     }
+    p_decParams->block_length=length_dec;
     nrLDPC_initcall(p_decParams, (int8_t*)&pl[0], llrProcBuf);
     no_iteration_ldpc = nrLDPC_decoder(p_decParams,
                                        (int8_t *)&pl[0],
@@ -1341,6 +1343,7 @@ void nr_dlsch_decoding_process(void *arg) {
     for (i=0, j=0; j < ((kc*harq_process->Z)>>4)+1;  i+=2, j++) {
       pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
     }
+    p_decParams->block_length=length_dec;
     nrLDPC_initcall(p_decParams, (int8_t*)&pl[0], llrProcBuf);
     no_iteration_ldpc = nrLDPC_decoder(p_decParams,
                                        (int8_t *)&pl[0],
-- 
2.26.2