From ca19e977c08e4dfd5499aee1def66393bf14c4d9 Mon Sep 17 00:00:00 2001 From: Steven Franke Date: Thu, 1 Sep 2016 21:50:52 +0000 Subject: [PATCH] Add early termination code to the msk144 long-message decoder. Remove references to Radford Neal's ldpc code, which served us well but is no longer needed. git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@7051 ab8295b8-cf94-4d9e-aec4-7959e3be5d79 --- CMakeLists.txt | 20 -------------------- lib/bpdecode144.f90 | 17 +++++++++++++++++ lib/detectmsk144.f90 | 13 +++---------- lib/detectmsk40.f90 | 12 +----------- lib/encode_msk144.f90 | 1 - lib/fast_decode.f90 | 7 +++---- lib/ldpcsim144.f90 | 25 +++++++------------------ lib/ldpcsim40.f90 | 29 +++++++---------------------- lib/msk144_decode.f90 | 7 +++---- lib/msk144sim.f90 | 6 ------ main.cpp | 2 -- mainwindow.cpp | 25 ++----------------------- mainwindow.h | 3 --- 13 files changed, 43 insertions(+), 124 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 415be33b4..e20041eea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -481,22 +481,6 @@ set (ka9q_CSRCS ) set_source_files_properties (${ka9q_CSRCS} PROPERTIES COMPILE_FLAGS -Wno-sign-compare) -set (ldpc_CSRCS - lib/ldpc/alloc.c - lib/ldpc/rcode.c - lib/ldpc/dec.c - lib/ldpc/enc.c - lib/ldpc/intio.c - lib/ldpc/blockio.c - lib/ldpc/check.c - lib/ldpc/encode.c - lib/ldpc/open.c - lib/ldpc/mod2dense.c - lib/ldpc/mod2sparse.c - lib/ldpc/mod2convert.c - lib/ldpc/distrib.c - ) - set (qra_CSRCS lib/qra/qra64/qra64.c lib/qra/qra64/qra64_subs.c @@ -1245,10 +1229,6 @@ install (FILES install (FILES contrib/Ephemeris/JPLEPH - contrib/LDPC/peg-128-80-reg3.gen - contrib/LDPC/peg-128-80-reg3.pchk - contrib/LDPC/peg-32-16-reg3.gen - contrib/LDPC/peg-32-16-reg3.pchk DESTINATION ${WSJT_SHARE_DESTINATION}/${WSJT_DATA_DESTINATION} #COMPONENT runtime ) diff --git a/lib/bpdecode144.f90 b/lib/bpdecode144.f90 index bcbd6c16c..8cbf91208 100644 --- a/lib/bpdecode144.f90 +++ b/lib/bpdecode144.f90 @@ -276,6 +276,8 @@ do j=1,M enddo enddo +ncnt=0 + do iter=0,maxiterations ! Update bit log likelihood ratios @@ -299,6 +301,21 @@ do iter=0,maxiterations return endif + if( iter.gt.0 ) then ! this code block implements an early stopping criterion + nd=ncheck-nclast + if( nd .lt. 0 ) then ! # of unsatisfied parity checks decreased + ncnt=0 ! reset counter + else + ncnt=ncnt+1 + endif +! write(*,*) iter,ncheck,nd,ncnt + if( ncnt .ge. 3 .and. iter .ge. 5 .and. ncheck .gt. 10) then + niterations=-1 + return + endif + endif + nclast=ncheck + ! Send messages from bits to check nodes do j=1,M do i=1,nrw diff --git a/lib/detectmsk144.f90 b/lib/detectmsk144.f90 index 12c0ab2c3..9128e6372 100644 --- a/lib/detectmsk144.f90 +++ b/lib/detectmsk144.f90 @@ -1,10 +1,9 @@ -subroutine detectmsk144(cbig,n,pchk_file,lines,nmessages,nutc,ntol,t00) +subroutine detectmsk144(cbig,n,lines,nmessages,nutc,ntol,t00) use timer_module, only: timer parameter (NSPM=864, NPTS=3*NSPM, MAXSTEPS=1700, NFFT=NSPM, MAXCAND=16) character*22 msgreceived,allmessages(20) character*80 lines(100) - character*512 pchk_file,gen_file complex cbig(n) complex cdat(NPTS) !Analytic signal complex cdat2(NPTS) @@ -48,10 +47,6 @@ subroutine detectmsk144(cbig,n,pchk_file,lines,nmessages,nutc,ntol,t00) data s8r/1,0,1,1,0,0,0,1/ save df,first,cb,fs,pi,twopi,dt,s8,rcw,pp,nmatchedfilter - i=index(pchk_file,".pchk") - gen_file=pchk_file(1:i-1)//".gen" -! call init_ldpc(trim(pchk_file)//char(0),trim(gen_file)//char(0)) - if(first) then nmatchedfilter=1 ! define half-sine pulse and raised-cosine edge window @@ -382,11 +377,9 @@ subroutine detectmsk144(cbig,n,pchk_file,lines,nmessages,nutc,ntol,t00) max_iterations=10 max_dither=1 - call timer('ldpcdecod',0) -! call ldpc_decode(lratio, decoded, & -! max_iterations, niterations, max_dither, ndither) + call timer('bpdec144 ',0) call bpdecode144(llr,max_iterations,decoded,niterations) - call timer('ldpcdecod',1) + call timer('bpdec144 ',1) if( niterations .ge. 0.0 ) then call extractmessage144(decoded,msgreceived,nhashflag) diff --git a/lib/detectmsk40.f90 b/lib/detectmsk40.f90 index 9c0d25680..46daff68b 100644 --- a/lib/detectmsk40.f90 +++ b/lib/detectmsk40.f90 @@ -1,4 +1,4 @@ -subroutine detectmsk40(cbig,n,pchk_file,mycall,hiscall,lines,nmessages, & +subroutine detectmsk40(cbig,n,mycall,hiscall,lines,nmessages, & nutc,ntol,t00) use timer_module, only: timer @@ -7,8 +7,6 @@ subroutine detectmsk40(cbig,n,pchk_file,mycall,hiscall,lines,nmessages, & character*6 mycall,hiscall,mycall0,hiscall0 character*22 hashmsg,msgreceived character*80 lines(100) - character*512 pchk_file - character*512 pchk_file40,gen_file40 complex cbig(n) complex cdat(NPTS) !Analytic signal complex cdat2(NPTS) @@ -108,13 +106,6 @@ subroutine detectmsk40(cbig,n,pchk_file,mycall,hiscall,lines,nmessages, & hiscall0=hiscall endif -! Temporarily hardwire filenames and init on every call - i=index(pchk_file,"128-80") - pchk_file40=pchk_file(1:i-1)//"32-16"//pchk_file(i+6:) - i=index(pchk_file40,".pchk") - gen_file40=pchk_file40(1:i-1)//".gen" -! call init_ldpc(trim(pchk_file40)//char(0),trim(gen_file40)//char(0)) - ! Fill the detmet, detferr arrays nstepsize=60 ! 5ms steps nstep=(n-NPTS)/nstepsize @@ -384,7 +375,6 @@ subroutine detectmsk40(cbig,n,pchk_file,mycall,hiscall,lines,nmessages, & max_iterations=5 max_dither=1 -! call ldpc_decode(lratio,decoded,max_iterations,niterations,max_dither,ndither) call bpdecode40(llr,max_iterations, decoded, niterations) ncalls=ncalls+1 diff --git a/lib/encode_msk144.f90 b/lib/encode_msk144.f90 index fb7c77a62..4e4d8968e 100644 --- a/lib/encode_msk144.f90 +++ b/lib/encode_msk144.f90 @@ -8,7 +8,6 @@ subroutine encode_msk144(message,codeword) ! matrix stored in Radford Neal's "pchk" format. ! character*20 g(48) -character*1 tmpstr integer*1 codeword(128) integer*1 colorder(128) integer*1 gen144(48,80) diff --git a/lib/fast_decode.f90 b/lib/fast_decode.f90 index a297011ea..607a7ea4d 100644 --- a/lib/fast_decode.f90 +++ b/lib/fast_decode.f90 @@ -1,4 +1,4 @@ -subroutine fast_decode(id2,narg,ntrperiod,bShMsgs,line,pchk_file, & +subroutine fast_decode(id2,narg,ntrperiod,bShMsgs,line, & mycall_12,hiscall_12) parameter (NMAX=30*12000) @@ -13,7 +13,6 @@ subroutine fast_decode(id2,narg,ntrperiod,bShMsgs,line,pchk_file, & logical pick,first character*6 cfile6 character*80 line(100) - character*512 pchk_file character*12 mycall_12,hiscall_12 character*6 mycall,hiscall data first/.true./ @@ -63,10 +62,10 @@ subroutine fast_decode(id2,narg,ntrperiod,bShMsgs,line,pchk_file, & ! print*,ia,ib,nz,ndat0,t0,t1 if(npick.gt.1) go to 900 !### DISABLE PICK FROM LOWER PANEL### if(newdat.eq.1 .or. npick.le.1) then - call msk144_decode(id2(ia),nz,nutc,0,pchk_file,mycall,hiscall, & + call msk144_decode(id2(ia),nz,nutc,0,mycall,hiscall, & bShMsgs,ntol,t0,line) else - call msk144_decode(id2b(ia),nz,nutc,0,pchk_file,mycall,hiscall, & + call msk144_decode(id2b(ia),nz,nutc,0,mycall,hiscall, & bShMsgs,ntol,t0,line) endif go to 900 diff --git a/lib/ldpcsim144.f90 b/lib/ldpcsim144.f90 index cc9ecf059..56185823d 100644 --- a/lib/ldpcsim144.f90 +++ b/lib/ldpcsim144.f90 @@ -6,7 +6,6 @@ use hashing use packjt character*22 msg,msgsent,msgreceived character*80 prefix -character*85 pchk_file,gen_file character*8 arg integer*1, allocatable :: codeword(:), decoded(:), message(:) integer*1, target:: i1Msg8BitBytes(10) @@ -20,41 +19,31 @@ real, allocatable :: yy(:), llr(:) equivalence(ihash,i1hash) nargs=iargc() -if(nargs.ne.7) then - print*,'Usage: ldpcsim N K niter ndither #trials s ' - print*,'eg: ldpcsim "/pathto/peg-32-16-reg3" 32 16 10 1 1000 0.75' +if(nargs.ne.4) then + print*,'Usage: ldpcsim niter ndither #trials s ' + print*,'eg: ldpcsim 10 1 1000 0.75' return endif -call getarg(1,prefix) -call getarg(2,arg) -read(arg,*) N -call getarg(3,arg) -read(arg,*) K -call getarg(4,arg) +call getarg(1,arg) read(arg,*) max_iterations -call getarg(5,arg) +call getarg(2,arg) read(arg,*) max_dither -call getarg(6,arg) +call getarg(3,arg) read(arg,*) ntrials -call getarg(7,arg) +call getarg(4,arg) read(arg,*) s -pchk_file=trim(prefix)//".pchk" -gen_file=trim(prefix)//".gen" - !rate=real(K)/real(N) ! don't count hash bits as data bits rate=72.0/real(N) write(*,*) "rate: ",rate -write(*,*) "pchk file: ",pchk_file write(*,*) "niter= ",max_iterations," ndither= ",max_dither," s= ",s allocate ( codeword(N), decoded(K), message(K) ) allocate ( lratio(N), rxdata(N), yy(N), llr(N) ) -call init_ldpc(trim(pchk_file)//char(0),trim(gen_file)//char(0)) msg="K9AN K1JT EN50" call packmsg(msg,i4Msg6BitWords,itype) !Pack into 12 6-bit bytes call unpackmsg(i4Msg6BitWords,msgsent) !Unpack to get msgsent diff --git a/lib/ldpcsim40.f90 b/lib/ldpcsim40.f90 index 96a6ff767..27a51dd88 100644 --- a/lib/ldpcsim40.f90 +++ b/lib/ldpcsim40.f90 @@ -5,8 +5,6 @@ use hashing use packjt character*22 msg,msgsent,msgreceived -character*80 prefix -character*85 pchk_file,gen_file character*8 arg integer*1, allocatable :: codeword(:), decoded(:), message(:) real*8, allocatable :: lratio(:), rxdata(:) @@ -15,38 +13,28 @@ integer ihash integer*1 hardbits(32) nargs=iargc() -if(nargs.ne.7) then - print*,'Usage: ldpcsim N K niter ndither #trials s ' - print*,'eg: ldpcsim "/pathto/peg-32-16-reg3" 32 16 10 1 1000 0.75' +if(nargs.ne.4) then + print*,'Usage: ldpcsim niter ndither #trials s ' + print*,'eg: ldpcsim 10 1 1000 0.75' return endif -call getarg(1,prefix) -call getarg(2,arg) -read(arg,*) N -call getarg(3,arg) -read(arg,*) K -call getarg(4,arg) +call getarg(1,arg) read(arg,*) max_iterations -call getarg(5,arg) +call getarg(2,arg) read(arg,*) max_dither -call getarg(6,arg) +call getarg(3,arg) read(arg,*) ntrials -call getarg(7,arg) +call getarg(4,arg) read(arg,*) s -pchk_file=trim(prefix)//".pchk" -gen_file=trim(prefix)//".gen" - rate=real(K)/real(N) ! don't count hash bits as data bits !rate=5.0/real(N) write(*,*) "rate: ",rate -write(*,*) "pchk file: ",pchk_file write(*,*) "niter= ",max_iterations," ndither= ",max_dither," s= ",s allocate ( codeword(N), decoded(K), message(K) ) allocate ( lratio(N), rxdata(N), llr(N) ) -call init_ldpc(trim(pchk_file)//char(0),trim(gen_file)//char(0)) msg="K1JT K9AN RRR " irpt=14 @@ -59,8 +47,6 @@ do i=1,16 message(i)=iand(1,ishft(ig,1-i)) enddo write(*,'(16i1)') message -!call ldpc_encode(message,codeword) -!write(*,'(32i1)') codeword call encode_msk40(message,codeword) write(*,'(32i1)') codeword call init_random_seed() @@ -95,7 +81,6 @@ do idb = -6, 14 llr=2.0*rxdata/(ss*ss) lratio=exp(llr) -! call ldpc_decode(lratio, decoded, max_iterations, niterations, max_dither, ndither) call bpdecode40(llr, max_iterations, decoded, niterations) ! If the decoder finds a valid codeword, niterations will be .ge. 0. if( niterations .ge. 0 ) then diff --git a/lib/msk144_decode.f90 b/lib/msk144_decode.f90 index 575d21467..a1c21c58a 100644 --- a/lib/msk144_decode.f90 +++ b/lib/msk144_decode.f90 @@ -1,4 +1,4 @@ -subroutine msk144_decode(id2,npts,nutc,nprint,pchk_file,mycall,hiscall, & +subroutine msk144_decode(id2,npts,nutc,nprint,mycall,hiscall, & bShMsgs,ntol,t0,line) ! Calls the experimental decoder for MSK 72ms/16ms messages @@ -10,7 +10,6 @@ subroutine msk144_decode(id2,npts,nutc,nprint,pchk_file,mycall,hiscall, & real d(0:NMAX) !Raw r*4 data complex c(NFFTMAX) !Complex (analytic) data character*80 line(100) !Decodes passed back to caller - character*512 pchk_file character*6 mycall,hiscall logical*1 bShMsgs @@ -37,7 +36,7 @@ subroutine msk144_decode(id2,npts,nutc,nprint,pchk_file,mycall,hiscall, & call analytic(d,npts,nfft,c) !Convert to analytic signal and filter call timer('analytic',1) call timer('detec144',0) - call detectmsk144(c,npts,pchk_file,line,nline,nutc,ntol,t0) + call detectmsk144(c,npts,line,nline,nutc,ntol,t0) call timer('detec144',1) if( nprint .ne. 0 ) then do i=1,nline @@ -48,7 +47,7 @@ subroutine msk144_decode(id2,npts,nutc,nprint,pchk_file,mycall,hiscall, & if(nline.eq.0 .and. bShMsgs) then call timer('detect40',0) - call detectmsk40(c,npts,pchk_file,mycall,hiscall,line,nline,nutc,ntol,t0) + call detectmsk40(c,npts,mycall,hiscall,line,nline,nutc,ntol,t0) call timer('detect40',1) if( nprint .ne. 0 ) then do i=1,nline diff --git a/lib/msk144sim.f90 b/lib/msk144sim.f90 index 38548764f..dbb46a0e2 100644 --- a/lib/msk144sim.f90 +++ b/lib/msk144sim.f90 @@ -5,18 +5,12 @@ program msk144sim real pings(0:NMAX-1) real waveform(0:NMAX-1) character arg*8,msg*22,msgsent*22,fname*40 - character*512 encode_exe_file - character*512 pchk_file - character*512 ldpc_msg_file real wave(0:NMAX-1) !Simulated received waveform real*8 twopi,freq,phi,dphi0,dphi1,dphi type(hdr) h !Header for .wav file integer*2 iwave(0:NMAX-1) integer itone(144) !Message bits - pchk_file='./peg-128-80-reg3.pchk' - ldpc_msg_file='./ldpc_msg' - nargs=iargc() if(nargs.ne.5) then print*,'Usage: msk144sim message freq width snr nfiles' diff --git a/main.cpp b/main.cpp index 8c68925b5..bc077beb7 100644 --- a/main.cpp +++ b/main.cpp @@ -42,7 +42,6 @@ extern "C" { // Fortran procedures we need void four2a_(_Complex float *, int * nfft, int * ndim, int * isign, int * iform, int len); - void fini_ldpc_ (); } namespace @@ -348,7 +347,6 @@ int main(int argc, char *argv[]) } fftwf_forget_wisdom (); fftwf_cleanup (); - fini_ldpc_ (); // free LDPC decoder resources temp_dir.removeRecursively (); // clean up temp files return result; diff --git a/mainwindow.cpp b/mainwindow.cpp index ec7f223c7..704a6943a 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -109,7 +109,7 @@ extern "C" { float* width); void fast_decode_(short id2[], int narg[], int* ntrperiod, bool* bShMsgs, - char msg[], char pchkFile[], char mycall[], char hiscall[], + char msg[], char mycall[], char hiscall[], int len1, int len2, int len3, int len4); void hash_calls_(char calls[], int* ih9, int len); void degrade_snr_(short d2[], int* n, float* db, float* bandwidth); @@ -831,27 +831,6 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, int ntr[]={5,10,15,30}; m_TRperiod=ntr[m_TRindex-11]; } - QString pchkFile = m_config.data_dir().absoluteFilePath("peg-128-80-reg3.pchk"); - QByteArray ba = pchkFile.toLocal8Bit(); - for(int i=0; i<512; i++) { - m_pchkFile[i]=32; - if(isetMode(m_mode); @@ -2235,7 +2214,7 @@ void MainWindow::decode() //decode() narg[14]=m_config.aggressive(); memcpy(d2b,dec_data.d2,2*360000); watcher3.setFuture (QtConcurrent::run (std::bind (fast_decode_,&d2b[0], - &narg[0],&m_TRperiod,&m_bShMsgs,&m_msg[0][0],&m_pchkFile[0], + &narg[0],&m_TRperiod,&m_bShMsgs,&m_msg[0][0], dec_data.params.mycall,dec_data.params.hiscall,80,512,12,12))); } else { memcpy(to, from, qMin(mem_jt9->size(), size)); diff --git a/mainwindow.h b/mainwindow.h index b56b6abcd..d35e2b307 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -429,9 +429,6 @@ private: bool m_first_error; char m_msg[100][80]; - char m_pchkFile[512]; - char m_ldpcMsgFile[512]; - char m_encodeExeFile[512]; // labels in status bar QLabel tx_status_label;