Commit 96aacd58 authored by Robert Schmidt's avatar Robert Schmidt

Merge remote-tracking branch 'origin/remove-thread-pool-abort' into integration_2023_w24

parents d4eeffff 15b8dbc4
......@@ -1015,6 +1015,10 @@ endif()
add_library(ldpc MODULE ${PHY_LDPC_OPTIM8SEGMULTI_SRC} )
target_link_libraries(ldpc PRIVATE ldpc_gen_HEADERS)
add_library(ldpc_parityCheck MODULE ${PHY_LDPC_OPTIM8SEGMULTI_SRC} )
target_compile_definitions(ldpc_parityCheck PUBLIC NR_LDPC_ENABLE_PARITY_CHECK)
target_link_libraries(ldpc_parityCheck PRIVATE ldpc_gen_HEADERS)
add_library(coding MODULE ${PHY_TURBOSRC} )
add_library(dfts MODULE ${OPENAIR1_DIR}/PHY/TOOLS/oai_dfts.c )
......@@ -2408,7 +2412,7 @@ add_executable(ldpctest
${SHLIB_LOADER_SOURCES}
)
add_dependencies( ldpctest ldpc_orig ldpc_optim ldpc_optim8seg ldpc )
add_dependencies( ldpctest ldpc_orig ldpc_optim ldpc_optim8seg ldpc ldpc_parityCheck)
if (ENABLE_LDPC_CUDA)
add_dependencies(ldpctest ldpc_cuda)
endif()
......
......@@ -63,60 +63,55 @@ void loader_init(void) {
}
/* build the full shared lib name from the module name */
char *loader_format_shlibpath(char *modname, char *version)
static char *loader_format_shlibpath(char *modname, char *version)
{
char *tmpstr;
char *shlibpath =NULL;
char *shlibversion=NULL;
// clang-format off
paramdef_t LoaderParams[] = {
char *tmpstr;
char *shlibpath = NULL;
char *shlibversion = NULL;
// clang-format off
paramdef_t LoaderParams[] = {
{"shlibpath", NULL, 0, .strptr = &shlibpath, .defstrval = NULL, TYPE_STRING, 0, NULL},
{"shlibversion", NULL, 0, .strptr = &shlibversion, .defstrval = "", TYPE_STRING, 0, NULL}
};
// clang-format on
int ret;
};
// clang-format on
int ret;
/* looks for specific path for this module in the config file */
/* specific value for a module path and version is located in a modname subsection of the loader section */
/* shared lib name is formatted as lib<module name><module version>.so */
/* looks for specific path for this module in the config file */
/* specific value for a module path and version is located in a modname subsection of the loader section */
/* shared lib name is formatted as lib<module name><module version>.so */
char cfgprefix[sizeof(LOADER_CONFIG_PREFIX)+strlen(modname)+16];
sprintf(cfgprefix,LOADER_CONFIG_PREFIX ".%s",modname);
ret = config_get( LoaderParams,sizeof(LoaderParams)/sizeof(paramdef_t),cfgprefix);
ret = config_get(LoaderParams, sizeofArray(LoaderParams), cfgprefix);
if (ret <0) {
fprintf(stderr,"[LOADER] %s %d couldn't retrieve config from section %s\n",__FILE__, __LINE__,cfgprefix);
}
/* no specific path, use loader default shared lib path */
if (shlibpath == NULL) {
shlibpath = loader_data.shlibpath ;
}
/* no specific shared lib version */
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 */
tmpstr = malloc(strlen(shlibpath)+strlen(modname)+strlen(shlibversion)+16);
if (tmpstr == NULL) {
fprintf(stderr,"[LOADER] %s %d malloc error loading module %s, %s\n",__FILE__, __LINE__, modname, strerror(errno));
exit_fun("[LOADER] unrecoverable error");
}
if(shlibpath[0] != 0) {
ret=sprintf(tmpstr,"%s/",shlibpath);
} else {
ret = 0;
}
fprintf(stderr, "[LOADER] %s %d couldn't retrieve config from section %s\n", __FILE__, __LINE__, cfgprefix);
}
/* no specific path, use loader default shared lib path */
if (shlibpath == NULL) {
shlibpath = loader_data.shlibpath;
}
/* no specific shared lib version */
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 */
tmpstr = malloc(strlen(shlibpath) + strlen(modname) + strlen(shlibversion) + 16);
if (tmpstr == NULL) {
fprintf(stderr, "[LOADER] %s %d malloc error loading module %s, %s\n", __FILE__, __LINE__, modname, strerror(errno));
exit_fun("[LOADER] unrecoverable error");
}
if (shlibpath[0] != 0) {
ret = sprintf(tmpstr, "%s/", shlibpath);
} else {
ret = 0;
}
sprintf(tmpstr + ret, "lib%s%s.so", modname, shlibversion);
sprintf(tmpstr+ret,"lib%s%s.so",modname,shlibversion);
return tmpstr;
return tmpstr;
}
int load_module_version_shlib(char *modname, char *version, loader_shlibfunc_t *farray, int numf, void *autoinit_arg)
......
......@@ -218,14 +218,8 @@ int main() {
tmp=pullNotifiedFIFO(&myFifo);
printf("pulled: %lu\n", tmp->key);
displayList(&myFifo);
abortNotifiedFIFOJob(&myFifo,1005);
printf("aborted 1005\n");
displayList(&myFifo);
pushNotifiedFIFO(&myFifo,newNotifiedFIFO_elt(sizeof(struct testData), 12345678, NULL, NULL));
displayList(&myFifo);
abortNotifiedFIFOJob(&myFifo,12345678);
printf("aborted 12345678\n");
displayList(&myFifo);
do {
tmp=pollNotifiedFIFO(&myFifo);
......
......@@ -197,31 +197,6 @@ static inline time_stats_t exec_time_stats_NotifiedFIFO(const notifiedFIFO_elt_t
return ts;
}
// This function aborts all messages matching the key
// If the queue is used in thread pools, it doesn't cancels already running processing
// because the message has already been picked
static inline int abortNotifiedFIFOJob(notifiedFIFO_t *nf, uint64_t key) {
mutexlock(nf->lockF);
int nbDeleted=0;
notifiedFIFO_elt_t **start=&nf->outF;
while(*start!=NULL) {
if ( (*start)->key == key ) {
notifiedFIFO_elt_t *request=*start;
*start=(*start)->next;
delNotifiedFIFO_elt(request);
nbDeleted++;
} else
start=&(*start)->next;
}
if (nf->outF == NULL)
nf->inF=NULL;
mutexunlock(nf->lockF);
return nbDeleted;
}
// This functions aborts all messages in the queue, and marks the queue as
// "aborted", such that every call to it will return NULL
static inline void abortNotifiedFIFO(notifiedFIFO_t *nf) {
......@@ -317,39 +292,6 @@ static inline notifiedFIFO_elt_t *tryPullTpool(notifiedFIFO_t *responseFifo, tpo
return msg;
}
static inline int abortTpoolJob(tpool_t *t, uint64_t key) {
int nbRemoved=0;
notifiedFIFO_t *nf=&t->incomingFifo;
mutexlock(nf->lockF);
notifiedFIFO_elt_t **start=&nf->outF;
while(*start!=NULL) {
if ( (*start)->key == key ) {
notifiedFIFO_elt_t *request=*start;
*start=(*start)->next;
delNotifiedFIFO_elt(request);
nbRemoved++;
} else
start=&(*start)->next;
}
if (t->incomingFifo.outF==NULL)
t->incomingFifo.inF=NULL;
struct one_thread *thread = t->allthreads;
while (thread != NULL) {
if (thread->runningOnKey == key) {
thread->dropJob = true;
nbRemoved++;
}
thread = thread->next;
}
mutexunlock(nf->lockF);
return nbRemoved;
}
static inline int abortTpool(tpool_t *t) {
int nbRemoved=0;
/* disables threading: if a message comes in now, we cannot have a race below
......
......@@ -2,8 +2,6 @@
The **thread pool** is a working server, made of a set of worker threads that can be mapped on CPU cores. Each thread pool has an **input queue** ("**FIFO**"), from which its workers pick **jobs** (FIFO element) to execute. When a job is done, the worker sends a message to an output queue, if it has been defined.
A selective abort allows to cancel parallel jobs. This can be useful, e.g., if a client pushed jobs, but from a response of one job, the other linked jobs become useless.
All the thread pool functions are thread safe. The functions executed by worker threads are provided by the thread pool client, so the client has to handle the concurrency/parallel execution of his functions.
## license
......@@ -56,7 +54,6 @@ Queues can be used to enqueue messages/jobs, of type `notifiedFIFO_t`.
* `pushNotifiedFIFO()`: Add a job to a queue
* `pullNotifiedFIFO()`: Pull a job from a queue. This call is blocking until a job arrived.
* `pollNotifiedFIFO()`: Pull a job from a queue. This call is not blocking, so it returns always very shortly
* `abortNotifiedFIFOJob()`: Allows to delete all waiting jobs that match a key (see `key` in jobs definition)
* `abortNotifiedFIFO()`: Aborts a FIFO, such that it will always return `NULL`
Note that in 99.9% of cases, `pull()` is better than `poll()`.
......@@ -104,12 +101,6 @@ Like `pullNotifiedFIFO()`, but non-blocking: they check if the queue `nf` contai
Note that unlike for `pullNotifiedFIFO()`, returning `NULL` does not inform whether the queue has been aborted; the caller should manually check the `abortFIFO` flag of `nf` in this case.
### `int abortNotifiedFIFOJob(notifiedFIFO_t *nf, uint64_t key)`
Aborts all jobs in FIFO queue `nf` with key `key`. Jobs already under execution will be silently dropped and not put in the FIFO return queue, if any.
Returns the number of aborted jobs.
### `void abortNotifiedFIFO(notifiedFIFO_t *nf)`
Aborts the entire FIFO queue `nf`: all jobs will be dropped, and the FIFO is marked as aborted, such that a call to `pullNotifiedFIFO()` returns `NULL`.
......@@ -135,10 +126,6 @@ If they need a return value (e.g., result of a computation), they have to create
## Abort
A abort service `abortTpoolJob()` allows to abort all jobs that match a key (see a job's `key`). When the abort returns, it garanties that no job (matching the key) response will be posted on response queues.
Nevertheless, jobs already performed before the return of `abortTpoolJob()` are pushed in the response Fifo queue.
`abortTpool()` kills all jobs in the Tpool, and terminates the pool.
## API details
......@@ -171,7 +158,7 @@ Adds a job for processing in the thread pool.
The job data you can set are, inside `msg`:
* `key`: an arbitrary key to find a job in a response queue, and which can be used to abort jobs using `abortTpoolJob()`.
* `key`: an arbitrary key to find a job in a response queue.
* `reponseFifo`: if non-`NULL`, the message will be sent back on this queue when the job is done. If `NULL`, the thread pool automatically frees the job when it is done.
* `processingFunc`: the function to execute for this job.
......@@ -187,14 +174,6 @@ Multiple return queues might be useful. Consider the following example in the eN
The same as `pullTpool()` in a non-blocking fashion (an alternative name would have been `pollTpool()`).
### `int abortTpoolJob(tpool_t *t, uint64_t key)`
Is a facility to cancel work you pushed to a thread pool: every job with a given `key` will be deleted, and results of jobs with such `key` under execution will be dropped.
It returns the number of aborted jobs, including the ones that are currently being executed.
I used it once: when eNB performs turbo decode, I push all segments in the thread pool. But when I get back the decoding results, if one segment can't be decoded, I don't need the results of the other segments of the same UE.
### `int abortTpool(tpool_t *t)`
Aborts the complete Tpool: cancel every work in the input queue, marks to drop existing jobs in processing, and terminates all worker threads. It is afterwards still possible to call functions such as `pushTpool()`, but each calling thread will execute the job itself.
......
......@@ -67,10 +67,7 @@ COPY --from=gnb-build \
/oai-ran/cmake_targets/ran_build/build/libcoding.so \
/oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \
/oai-ran/cmake_targets/ran_build/build/libdfts.so \
/oai-ran/cmake_targets/ran_build/build/libldpc.so \
/oai-ran/cmake_targets/ran_build/build/libldpc_optim.so \
/oai-ran/cmake_targets/ran_build/build/libldpc_optim8seg.so \
/oai-ran/cmake_targets/ran_build/build/libldpc_orig.so \
/oai-ran/cmake_targets/ran_build/build/libldpc*.so \
/oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \
/usr/local/lib/
......
......@@ -68,10 +68,7 @@ COPY --from=gnb-build \
/oai-ran/cmake_targets/ran_build/build/libcoding.so \
/oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \
/oai-ran/cmake_targets/ran_build/build/libdfts.so \
/oai-ran/cmake_targets/ran_build/build/libldpc.so \
/oai-ran/cmake_targets/ran_build/build/libldpc_optim.so \
/oai-ran/cmake_targets/ran_build/build/libldpc_optim8seg.so \
/oai-ran/cmake_targets/ran_build/build/libldpc_orig.so \
/oai-ran/cmake_targets/ran_build/build/libldpc*.so \
/oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \
/usr/local/lib/libori.so \
/usr/local/lib/
......@@ -86,19 +83,7 @@ COPY --from=gnb-base \
RUN ln -s /usr/local/lib/libaw2sori_transpro.so /usr/local/lib/libthirdparty_transpro.so && \
ln -s /usr/local/lib/liboai_eth_transpro.so /usr/local/lib/liboai_transpro.so && \
ldconfig && \
echo "ldd on nr-softmodem" && ldd /opt/oai-gnb-aw2s/bin/nr-softmodem && \
echo "ldd on liboai_eth_transpro" && ldd /usr/local/lib/liboai_eth_transpro.so && \
echo "ldd on librfsimulator" && ldd /usr/local/lib/librfsimulator.so && \
echo "ldd on libaw2sori_transpro" && ldd /usr/local/lib/libaw2sori_transpro.so && \
echo "ldd on libcoding" && ldd /usr/local/lib/libcoding.so && \
echo "ldd on libparams_libconfig" && ldd /usr/local/lib/libparams_libconfig.so && \
echo "ldd on libdfts" && ldd /usr/local/lib/libdfts.so && \
echo "ldd on libldpc" && ldd /usr/local/lib/libldpc.so && \
echo "ldd on libldpc_optim" && ldd /usr/local/lib/libldpc_optim.so && \
echo "ldd on libldpc_optim8seg" && ldd /usr/local/lib/libldpc_optim8seg.so && \
echo "ldd on libldpc_orig" && ldd /usr/local/lib/libldpc_orig.so && \
echo "ldd on libtelnetsrv" && ldd /usr/local/lib/libtelnetsrv.so
ldconfig
WORKDIR /opt/oai-gnb-aw2s
ENTRYPOINT ["/opt/oai-gnb-aw2s/bin/entrypoint.sh"]
......
......@@ -70,10 +70,7 @@ COPY --from=gnb-build \
/oai-ran/cmake_targets/ran_build/build/libcoding.so \
/oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \
/oai-ran/cmake_targets/ran_build/build/libdfts.so \
/oai-ran/cmake_targets/ran_build/build/libldpc.so \
/oai-ran/cmake_targets/ran_build/build/libldpc_optim.so \
/oai-ran/cmake_targets/ran_build/build/libldpc_optim8seg.so \
/oai-ran/cmake_targets/ran_build/build/libldpc_orig.so \
/oai-ran/cmake_targets/ran_build/build/libldpc*.so \
/oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \
/usr/local/lib/
......
......@@ -64,10 +64,7 @@ COPY --from=gnb-build \
/oai-ran/cmake_targets/ran_build/build/libcoding.so \
/oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \
/oai-ran/cmake_targets/ran_build/build/libdfts.so \
/oai-ran/cmake_targets/ran_build/build/libldpc.so \
/oai-ran/cmake_targets/ran_build/build/libldpc_optim.so \
/oai-ran/cmake_targets/ran_build/build/libldpc_optim8seg.so \
/oai-ran/cmake_targets/ran_build/build/libldpc_orig.so \
/oai-ran/cmake_targets/ran_build/build/libldpc*.so \
/oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \
/oai-ran/cmake_targets/ran_build/build/libtelnetsrv_ci.so \
/usr/local/lib/
......
......@@ -68,10 +68,7 @@ COPY --from=gnb-build \
/oai-ran/cmake_targets/ran_build/build/libcoding.so \
/oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \
/oai-ran/cmake_targets/ran_build/build/libdfts.so \
/oai-ran/cmake_targets/ran_build/build/libldpc.so \
/oai-ran/cmake_targets/ran_build/build/libldpc_optim.so \
/oai-ran/cmake_targets/ran_build/build/libldpc_optim8seg.so \
/oai-ran/cmake_targets/ran_build/build/libldpc_orig.so \
/oai-ran/cmake_targets/ran_build/build/libldpc*.so \
/oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \
/oai-ran/cmake_targets/ran_build/build/libtelnetsrv_ci.so \
/usr/local/lib/
......@@ -107,21 +104,8 @@ WORKDIR /usr/local/share/uhd/rfnoc
COPY --from=gnb-base /usr/local/share/uhd/rfnoc/ .
RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai_device.so" && \
ldconfig && \
echo "ldd on nr-softmodem" && ldd /opt/oai-gnb/bin/nr-softmodem && \
echo "ldd on liboai_eth_transpro" && ldd /usr/local/lib/liboai_eth_transpro.so && \
echo "ldd on librfsimulator" && ldd /usr/local/lib/librfsimulator.so && \
echo "ldd on liboai_usrpdevif" && ldd /usr/local/lib/liboai_usrpdevif.so && \
echo "ldd on libcoding" && ldd /usr/local/lib/libcoding.so && \
echo "ldd on libparams_libconfig" && ldd /usr/local/lib/libparams_libconfig.so && \
echo "ldd on libdfts" && ldd /usr/local/lib/libdfts.so && \
echo "ldd on libldpc" && ldd /usr/local/lib/libldpc.so && \
echo "ldd on libldpc_optim" && ldd /usr/local/lib/libldpc_optim.so && \
echo "ldd on libldpc_optim8seg" && ldd /usr/local/lib/libldpc_optim8seg.so && \
echo "ldd on libldpc_orig" && ldd /usr/local/lib/libldpc_orig.so && \
echo "ldd on libtelnetsrv" && ldd /usr/local/lib/libtelnetsrv.so && \
echo "ldd on libtelnetsrv_ci" && ldd /usr/local/lib/libtelnetsrv_ci.so
ldconfig
# Copy the relevant configuration files for gNB
WORKDIR /opt/oai-gnb/etc
COPY --from=gnb-build /oai-ran/docker/etc .
......
......@@ -70,10 +70,7 @@ COPY --from=gnb-build \
/oai-ran/cmake_targets/ran_build/build/libcoding.so \
/oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \
/oai-ran/cmake_targets/ran_build/build/libdfts.so \
/oai-ran/cmake_targets/ran_build/build/libldpc.so \
/oai-ran/cmake_targets/ran_build/build/libldpc_optim.so \
/oai-ran/cmake_targets/ran_build/build/libldpc_optim8seg.so \
/oai-ran/cmake_targets/ran_build/build/libldpc_orig.so \
/oai-ran/cmake_targets/ran_build/build/libldpc*.so \
/oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \
/oai-ran/cmake_targets/ran_build/build/libtelnetsrv_ci.so \
/usr/local/lib/
......
......@@ -70,10 +70,7 @@ COPY --from=nr-ue-build \
/oai-ran/cmake_targets/ran_build/build/libcoding.so \
/oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \
/oai-ran/cmake_targets/ran_build/build/libdfts.so \
/oai-ran/cmake_targets/ran_build/build/libldpc.so \
/oai-ran/cmake_targets/ran_build/build/libldpc_optim.so \
/oai-ran/cmake_targets/ran_build/build/libldpc_optim8seg.so \
/oai-ran/cmake_targets/ran_build/build/libldpc_orig.so \
/oai-ran/cmake_targets/ran_build/build/libldpc*.so \
/oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \
/oai-ran/cmake_targets/ran_build/build/libtelnetsrv_5Gue.so \
/usr/local/lib/
......
......@@ -75,10 +75,7 @@ COPY --from=nr-ue-build \
/oai-ran/cmake_targets/ran_build/build/libcoding.so \
/oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \
/oai-ran/cmake_targets/ran_build/build/libdfts.so \
/oai-ran/cmake_targets/ran_build/build/libldpc.so \
/oai-ran/cmake_targets/ran_build/build/libldpc_optim.so \
/oai-ran/cmake_targets/ran_build/build/libldpc_optim8seg.so \
/oai-ran/cmake_targets/ran_build/build/libldpc_orig.so \
/oai-ran/cmake_targets/ran_build/build/libldpc*.so \
/oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \
/oai-ran/cmake_targets/ran_build/build/libtelnetsrv_5Gue.so \
/usr/local/lib/
......@@ -114,21 +111,8 @@ WORKDIR /usr/local/share/uhd/rfnoc
COPY --from=nr-ue-base /usr/local/share/uhd/rfnoc/ .
RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai_device.so" && \
ldconfig && \
echo "ldd on nr-uesoftmodem" && ldd /opt/oai-nr-ue/bin/nr-uesoftmodem && \
echo "ldd on liboai_eth_transpro" && ldd /usr/local/lib/liboai_eth_transpro.so && \
echo "ldd on librfsimulator" && ldd /usr/local/lib/librfsimulator.so && \
echo "ldd on liboai_usrpdevif" && ldd /usr/local/lib/liboai_usrpdevif.so && \
echo "ldd on libcoding" && ldd /usr/local/lib/libcoding.so && \
echo "ldd on libparams_libconfig" && ldd /usr/local/lib/libparams_libconfig.so && \
echo "ldd on libdfts" && ldd /usr/local/lib/libdfts.so && \
echo "ldd on libldpc" && ldd /usr/local/lib/libldpc.so && \
echo "ldd on libldpc_optim" && ldd /usr/local/lib/libldpc_optim.so && \
echo "ldd on libldpc_optim8seg" && ldd /usr/local/lib/libldpc_optim8seg.so && \
echo "ldd on libldpc_orig" && ldd /usr/local/lib/libldpc_orig.so && \
echo "ldd on libtelnetsrv" && ldd /usr/local/lib/libtelnetsrv.so && \
echo "ldd on libtelnetsrv_5Gue" && ldd /usr/local/lib/libtelnetsrv_5Gue.so
ldconfig
# Copy the relevant configuration files for eNB
WORKDIR /opt/oai-nr-ue/etc
COPY --from=nr-ue-build /oai-ran/ci-scripts/conf_files/ue.* .
......
......@@ -76,10 +76,7 @@ COPY --from=nr-ue-build \
/oai-ran/cmake_targets/ran_build/build/libcoding.so \
/oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \
/oai-ran/cmake_targets/ran_build/build/libdfts.so \
/oai-ran/cmake_targets/ran_build/build/libldpc.so \
/oai-ran/cmake_targets/ran_build/build/libldpc_optim.so \
/oai-ran/cmake_targets/ran_build/build/libldpc_optim8seg.so \
/oai-ran/cmake_targets/ran_build/build/libldpc_orig.so \
/oai-ran/cmake_targets/ran_build/build/libldpc*.so \
/oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \
/oai-ran/cmake_targets/ran_build/build/libtelnetsrv_5Gue.so \
/usr/local/lib/
......
......@@ -89,8 +89,7 @@ COPY --from=phy-sim-build \
/usr/lib64/libasan.so.6 \
/usr/lib64/libubsan.so.1 \
/oai-ran/cmake_targets/ran_build/build/libdfts.so \
/oai-ran/cmake_targets/ran_build/build/libldpc.so \
/oai-ran/cmake_targets/ran_build/build/libldpc_orig.so \
/oai-ran/cmake_targets/ran_build/build/libldpc*.so \
/usr/local/lib/
RUN ldconfig
......
......@@ -982,7 +982,9 @@ uint8_t phy_threegpplte_turbo_decoder16(int16_t *y,
time_stats_t *gamma_stats,
time_stats_t *ext_stats,
time_stats_t *intl1_stats,
time_stats_t *intl2_stats) {
time_stats_t *intl2_stats,
decode_abort_t *ab)
{
/* y is a pointer to the input
decoded_bytes is a pointer to the decoded output
n is the size in bits of the coded block, with the tail */
......@@ -1356,7 +1358,8 @@ uint8_t phy_threegpplte_turbo_decoder16(int16_t *y,
return(iteration_cnt);
}
}
if (check_abort(ab))
return max_iterations + 2;
// do log_map from first parity bit
if (iteration_cnt < max_iterations) {
log_map16(systematic1,yparity1,m11,m10,alpha,beta,ext,n,0,F,offset8_flag,alpha_stats,beta_stats,gamma_stats,ext_stats);
......@@ -1390,9 +1393,7 @@ uint8_t phy_threegpplte_turbo_decoder16(int16_t *y,
_mm_empty();
_m_empty();
#endif
if (iteration_cnt > max_iterations)
set_abort(ab, true);
return(iteration_cnt);
}
......@@ -792,7 +792,9 @@ uint8_t phy_threegpplte_turbo_decoder8(int16_t *y,
time_stats_t *gamma_stats,
time_stats_t *ext_stats,
time_stats_t *intl1_stats,
time_stats_t *intl2_stats) {
time_stats_t *intl2_stats,
decode_abort_t *ab)
{
/* y is a pointer to the input
decoded_bytes is a pointer to the decoded output
n is the size in bits of the coded block, with the tail */
......@@ -1278,7 +1280,8 @@ uint8_t phy_threegpplte_turbo_decoder8(int16_t *y,
return(iteration_cnt);
}
}
if (check_abort(ab))
return max_iterations + 2;
// do a new iteration if it is not yet decoded
if (iteration_cnt < max_iterations) {
log_map8(systematic1,yparity1,m11,m10,alpha,beta,ext,n2,0,F,offset8_flag,alpha_stats,beta_stats,gamma_stats,ext_stats);
......@@ -1303,6 +1306,7 @@ uint8_t phy_threegpplte_turbo_decoder8(int16_t *y,
}
}
}
if (iteration_cnt > max_iterations)
set_abort(ab, true);
return(iteration_cnt);
}
......@@ -185,7 +185,6 @@ int test_ldpc(short max_iterations,
}
}
//determine number of bits in codeword
if (block_length>3840)
{
......@@ -270,6 +269,8 @@ int test_ldpc(short max_iterations,
if (ntrials==0)
encoder_orig(test_input,channel_input, Zc, BG, block_length, BG, &impp);
impp.gen_code=0;
decode_abort_t dec_abort;
init_abort(&dec_abort);
for (int trial=0; trial < ntrials; trial++)
{
segment_bler = 0;
......@@ -359,7 +360,12 @@ int test_ldpc(short max_iterations,
}
for(int j=0;j<n_segments;j++) {
start_meas(time_decoder);
n_iter = nrLDPC_decoder(&decParams[j], (int8_t*)channel_output_fixed[j], (int8_t*)estimated_output[j], &decoder_profiler);
set_abort(&dec_abort, false);
n_iter = nrLDPC_decoder(&decParams[j],
(int8_t *)channel_output_fixed[j],
(int8_t *)estimated_output[j],
&decoder_profiler,
&dec_abort);
stop_meas(time_decoder);
//count errors
if ( memcmp(estimated_output[j], test_input[j], block_length/8 ) != 0 ) {
......@@ -429,7 +435,9 @@ int main(int argc, char *argv[])
unsigned int errors, errors_bit, crc_misses;
double errors_bit_uncoded;
short block_length=8448; // decoder supports length: 1201 -> 1280, 2401 -> 2560
char *ldpc_version=NULL; /* version of the ldpc decoder library to use (XXX suffix to use when loading libldpc_XXX.so */
// default to check output inside ldpc, the NR version checks the outer CRC defined by 3GPP
char *ldpc_version = "_parityCheck";
/* version of the ldpc decoder library to use (XXX suffix to use when loading libldpc_XXX.so */
short max_iterations=5;
int n_segments=1;
//double rate=0.333;
......@@ -529,11 +537,7 @@ int main(int argc, char *argv[])
printf("n_trials %d: \n", n_trials);
printf("SNR0 %f: \n", SNR0);
if (ldpc_version != NULL)
load_nrLDPClib(ldpc_version);
else
load_nrLDPClib(NULL);
load_nrLDPClib(ldpc_version);
load_nrLDPClib_ref("_orig", &encoder_orig);
//for (block_length=8;block_length<=MAX_BLOCK_LENGTH;block_length+=8)
......
......@@ -399,8 +399,8 @@ unsigned int crc8 (unsigned char * inptr, int bitlen);
@param bitlen length of inputs in bits*/
unsigned int crc6 (unsigned char * inptr, int bitlen);
int check_crc(uint8_t* decoded_bytes, uint32_t n, uint32_t F, uint8_t crc_type);
int check_crc(uint8_t *decoded_bytes, uint32_t n, uint8_t crc_type);
/*!\fn void phy_viterbi_dot11_sse2(int8_t *y, uint8_t *decoded_bytes, uint16_t n,int offset,int traceback)
\brief This routine performs a SIMD optmized Viterbi decoder for the 802.11 64-state convolutional code. It can be
run in segments with final trace back after last segment.
......
......@@ -58,21 +58,22 @@ decoder_if_t *decoder8;
encoder_if_t *encoder;
extern int _may_i_use_cpu_feature(unsigned __int64);
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)
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,
decode_abort_t *ab)
{
return max_iterations+1;
};
......
......@@ -313,7 +313,7 @@ uint32_t crc6(unsigned char* inptr, int bitlen)
return crc;
}
int check_crc(uint8_t* decoded_bytes, uint32_t n, uint32_t F, uint8_t crc_type)
int check_crc(uint8_t* decoded_bytes, uint32_t n, uint8_t crc_type)
{
uint32_t crc=0,oldcrc=0;
uint8_t crc_len=0;
......
......@@ -2728,41 +2728,25 @@ static inline void nrLDPC_bnProc(t_nrLDPC_lut* p_lut, int8_t* bnProcBuf, int8_t*
*/
static inline void nrLDPC_llr2bit(int8_t* out, int8_t* llrOut, uint16_t numLLR)
{
__m256i* p_llrOut = (__m256i*) llrOut;
__m256i* p_out = (__m256i*) out;
int8_t* p_llrOut8;
int8_t* p_out8;
uint32_t i;
uint32_t M = numLLR>>5;
uint32_t Mr = numLLR&31;
__m256i* p_llrOut = (__m256i*)llrOut;
__m256i* p_out = (__m256i*)out;
const int M = numLLR >> 5;
const int Mr = numLLR & 31;
const __m256i* p_zeros = (__m256i*) zeros256_epi8;
const __m256i* p_ones = (__m256i*) ones256_epi8;
const __m256i* p_zeros = (__m256i*)zeros256_epi8;
const __m256i* p_ones = (__m256i*)ones256_epi8;
for (i=0; i<M; i++)
{
*p_out++ = simde_mm256_and_si256(*p_ones, simde_mm256_cmpgt_epi8(*p_zeros, *p_llrOut));
p_llrOut++;
}
for (int i = 0; i < M; i++) {
*p_out++ = simde_mm256_and_si256(*p_ones, simde_mm256_cmpgt_epi8(*p_zeros, *p_llrOut));
p_llrOut++;
}
if (Mr > 0)
{
// Remaining LLRs that do not fit in multiples of 32 bytes
p_llrOut8 = (int8_t*) p_llrOut;
p_out8 = (int8_t*) p_out;
// Remaining LLRs that do not fit in multiples of 32 bytes
int8_t* p_llrOut8 = (int8_t*)p_llrOut;
int8_t* p_out8 = (int8_t*)p_out;
for (i=0; i<Mr; i++)
{
if (p_llrOut8[i] < 0)
{
p_out8[i] = 1;
}
else
{
p_out8[i] = 0;
}
}
}
for (int i = 0; i < Mr; i++)
p_out8[i] = p_llrOut8[i] < 0;
}
/**
......@@ -2778,44 +2762,29 @@ static inline void nrLDPC_llr2bitPacked(int8_t* out, int8_t* llrOut, uint16_t nu
{
/** Vector of indices for shuffling input */
const uint8_t constShuffle_256_epi8[32] __attribute__ ((aligned(32))) = {7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8};
const __m256i* p_shuffle = (__m256i*)constShuffle_256_epi8;
__m256i* p_llrOut = (__m256i*) llrOut;
uint32_t* p_bits = (uint32_t*) out;
__m256i inPerm;
int8_t* p_llrOut8;
uint32_t bitsTmp = 0;
uint32_t i;
uint32_t M = numLLR>>5;
uint32_t Mr = numLLR&31;
const __m256i* p_shuffle = (__m256i*) constShuffle_256_epi8;
for (i=0; i<M; i++)
{
// Move LSB to MSB on 8 bits
inPerm = simde_mm256_shuffle_epi8(*p_llrOut,*p_shuffle);
// Hard decision
*p_bits++ = simde_mm256_movemask_epi8(inPerm);
p_llrOut++;
const uint32_t M = numLLR >> 5;
const uint32_t Mr = numLLR & 31;
for (uint32_t i = 0; i < M; i++) {
// Move LSB to MSB on 8 bits
const __m256i inPerm = simde_mm256_shuffle_epi8(*p_llrOut, *p_shuffle);
// Hard decision
*p_bits++ = simde_mm256_movemask_epi8(inPerm);
p_llrOut++;
}
if (Mr > 0)
{
// Remaining LLRs that do not fit in multiples of 32 bytes
p_llrOut8 = (int8_t*) p_llrOut;
for (i=0; i<Mr; i++)
{
if (p_llrOut8[i] < 0)
{
bitsTmp |= (1<<((7-i) + (16*(i/8))));
}
else
{
bitsTmp |= (0<<((7-i) + (16*(i/8))));
}
}
// Remaining LLRs that do not fit in multiples of 32 bytes
if (Mr) {
const int8_t* p_llrOut8 = (int8_t*)p_llrOut;
uint32_t bitsTmp = 0;
for (uint32_t i = 0; i < Mr; i++)
bitsTmp |= (p_llrOut8[i] < 0) << ((7 - i) + (16 * (i / 8)));
*p_bits = bitsTmp;
}
*p_bits = bitsTmp;
}
#endif
......@@ -334,8 +334,12 @@ void nrLDPC_initcall(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_
// init_LLR_DMA(p_decParams, p_llr, p_out);
}
int32_t nrLDPC_decod(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out,t_nrLDPC_procBuf* p_procBuf, t_nrLDPC_time_stats *time_decoder)
int32_t nrLDPC_decod(t_nrLDPC_dec_params *p_decParams,
int8_t *p_llr,
int8_t *p_out,
t_nrLDPC_procBuf *p_procBuf,
t_nrLDPC_time_stats *time_decoder,
decode_abort_t *ab)
{
uint16_t Zc = p_decParams->Z;
uint8_t BG = p_decParams->BG;
......
/*
* 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
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* 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 nrLDPC_init_mem.h
* \brief Defines the function to initialize the LDPC decoder and sets correct LUTs.
* \author Sebastian Wagner (TCL Communications) Email: <mailto:sebastian.wagner@tcl.com>
* \date 07-12-2018
* \version 1.0
* \note
* \warning
*/
#ifndef __NR_LDPC_INIT_MEM__H__
#define __NR_LDPC_INIT_MEM__H__
#include <stdlib.h>
#include "nrLDPC_types.h"
/**
\brief Allocates 32 byte aligned memory and initializes to zero
\param size Input size in bytes
\return Pointer to memory
*/
static inline void* malloc32_clear(size_t size)
{
void* ptr = (void*) memalign(64, size+64);
memset(ptr, 0, size);
return ptr;
}
/**
\brief Allocates and initializes the internal decoder processing buffers
\param p_decParams Pointer to decoder parameters
\param p_lut Pointer to decoder LUTs
\return Number of LLR values
*/
static inline t_nrLDPC_procBuf* nrLDPC_init_mem(void)
{
t_nrLDPC_procBuf* p_procBuf = (t_nrLDPC_procBuf*) malloc32_clear(sizeof(t_nrLDPC_procBuf));
if (p_procBuf)
{
p_procBuf->cnProcBuf = (int8_t*) malloc32_clear(NR_LDPC_SIZE_CN_PROC_BUF*sizeof(int8_t));
p_procBuf->cnProcBufRes = (int8_t*) malloc32_clear(NR_LDPC_SIZE_CN_PROC_BUF*sizeof(int8_t));
p_procBuf->bnProcBuf = (int8_t*) malloc32_clear(NR_LDPC_SIZE_BN_PROC_BUF*sizeof(int8_t));
p_procBuf->bnProcBufRes = (int8_t*) malloc32_clear(NR_LDPC_SIZE_BN_PROC_BUF*sizeof(int8_t));
p_procBuf->llrRes = (int8_t*) malloc32_clear(NR_LDPC_MAX_NUM_LLR *sizeof(int8_t));
p_procBuf->llrProcBuf = (int8_t*) malloc32_clear(NR_LDPC_MAX_NUM_LLR *sizeof(int8_t));
}
return(p_procBuf);
}
static inline void nrLDPC_free_mem(t_nrLDPC_procBuf* p_procBuf)
{
free(p_procBuf->cnProcBuf);
free(p_procBuf->cnProcBufRes);
free(p_procBuf->bnProcBuf);
free(p_procBuf->bnProcBufRes);
free(p_procBuf->llrRes);
free(p_procBuf->llrProcBuf);
free(p_procBuf);
}
#endif
......@@ -88,6 +88,7 @@ typedef struct nrLDPC_dec_params {
uint8_t numMaxIter; /**< Maximum number of iterations */
int block_length;
e_nrLDPC_outMode outMode; /**< Output format */
int crc_type;
} t_nrLDPC_dec_params;
/**
......
......@@ -73,7 +73,7 @@ typedef int(*nrLDPC_encoderfunc_t)(unsigned char **,unsigned char **,int,int,sho
\param p_profiler LDPC profiler statistics
*/
typedef int32_t(*nrLDPC_decoderfunc_t)(t_nrLDPC_dec_params* , int8_t*, int8_t* , t_nrLDPC_time_stats* );
typedef int32_t (*nrLDPC_decoderfunc_t)(t_nrLDPC_dec_params *, int8_t *, int8_t *, t_nrLDPC_time_stats *, decode_abort_t *ab);
typedef int32_t(*nrLDPC_decoffloadfunc_t)(t_nrLDPC_dec_params* , uint8_t, uint8_t, uint8_t , uint8_t, uint16_t, uint32_t, uint8_t, int8_t*, int8_t* ,uint8_t);
typedef int32_t(*nrLDPC_dectopfunc_t)(void);
......
......@@ -28,10 +28,10 @@ nrLDPC_decoffloadfunc_t nrLDPC_decoder_offload;
nrLDPC_dectopfunc_t top_testsuite;
#else
/* functions to load the LDPC shared lib, implemented in openair1/PHY/CODING/nrLDPC_load.c */
extern int load_nrLDPClib(char *version) ;
extern int load_nrLDPClib_offload(void) ;
extern int free_nrLDPClib_offload(void) ;
extern int load_nrLDPClib_ref(char *libversion, nrLDPC_encoderfunc_t * nrLDPC_encoder_ptr); // for ldpctest
int load_nrLDPClib(char *version);
int load_nrLDPClib_offload(void);
int free_nrLDPClib_offload(void);
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;
......
......@@ -49,26 +49,23 @@ static loader_shlibfunc_t shlib_fdesc[3];
char *arg[64]={"ldpctest",NULL};
int load_nrLDPClib(char *version) {
char *ptr = (char*)config_get_if();
char libname[64]="ldpc";
if ( ptr==NULL ) {// phy simulators, config module possibly not loaded
load_configmodule(1,arg,CONFIG_ENABLECMDLINEONLY) ;
logInit();
}
shlib_fdesc[0].fname = "nrLDPC_decod";
shlib_fdesc[1].fname = "nrLDPC_encod";
shlib_fdesc[2].fname = "nrLDPC_initcall";
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;
nrLDPC_initcall = (nrLDPC_initcallfunc_t)shlib_fdesc[2].fptr;
return 0;
char *ptr = (char *)config_get_if();
char libname[64] = "ldpc";
if (ptr == NULL) { // phy simulators, config module possibly not loaded
load_configmodule(1, arg, CONFIG_ENABLECMDLINEONLY);
logInit();
}
shlib_fdesc[0].fname = "nrLDPC_decod";
shlib_fdesc[1].fname = "nrLDPC_encod";
shlib_fdesc[2].fname = "nrLDPC_initcall";
int ret;
ret = load_module_version_shlib(libname, version, shlib_fdesc, sizeofArray(shlib_fdesc), 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;
nrLDPC_initcall = (nrLDPC_initcallfunc_t)shlib_fdesc[2].fptr;
return 0;
}
int load_nrLDPClib_offload(void) {
......
......@@ -551,7 +551,8 @@ int nr_rate_matching_ldpc_rx(uint32_t Tbslbrm,
printf("nr_rate_matching_ldpc_rx: Clear %d, E %u, k0 %u, Ncb %u, rvidx %d, Tbslbrm %u\n", clear, E, ind, Ncb, rvidx, Tbslbrm);
#endif
if (clear==1) memset(w,0,Ncb*sizeof(int16_t));
if (clear == 1)
memset(w, 0, Ncb * sizeof(int16_t));
k=0;
......
......@@ -573,18 +573,10 @@ void nr_init_dl_harq_processes(NR_DL_UE_HARQ_t harq_list[2][NR_MAX_DLSCH_HARQ_PR
harq_list[j][i].c = malloc16(a_segments*sizeof(uint8_t *));
harq_list[j][i].d = malloc16(a_segments*sizeof(int16_t *));
const int sz=5*8448*sizeof(int16_t);
init_abort(&harq_list[j][i].abort_decode);
for (int r=0; r<a_segments; r++) {
harq_list[j][i].c[r] = malloc16(1056);
harq_list[j][i].d[r] = malloc16(sz);
if (harq_list[j][i].c[r])
memset(harq_list[j][i].c[r],0,1056);
else
AssertFatal(true, "Unable to reset harq memory \"c\"\n");
if (harq_list[j][i].d[r])
memset(harq_list[j][i].d[r], 0, sz);
else
AssertFatal(true, "Unable to reset harq memory \"d\"\n");
harq_list[j][i].c[r] = malloc16_clear(1056);
harq_list[j][i].d[r] = malloc16_clear(sz);
}
harq_list[j][i].status = 0;
harq_list[j][i].DLround = 0;
......
......@@ -327,6 +327,7 @@ typedef struct {
uint32_t repetition_number ;
// PUSCH Total number of repetitions
uint32_t total_number_of_repetitions;
decode_abort_t abort_decode;
} LTE_UL_eNB_HARQ_t;
typedef struct {
......
......@@ -538,20 +538,6 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *phy_vars_eNB,
uint8_t Nbundled,
uint8_t llr8_flag);
/*!
\brief Decoding of ULSCH data component from 36-212. This one is single thread.
@param phy_vars_eNB Pointer to eNB top-level descriptor
@param UE_id ID of UE transmitting this PUSCH
@param harq_pid HARQ process ID
@param llr8_flag If 1, indicate that the 8-bit turbo decoder should be used
@returns 0 on success
*/
int ulsch_decoding_data(PHY_VARS_eNB *eNB,
L1_rxtx_proc_t *proc,
int UE_id,
int harq_pid,
int llr8_flag);
void generate_phich_top(PHY_VARS_eNB *phy_vars_eNB,
L1_rxtx_proc_t *proc,
int16_t amp);
......
......@@ -113,6 +113,7 @@ LTE_eNB_ULSCH_t *new_eNB_ulsch(uint8_t max_turbo_iterations,uint8_t N_RB_UL, uin
if (ulsch->harq_processes[i]) {
memset(ulsch->harq_processes[i],0,sizeof(LTE_UL_eNB_HARQ_t));
init_abort(&ulsch->harq_processes[i]->abort_decode);
ulsch->harq_processes[i]->decodedBytes = (uint8_t *)malloc16(MAX_ULSCH_PAYLOAD_BYTES/bw_scaling);
if (ulsch->harq_processes[i]->decodedBytes)
......@@ -281,11 +282,21 @@ void processULSegment(void * arg) {
&eNB->ulsch_tc_gamma_stats,
&eNB->ulsch_tc_ext_stats,
&eNB->ulsch_tc_intl1_stats,
&eNB->ulsch_tc_intl2_stats);
&eNB->ulsch_tc_intl2_stats,
&ulsch_harq->abort_decode);
}
int ulsch_decoding_data(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc,
int UE_id,int harq_pid,int llr8_flag) {
/*!
\brief Decoding of ULSCH data component from 36-212. This one is single thread.
@param phy_vars_eNB Pointer to eNB top-level descriptor
@param UE_id ID of UE transmitting this PUSCH
@param harq_pid HARQ process ID
@param llr8_flag If 1, indicate that the 8-bit turbo decoder should be used
@returns 0 on success
*/
static int ulsch_decoding_data(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, int UE_id, int harq_pid, int llr8_flag)
{
unsigned int r_offset=0;
int offset = 0;
LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id];
......@@ -297,7 +308,7 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc,
decoder_if_t * td=llr8_flag == 0 ?
*decoder16 : *decoder8;
ulsch_harq->processedSegments=0;
set_abort(&ulsch_harq->abort_decode, false);
for (int r=0; r<ulsch_harq->C; r++) {
// printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]);
// Get Turbo interleaver parameters
......
......@@ -106,9 +106,10 @@ LTE_UE_DLSCH_t *new_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_
for (i=0; i<Mdlharq; i++) {
// printf("new_ue_dlsch: Harq process %d\n",i);
dlsch->harq_processes[i] = (LTE_DL_UE_HARQ_t *)malloc16(sizeof(LTE_DL_UE_HARQ_t));
if (dlsch->harq_processes[i]) {
memset(dlsch->harq_processes[i],0,sizeof(LTE_DL_UE_HARQ_t));
init_abort(&dlsch->harq_processes[i]->abort_decode);
dlsch->harq_processes[i]->first_tx=1;
dlsch->harq_processes[i]->b = (uint8_t *)malloc16(MAX_DLSCH_PAYLOAD_BYTES/bw_scaling);
......@@ -277,7 +278,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
printf("Segmentation: C %d, Cminus %d, Kminus %d, Kplus %d\n",harq_process->C,harq_process->Cminus,harq_process->Kminus,harq_process->Kplus);
#endif
opp_enabled=1;
set_abort(&harq_process->abort_decode, false);
for (r=0; r<harq_process->C; r++) {
// Get Turbo interleaver parameters
if (r<harq_process->Cminus)
......@@ -381,7 +382,8 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
&phy_vars_ue->dlsch_tc_gamma_stats,
&phy_vars_ue->dlsch_tc_ext_stats,
&phy_vars_ue->dlsch_tc_intl1_stats,
&phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1);
&phy_vars_ue->dlsch_tc_intl2_stats,
&harq_process->abort_decode); //(is_crnti==0)?harq_pid:harq_pid+1);
stop_UE_TIMING(phy_vars_ue->dlsch_turbo_decoding_stats);
}
......
......@@ -269,6 +269,7 @@ typedef struct {
uint32_t errors[8];
/// codeword this transport block is mapped to
uint8_t codeword;
decode_abort_t abort_decode;
} LTE_DL_UE_HARQ_t;
......
......@@ -49,16 +49,15 @@ NR_gNB_ULSCH_t new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL);
@param is_crnti
*/
uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
uint8_t UE_id,
short *ulsch_llr,
NR_DL_FRAME_PARMS *frame_parms,
nfapi_nr_pusch_pdu_t *pusch_pdu,
uint32_t frame,
uint8_t nr_tti_rx,
uint8_t harq_pid,
uint32_t G);
int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
uint8_t UE_id,
short *ulsch_llr,
NR_DL_FRAME_PARMS *frame_parms,
nfapi_nr_pusch_pdu_t *pusch_pdu,
uint32_t frame,
uint8_t nr_tti_rx,
uint8_t harq_pid,
uint32_t G);
/*! \brief Perform PUSCH unscrambling. TS 38.211 V15.4.0 subclause 6.3.1.1
@param llr, Pointer to llr bits
......@@ -70,17 +69,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
void nr_ulsch_unscrambling(int16_t* llr, uint32_t size, uint32_t Nid, uint32_t n_RNTI);
void nr_ulsch_layer_demapping(int16_t *llr_cw,
uint8_t Nl,
uint8_t mod_order,
uint32_t length,
int16_t **llr_layers);
void nr_ulsch_procedures(PHY_VARS_gNB *gNB,
int frame_rx,
int slot_rx,
int UE_id,
uint8_t harq_pid);
void nr_ulsch_layer_demapping(int16_t *llr_cw, uint8_t Nl, uint8_t mod_order, uint32_t length, int16_t **llr_layers);
NR_gNB_ULSCH_t *find_nr_ulsch(PHY_VARS_gNB *gNB, uint16_t rnti, int pid);
......
......@@ -143,6 +143,7 @@ typedef struct {
/// Last index of LLR buffer that contains information.
/// Used for computing LDPC decoder R
int llrLen;
decode_abort_t abort_decode;
} NR_DL_UE_HARQ_t;
typedef struct {
......
......@@ -960,7 +960,36 @@ extern int sync_var;
#define MBSFN_FDD_SF6 0x10
#define MBSFN_FDD_SF7 0x08
#define MBSFN_FDD_SF8 0x04
typedef struct {
pthread_mutex_t mutex_failure;
bool failed;
} decode_abort_t;
static inline void init_abort(decode_abort_t *ab)
{
int ret = pthread_mutex_init(&ab->mutex_failure, NULL);
AssertFatal(ret == 0, "mutex failed with %d\n", ret);
ab->failed = false;
}
static inline bool check_abort(decode_abort_t *ab)
{
int ret = pthread_mutex_lock(&ab->mutex_failure);
AssertFatal(ret == 0, "mutex failed with %d\n", ret);
bool failed = ab->failed;
ret = pthread_mutex_unlock(&ab->mutex_failure);
AssertFatal(ret == 0, "mutex failed with %d\n", ret);
return failed;
}
static inline void set_abort(decode_abort_t *ab, bool v)
{
int ret = pthread_mutex_lock(&ab->mutex_failure);
AssertFatal(ret == 0, "mutex failed with %d\n", ret);
ab->failed = v;
ret = pthread_mutex_unlock(&ab->mutex_failure);
AssertFatal(ret == 0, "mutex failed with %d\n", ret);
}
typedef uint8_t(decoder_if_t)(int16_t *y,
int16_t *y2,
......@@ -976,7 +1005,8 @@ typedef uint8_t(decoder_if_t)(int16_t *y,
time_stats_t *gamma_stats,
time_stats_t *ext_stats,
time_stats_t *intl1_stats,
time_stats_t *intl2_stats);
time_stats_t *intl2_stats,
decode_abort_t *abort_decode);
typedef uint8_t(encoder_if_t)(uint8_t *input,
uint16_t input_length_bytes,
......
......@@ -221,6 +221,7 @@ typedef struct {
uint32_t E;
/// Number of segments processed so far
uint32_t processedSegments;
decode_abort_t abort_decode;
/// Last index of LLR buffer that contains information.
/// Used for computing LDPC decoder R
int llrLen;
......@@ -774,7 +775,6 @@ typedef struct PHY_VARS_gNB_s {
pthread_t L1_tx_thread;
int L1_tx_thread_core;
struct processingData_L1tx *msgDataTx;
int nbDecode;
void *scopeData;
/// structure for analyzing high-level RT measurements
rt_L1_profiling_t rt_L1_profiling;
......
......@@ -1228,7 +1228,8 @@ uci_procedures(PHY_VARS_eNB *eNB,
} // end loop for (int i = 0; i < NUMBER_OF_UCI_MAX; i++) {
}
void postDecode(L1_rxtx_proc_t *proc, notifiedFIFO_elt_t *req) {
void postDecode(L1_rxtx_proc_t *proc, notifiedFIFO_elt_t *req)
{
turboDecode_t * rdata=(turboDecode_t *) NotifiedFifoData(req);
LTE_eNB_ULSCH_t *ulsch = rdata->eNB->ulsch[rdata->UEid];
......@@ -1244,19 +1245,7 @@ void postDecode(L1_rxtx_proc_t *proc, notifiedFIFO_elt_t *req) {
if (decodeSucess) {
int Fbytes=(rdata->segment_r==0) ? rdata->Fbits>>3 : 0;
int sz=(rdata->Kr>>3) - Fbytes - ((ulsch_harq->C>1)?3:0);
memcpy(ulsch_harq->decodedBytes+rdata->offset,
rdata->decoded_bytes+Fbytes,
sz);
} else {
if ( rdata->nbSegments != ulsch_harq->processedSegments ) {
int nb=abortTpoolJob(proc->threadPool, req->key);
nb+=abortNotifiedFIFOJob(proc->respDecode, req->key);
proc->nbDecode-=nb;
LOG_D(PHY,"uplink segment error %d/%d, aborted %d segments\n",rdata->segment_r,rdata->nbSegments, nb);
AssertFatal(ulsch_harq->processedSegments+nb == rdata->nbSegments,"processed: %d, aborted: %d, total %d\n",
ulsch_harq->processedSegments, nb, rdata->nbSegments);
ulsch_harq->processedSegments=rdata->nbSegments;
}
memcpy(ulsch_harq->decodedBytes + rdata->offset, rdata->decoded_bytes + Fbytes, sz);
}
// if this UE segments are all done
......@@ -1276,8 +1265,8 @@ void postDecode(L1_rxtx_proc_t *proc, notifiedFIFO_elt_t *req) {
}
}
}
if (!decodeSucess) {
if (check_abort(&ulsch_harq->abort_decode)) {
T(T_ENB_PHY_ULSCH_UE_NACK, T_INT(eNB->Mod_id), T_INT(rdata->frame), T_INT(rdata->subframe), T_INT(ulsch->rnti),
T_INT(rdata->harq_pid));
fill_crc_indication(eNB,i,rdata->frame,rdata->subframe,1); // indicate NAK to MAC
......@@ -1302,28 +1291,28 @@ void postDecode(L1_rxtx_proc_t *proc, notifiedFIFO_elt_t *req) {
* locally in PHY.
*/
ulsch_harq->handled = 1;
} // ulsch in error
else if(ulsch_harq->repetition_number == ulsch_harq->total_number_of_repetitions){
fill_crc_indication(eNB,i,rdata->frame,rdata->subframe,0); // indicate ACK to MAC
fill_rx_indication(eNB,i,rdata->frame,rdata->subframe); // indicate SDU to MAC
ulsch_harq->status = SCH_IDLE;
ulsch->harq_mask &= ~(1 << rdata->harq_pid);
for (int j=0;j<NUMBER_OF_ULSCH_MAX;j++)
if (eNB->ulsch_stats[j].rnti == ulsch->rnti) {
eNB->ulsch_stats[j].total_bytes_rx+=ulsch_harq->TBS;
for (int aa=0;aa<eNB->frame_parms.nb_antennas_rx;aa++) {
eNB->ulsch_stats[j].ulsch_power[aa] = dB_fixed_x10(eNB->pusch_vars[rdata->UEid]->ulsch_power[aa]);
eNB->ulsch_stats[j].ulsch_noise_power[aa] = dB_fixed_x10(eNB->pusch_vars[rdata->UEid]->ulsch_noise_power[aa]);
}
break;
}
} // ulsch in error
else if (ulsch_harq->repetition_number == ulsch_harq->total_number_of_repetitions) {
fill_crc_indication(eNB, i, rdata->frame, rdata->subframe, 0); // indicate ACK to MAC
fill_rx_indication(eNB, i, rdata->frame, rdata->subframe); // indicate SDU to MAC
ulsch_harq->status = SCH_IDLE;
ulsch->harq_mask &= ~(1 << rdata->harq_pid);
for (int j = 0; j < NUMBER_OF_ULSCH_MAX; j++)
if (eNB->ulsch_stats[j].rnti == ulsch->rnti) {
eNB->ulsch_stats[j].total_bytes_rx += ulsch_harq->TBS;
for (int aa = 0; aa < eNB->frame_parms.nb_antennas_rx; aa++) {
eNB->ulsch_stats[j].ulsch_power[aa] = dB_fixed_x10(eNB->pusch_vars[rdata->UEid]->ulsch_power[aa]);
eNB->ulsch_stats[j].ulsch_noise_power[aa] = dB_fixed_x10(eNB->pusch_vars[rdata->UEid]->ulsch_noise_power[aa]);
}
break;
}
T (T_ENB_PHY_ULSCH_UE_ACK, T_INT(eNB->Mod_id), T_INT(rdata->frame), T_INT(rdata->subframe), T_INT(ulsch->rnti),
T_INT(rdata->harq_pid));
} // ulsch not in error
} // ulsch not in error
if (ulsch_harq->O_ACK>0)
fill_ulsch_harq_indication(eNB,ulsch_harq,ulsch->rnti,rdata->frame,rdata->subframe,ulsch->bundling);
}
}
}
void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
......
......@@ -232,7 +232,7 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX+offset,0);
}
void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req)
static void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req)
{
ldpcDecode_t *rdata = (ldpcDecode_t*) NotifiedFifoData(req);
NR_UL_gNB_HARQ_t *ulsch_harq = rdata->ulsch_harq;
......@@ -241,32 +241,22 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req)
nfapi_nr_pusch_pdu_t *pusch_pdu = &gNB->ulsch[rdata->ulsch_id].harq_process->ulsch_pdu;
bool decodeSuccess = (rdata->decodeIterations <= rdata->decoderParms.numMaxIter);
ulsch_harq->processedSegments++;
LOG_D(PHY, "processing result of segment: %d, processed %d/%d\n",
rdata->segment_r, ulsch_harq->processedSegments, rdata->nbSegments);
gNB->nbDecode--;
LOG_D(PHY,"remain to decoded in subframe: %d\n", gNB->nbDecode);
LOG_D(PHY,
"processing result of segment: %d, processed %d/%d\n",
rdata->segment_r,
ulsch_harq->processedSegments,
rdata->nbSegments);
if (decodeSuccess) {
memcpy(ulsch_harq->b+rdata->offset,
ulsch_harq->c[r],
rdata->Kr_bytes - (ulsch_harq->F>>3) -((ulsch_harq->C>1)?3:0));
memcpy(ulsch_harq->b + rdata->offset, ulsch_harq->c[r], rdata->Kr_bytes - (ulsch_harq->F >> 3) - ((ulsch_harq->C > 1) ? 3 : 0));
} else {
if ( rdata->nbSegments != ulsch_harq->processedSegments ) {
int nb = abortTpoolJob(&gNB->threadPool, req->key);
nb += abortNotifiedFIFOJob(&gNB->respDecode, req->key);
gNB->nbDecode-=nb;
LOG_D(PHY,"uplink segment error %d/%d, aborted %d segments\n",rdata->segment_r,rdata->nbSegments, nb);
LOG_D(PHY, "ULSCH %d in error\n",rdata->ulsch_id);
AssertFatal(ulsch_harq->processedSegments+nb == rdata->nbSegments,"processed: %d, aborted: %d, total %d\n",
ulsch_harq->processedSegments, nb, rdata->nbSegments);
ulsch_harq->processedSegments=rdata->nbSegments;
}
LOG_D(PHY, "ULSCH %d in error\n", rdata->ulsch_id);
}
//int dumpsig=0;
// if all segments are done
if (rdata->nbSegments == ulsch_harq->processedSegments) {
if (decodeSuccess && !gNB->pusch_vars[rdata->ulsch_id].DTX) {
if (!check_abort(&ulsch_harq->abort_decode) && !gNB->pusch_vars[rdata->ulsch_id].DTX) {
LOG_D(PHY,
"[gNB %d] ULSCH: Setting ACK for SFN/SF %d.%d (rnti %x, pid %d, ndi %d, status %d, round %d, TBS %d, Max interation "
"(all seg) %d)\n",
......@@ -306,6 +296,7 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req)
nr_fill_indication(gNB, ulsch->frame, ulsch->slot, rdata->ulsch_id, rdata->harq_pid, 1, 0);
// dumpsig=1;
}
ulsch->last_iteration_cnt = rdata->decodeIterations;
/*
if (ulsch_harq->ulsch_pdu.mcs_index == 0 && dumpsig==1) {
int off = ((ulsch_harq->ulsch_pdu.rb_size&1) == 1)? 4:0;
......@@ -348,13 +339,12 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req)
}
}
void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH_id, uint8_t harq_pid)
static int nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH_id, uint8_t harq_pid)
{
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
nfapi_nr_pusch_pdu_t *pusch_pdu = &gNB->ulsch[ULSCH_id].harq_process->ulsch_pdu;
uint16_t nb_re_dmrs;
uint8_t enable_ldpc_offload = gNB->ldpc_offload_flag;
uint16_t start_symbol = pusch_pdu->start_symbol_index;
uint16_t number_symbols = pusch_pdu->nr_of_symbols;
......@@ -407,17 +397,10 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH
//----------------------------------------------------------
start_meas(&gNB->ulsch_decoding_stats);
nr_ulsch_decoding(gNB, ULSCH_id, gNB->pusch_vars[ULSCH_id].llr, frame_parms, pusch_pdu, frame_rx, slot_rx, harq_pid, G);
if (enable_ldpc_offload == 0) {
while (gNB->nbDecode > 0) {
notifiedFIFO_elt_t *req = pullTpool(&gNB->respDecode, &gNB->threadPool);
if (req == NULL)
break; // Tpool has been stopped
nr_postDecode(gNB, req);
delNotifiedFIFO_elt(req);
}
}
int nbDecode =
nr_ulsch_decoding(gNB, ULSCH_id, gNB->pusch_vars[ULSCH_id].llr, frame_parms, pusch_pdu, frame_rx, slot_rx, harq_pid, G);
stop_meas(&gNB->ulsch_decoding_stats);
return nbDecode;
}
......@@ -848,6 +831,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
}
}
int totalDecode = 0;
for (int ULSCH_id = 0; ULSCH_id < gNB->max_nb_pusch; ULSCH_id++) {
NR_gNB_ULSCH_t *ulsch = &gNB->ulsch[ULSCH_id];
NR_UL_gNB_HARQ_t *ulsch_harq = ulsch->harq_process;
......@@ -944,11 +928,20 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
// LOG_M("rxdataF_comp.m","rxF_comp",gNB->pusch_vars[0]->rxdataF_comp[0],6900,1,1);
// LOG_M("rxdataF_ext.m","rxF_ext",gNB->pusch_vars[0]->rxdataF_ext[0],6900,1,1);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_ULSCH_PROCEDURES_RX, 1);
nr_ulsch_procedures(gNB, frame_rx, slot_rx, ULSCH_id, ulsch->harq_pid);
totalDecode += nr_ulsch_procedures(gNB, frame_rx, slot_rx, ULSCH_id, ulsch->harq_pid);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_ULSCH_PROCEDURES_RX, 0);
}
}
if (totalDecode > 0 && gNB->ldpc_offload_flag == 0) {
while (totalDecode > 0) {
notifiedFIFO_elt_t *req = pullTpool(&gNB->respDecode, &gNB->threadPool);
if (req == NULL)
break; // Tpool has been stopped
nr_postDecode(gNB, req);
delNotifiedFIFO_elt(req);
totalDecode--;
}
}
for (int i = 0; i < gNB->max_nb_srs; i++) {
NR_gNB_SRS_t *srs = &gNB->srs[i];
if (srs) {
......
......@@ -127,11 +127,16 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
NR_DL_UE_HARQ_t *dl_harq0 = NULL;
if ((pdu_type != FAPI_NR_RX_PDU_TYPE_SSB) && dlsch0) {
int t=WS_C_RNTI;
if (pdu_type == FAPI_NR_RX_PDU_TYPE_RAR)
t=WS_RA_RNTI;
if (pdu_type == FAPI_NR_RX_PDU_TYPE_SIB)
t=WS_SI_RNTI;
dl_harq0 = &ue->dl_harq_processes[0][dlsch0->dlsch_config.harq_process_nbr];
trace_NRpdu(DIRECTION_DOWNLINK,
b,
dlsch0->dlsch_config.TBS / 8,
WS_C_RNTI,
t,
dlsch0->rnti,
proc->frame_rx,
proc->nr_slot_rx,
......@@ -419,10 +424,8 @@ static int nr_ue_pbch_procedures(PHY_VARS_NR_UE *ue,
*/
}
return ret;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_OUT);
return ret;
}
......
......@@ -2995,6 +2995,8 @@ void ue_pmch_procedures(PHY_VARS_UE *ue,
void copy_harq_proc_struct(LTE_DL_UE_HARQ_t *harq_processes_dest,
LTE_DL_UE_HARQ_t *current_harq_processes) {
init_abort(&harq_processes_dest->abort_decode);
set_abort(&harq_processes_dest->abort_decode, check_abort(&current_harq_processes->abort_decode));
harq_processes_dest->B = current_harq_processes->B ;
harq_processes_dest->C = current_harq_processes->C ;
harq_processes_dest->Cminus = current_harq_processes->Cminus ;
......
......@@ -91,42 +91,24 @@ void deref_sched_response(int _)
exit(1);
}
int nr_postDecode_sim(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) {
int nr_postDecode_sim(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req, int *nb_ok)
{
ldpcDecode_t *rdata = (ldpcDecode_t*) NotifiedFifoData(req);
NR_UL_gNB_HARQ_t *ulsch_harq = rdata->ulsch_harq;
NR_gNB_ULSCH_t *ulsch = rdata->ulsch;
int r = rdata->segment_r;
bool decodeSuccess = (rdata->decodeIterations <= rdata->decoderParms.numMaxIter);
ulsch_harq->processedSegments++;
gNB->nbDecode--;
if (decodeSuccess) {
memcpy(ulsch_harq->b+rdata->offset,
ulsch_harq->c[r],
rdata->Kr_bytes - (ulsch_harq->F>>3) -((ulsch_harq->C>1)?3:0));
} else {
if ( rdata->nbSegments != ulsch_harq->processedSegments ) {
int nb=abortTpoolJob(&gNB->threadPool, req->key);
nb+=abortNotifiedFIFOJob(&gNB->respDecode, req->key);
gNB->nbDecode-=nb;
AssertFatal(ulsch_harq->processedSegments+nb == rdata->nbSegments,"processed: %d, aborted: %d, total %d\n",
ulsch_harq->processedSegments, nb, rdata->nbSegments);
ulsch_harq->processedSegments=rdata->nbSegments;
return 1;
}
}
// if all segments are done
if (rdata->nbSegments == ulsch_harq->processedSegments) {
if (decodeSuccess) {
return 0;
} else {
return 1;
}
}
ulsch->last_iteration_cnt = rdata->decodeIterations;
// if all segments are done
if (rdata->nbSegments == ulsch_harq->processedSegments)
return *nb_ok == rdata->nbSegments;
return 0;
}
......@@ -612,13 +594,15 @@ int main(int argc, char **argv)
rel15_ul->qam_mod_order,
rel15_ul->nrOfLayers);
nr_ulsch_decoding(gNB, UE_id, channel_output_fixed, frame_parms, rel15_ul,
frame, subframe, harq_pid, G);
while (gNB->nbDecode > 0) {
notifiedFIFO_elt_t *req=pullTpool(&gNB->respDecode, &gNB->threadPool);
ret = nr_postDecode_sim(gNB, req);
delNotifiedFIFO_elt(req);
}
int nbDecode = nr_ulsch_decoding(gNB, UE_id, channel_output_fixed, frame_parms, rel15_ul, frame, subframe, harq_pid, G);
int nb_ok = 0;
if (nbDecode > 0)
while (nbDecode > 0) {
notifiedFIFO_elt_t *req = pullTpool(&gNB->respDecode, &gNB->threadPool);
ret = nr_postDecode_sim(gNB, req, &nb_ok);
delNotifiedFIFO_elt(req);
nbDecode--;
}
if (ret)
n_errors++;
......
......@@ -680,7 +680,7 @@ int main(int argc, char **argv)
c16_t **rxdata;
rxdata = malloc(n_rx * sizeof(*rxdata));
for (int i = 0; i < n_rx; ++i)
rxdata[i] = malloc(gNB->frame_parms.samples_per_frame * sizeof(**rxdata));
rxdata[i] = calloc(gNB->frame_parms.samples_per_frame, sizeof(**rxdata));
NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[0];
......@@ -705,8 +705,7 @@ int main(int argc, char **argv)
}
// Configure UE
UE = malloc(sizeof(PHY_VARS_NR_UE));
memset((void*)UE,0,sizeof(PHY_VARS_NR_UE));
UE = calloc(1, sizeof(PHY_VARS_NR_UE));
PHY_vars_UE_g = malloc(sizeof(PHY_VARS_NR_UE**));
PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_NR_UE*));
PHY_vars_UE_g[0][0] = UE;
......@@ -756,21 +755,11 @@ int main(int argc, char **argv)
nr_phy_data_tx_t phy_data = {0};
unsigned char *estimated_output_bit;
unsigned char *test_input_bit;
uint32_t errors_decoding = 0;
test_input_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
nr_scheduled_response_t scheduled_response;
fapi_nr_ul_config_request_t ul_config;
fapi_nr_tx_request_t tx_req;
memset(&scheduled_response, 0, sizeof(scheduled_response));
memset(&ul_config, 0, sizeof(ul_config));
memset(&tx_req, 0, sizeof(tx_req));
nr_scheduled_response_t scheduled_response={0};
fapi_nr_ul_config_request_t ul_config={0};
fapi_nr_tx_request_t tx_req={0};
uint8_t ptrs_mcs1 = 2;
uint8_t ptrs_mcs2 = 4;
......@@ -851,7 +840,7 @@ int main(int argc, char **argv)
ulsch_input_buffer[0] = 0x31;
for (i = 1; i < TBS/8; i++) {
ulsch_input_buffer[i] = (unsigned char) rand();
ulsch_input_buffer[i] = (unsigned char) uniformrandom();
}
uint8_t ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, Imcs, mcs_table);
......@@ -1053,7 +1042,7 @@ int main(int argc, char **argv)
pusch_pdu->maintenance_parms_v3.tbSizeLbrmBytes = tbslbrm;
pusch_pdu->pusch_data.rv_index = rv_index;
pusch_pdu->pusch_data.harq_process_id = 0;
pusch_pdu->pusch_data.new_data_indicator = round == 0 ? 1 : 0;
pusch_pdu->pusch_data.new_data_indicator = round == 0 ? true : false;
pusch_pdu->pusch_data.num_cb = 0;
pusch_pdu->pusch_ptrs.ptrs_time_density = ptrs_time_density;
pusch_pdu->pusch_ptrs.ptrs_freq_density = ptrs_freq_density;
......@@ -1525,10 +1514,10 @@ int main(int argc, char **argv)
}
for (i = 0; i < TBS; i++) {
estimated_output_bit[i] = (ulsch_gNB->harq_process->b[i / 8] & (1 << (i & 7))) >> (i & 7);
test_input_bit[i] = (UE->ul_harq_processes[harq_pid].b[i / 8] & (1 << (i & 7))) >> (i & 7);
uint8_t estimated_output_bit = (ulsch_gNB->harq_process->b[i / 8] & (1 << (i & 7))) >> (i & 7);
uint8_t test_input_bit = (UE->ul_harq_processes[harq_pid].b[i / 8] & (1 << (i & 7))) >> (i & 7);
if (estimated_output_bit[i] != test_input_bit[i]) {
if (estimated_output_bit != test_input_bit) {
/*if(errors_decoding == 0)
printf("\x1B[34m""[frame %d][trial %d]\t1st bit in error in decoding = %d\n" "\x1B[0m", frame, trial, i);*/
errors_decoding++;
......@@ -1663,8 +1652,6 @@ int main(int argc, char **argv)
num_dmrs_cdm_grps_no_data);
free_MIB_NR(mib);
free(test_input_bit);
free(estimated_output_bit);
if (gNB->ldpc_offload_flag)
free_nrLDPClib_offload();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment