@@ -604,107 +604,61 @@ GPUd() uint32_t GPUTPCCFDecodeZSDenseLink::DecodePage(GPUSharedMemory& smem, pro
604604 const auto * decHeader = Peek<TPCZSHDRV2>(page, raw::RDHUtils::getMemorySize (*rawDataHeader) - sizeof (TPCZSHDRV2));
605605 ConsumeHeader<header::RAWDataHeader>(page);
606606
607+ assert (decHeader->version >= ZSVersionDenseLinkBased);
608+ assert (decHeader->magicWord == tpc::zerosupp_link_based::CommonHeader::MagicWordLinkZSMetaHeader);
609+
607610 uint16_t nSamplesWritten = 0 ;
608611 const uint16_t nSamplesInPage = decHeader->nADCsamples ;
609612
610613 const auto * payloadEnd = Peek (pageStart, raw::RDHUtils::getMemorySize (*rawDataHeader) - sizeof (TPCZSHDRV2) - ((decHeader->flags & TPCZSHDRV2::ZSFlags::TriggerWordPresent) ? TPCZSHDRV2::TRIGGER_WORD_SIZE : 0 ));
611614 const auto * nextPage = Peek (pageStart, TPCZSHDR::TPC_ZS_PAGE_SIZE);
612615
613- const bool extendsToNextPage = decHeader->flags & TPCZSHDRV2::ZSFlags::payloadExtendsToNextPage;
614-
615616 ConsumeBytes (page, decHeader->firstZSDataOffset - sizeof (o2::header::RAWDataHeader));
616617
617- int err = GPUErrors::ERROR_NONE;
618+ for ( uint16_t i = 0 ; i < decHeader-> nTimebinHeaders ; i++) {
618619
619- if (decHeader->version < ZSVersionDenseLinkBased) {
620- err = GPUErrors::ERROR_TPCZS_VERSION_MISMATCH;
621- }
620+ [[maybe_unused]] ptrdiff_t sizeLeftInPage = payloadEnd - page;
621+ assert (sizeLeftInPage > 0 );
622622
623- if (decHeader->magicWord != zerosupp_link_based::CommonHeader::MagicWordLinkZSMetaHeader) {
624- err = GPUErrors::ERROR_TPCZS_INVALID_MAGIC_WORD;
625- }
626-
627- for (uint16_t i = 0 ; i < decHeader->nTimebinHeaders && !err; i++) {
628-
629- ptrdiff_t sizeLeftInPage = payloadEnd - page;
630- if (sizeLeftInPage <= 0 ) {
631- err = GPUErrors::ERROR_TPCZS_PAGE_OVERFLOW;
632- break ;
633- }
634-
635- int16_t nSamplesWrittenTB = 0 ;
636- uint16_t nSamplesLeftInPage = nSamplesInPage - nSamplesWritten;
637-
638- if (i == decHeader->nTimebinHeaders - 1 && extendsToNextPage) {
639- if (raw::RDHUtils::getMemorySize (*rawDataHeader) != TPCZSHDR::TPC_ZS_PAGE_SIZE) {
640- err = GPUErrors::ERROR_TPCZS_PAGE_OVERFLOW;
641- break ;
642- }
623+ uint16_t nSamplesWrittenTB = 0 ;
643624
625+ if (i == decHeader->nTimebinHeaders - 1 && decHeader->flags & o2::tpc::TPCZSHDRV2::ZSFlags::payloadExtendsToNextPage) {
626+ assert (o2::raw::RDHUtils::getMemorySize (*rawDataHeader) == TPCZSHDR::TPC_ZS_PAGE_SIZE);
644627 if ((uint16_t )(raw::RDHUtils::getPageCounter (rawDataHeader) + 1 ) == raw::RDHUtils::getPageCounter (nextPage)) {
645- nSamplesWrittenTB = DecodeTB<DecodeInParallel, true >(clusterer, smem, iThread, page, pageDigitOffset, rawDataHeader, firstHBF, decHeader->cruID , nSamplesLeftInPage, payloadEnd, nextPage);
628+ nSamplesWrittenTB = DecodeTB<DecodeInParallel, true >(clusterer, smem, iThread, page, pageDigitOffset, rawDataHeader, firstHBF, decHeader->cruID , payloadEnd, nextPage);
646629 } else {
647- err = GPUErrors::ERROR_TPCZS_INCOMPLETE_HBF;
648- break ;
630+ nSamplesWrittenTB = FillWithInvalid (clusterer, iThread, nThreads, pageDigitOffset, nSamplesInPage - nSamplesWritten);
631+ #ifdef GPUCA_CHECK_TPCZS_CORRUPTION
632+ if (iThread == 0 ) {
633+ clusterer.raiseError (GPUErrors::ERROR_TPCZS_INCOMPLETE_HBF, clusterer.mISector * 1000 + decHeader->cruID , raw::RDHUtils::getPageCounter (rawDataHeader), raw::RDHUtils::getPageCounter (nextPage));
634+ }
635+ #endif
649636 }
650637 } else {
651- nSamplesWrittenTB = DecodeTB<DecodeInParallel, false >(clusterer, smem, iThread, page, pageDigitOffset, rawDataHeader, firstHBF, decHeader->cruID , nSamplesLeftInPage, payloadEnd, nextPage);
652- }
653-
654- // Abort decoding the page if an error was detected.
655- if (nSamplesWrittenTB < 0 ) {
656- err = -nSamplesWrittenTB;
657- break ;
638+ nSamplesWrittenTB = DecodeTB<DecodeInParallel, false >(clusterer, smem, iThread, page, pageDigitOffset, rawDataHeader, firstHBF, decHeader->cruID , payloadEnd, nextPage);
658639 }
659640
641+ assert (nSamplesWritten <= nSamplesInPage);
660642 nSamplesWritten += nSamplesWrittenTB;
661643 pageDigitOffset += nSamplesWrittenTB;
662644 } // for (uint16_t i = 0; i < decHeader->nTimebinHeaders; i++)
663645
664- if (nSamplesWritten != nSamplesInPage) {
665- if (nSamplesWritten < nSamplesInPage) {
666- pageDigitOffset += FillWithInvalid (clusterer, iThread, nThreads, pageDigitOffset, nSamplesInPage - nSamplesWritten);
667- }
668- err = !err ? GPUErrors::ERROR_TPCZS_INVALID_NADC : err; // Ensure we don't overwrite any previous error
669- }
670-
671- if (iThread == 0 && err) {
672- [[maybe_unused]] bool dumpPage = false ;
673-
674- if (err == GPUErrors::ERROR_TPCZS_VERSION_MISMATCH) {
675- clusterer.raiseError (err, decHeader->version , ZSVersionDenseLinkBased);
676- } else if (err == GPUErrors::ERROR_TPCZS_INVALID_MAGIC_WORD) {
677- clusterer.raiseError (err, decHeader->magicWord );
678- } else if (err == GPUErrors::ERROR_TPCZS_INCOMPLETE_HBF) {
679- clusterer.raiseError (err, clusterer.mISector * 1000 + decHeader->cruID , raw::RDHUtils::getPageCounter (rawDataHeader), raw::RDHUtils::getPageCounter (nextPage));
680- } else if (err == GPUErrors::ERROR_TPCZS_PAGE_OVERFLOW) {
681- clusterer.raiseError (err, extendsToNextPage);
682- dumpPage = true ;
683- } else if (err == GPUErrors::ERROR_TPCZS_INVALID_NADC) {
684- clusterer.raiseError (err, nSamplesInPage, nSamplesWritten, extendsToNextPage);
685- dumpPage = true ;
686- } else {
687- clusterer.raiseError (GPUErrors::ERROR_TPCZS_UNKNOWN, err);
688- }
689-
690646#ifdef GPUCA_CHECK_TPCZS_CORRUPTION
691- #ifndef GPUCA_GPUCODE
692- if (dumpPage) {
693- // allocate more space on the stack for fname, so it can be overwritten by hand in a debugger.
694- const char fname[64 ] = " dump00.bin" ;
695- FILE* foo = fopen (fname, " w+b" );
696- fwrite (pageStart, 1 , TPCZSHDR::TPC_ZS_PAGE_SIZE, foo);
697- fclose (foo);
698- }
699- #endif
700- #endif
647+ if (iThread == 0 && nSamplesWritten != nSamplesInPage) {
648+ clusterer.raiseError (GPUErrors::ERROR_TPCZS_INVALID_NADC, clusterer.mISector * 1000 + decHeader->cruID , nSamplesInPage, nSamplesWritten);
649+ /* #ifndef GPUCA_GPUCODE
650+ FILE* foo = fopen("dump.bin", "w+b");
651+ fwrite(pageSrc, 1, o2::raw::RDHUtils::getMemorySize(*rdHdr), foo);
652+ fclose(foo);
653+ #endif*/
701654 }
655+ #endif
702656
703657 return pageDigitOffset;
704658}
705659
706660template <bool DecodeInParallel, bool PayloadExtendsToNextPage>
707- GPUd () int16_t GPUTPCCFDecodeZSDenseLink::DecodeTB (
661+ GPUd () uint16_t GPUTPCCFDecodeZSDenseLink::DecodeTB (
708662 processorType& clusterer,
709663 [[maybe_unused]] GPUSharedMemory& smem,
710664 int32_t iThread,
@@ -713,24 +667,23 @@ GPUd() int16_t GPUTPCCFDecodeZSDenseLink::DecodeTB(
713667 const header::RAWDataHeader* rawDataHeader,
714668 int32_t firstHBF,
715669 int32_t cru,
716- uint16_t nSamplesLeftInPage,
717- const uint8_t * payloadEnd,
718- const uint8_t * nextPage)
670+ [[maybe_unused]] const uint8_t * payloadEnd,
671+ [[maybe_unused]] const uint8_t * nextPage)
719672{
720673
721674 if constexpr (DecodeInParallel) {
722- return DecodeTBMultiThread<PayloadExtendsToNextPage>(clusterer, smem, iThread, page, pageDigitOffset, rawDataHeader, firstHBF, cru, nSamplesLeftInPage, payloadEnd, nextPage);
675+ return DecodeTBMultiThread<PayloadExtendsToNextPage>(clusterer, smem, iThread, page, pageDigitOffset, rawDataHeader, firstHBF, cru, payloadEnd, nextPage);
723676 } else {
724- int16_t nSamplesWritten = 0 ;
677+ uint16_t nSamplesWritten = 0 ;
725678 if (iThread == 0 ) {
726- nSamplesWritten = DecodeTBSingleThread<PayloadExtendsToNextPage>(clusterer, page, pageDigitOffset, rawDataHeader, firstHBF, cru, nSamplesLeftInPage, payloadEnd, nextPage);
679+ nSamplesWritten = DecodeTBSingleThread<PayloadExtendsToNextPage>(clusterer, page, pageDigitOffset, rawDataHeader, firstHBF, cru, payloadEnd, nextPage);
727680 }
728681 return warp_broadcast (nSamplesWritten, 0 );
729682 }
730683}
731684
732685template <bool PayloadExtendsToNextPage>
733- GPUd () int16_t GPUTPCCFDecodeZSDenseLink::DecodeTBMultiThread (
686+ GPUd () uint16_t GPUTPCCFDecodeZSDenseLink::DecodeTBMultiThread (
734687 processorType& clusterer,
735688 GPUSharedMemory& smem,
736689 const int32_t iThread,
@@ -739,9 +692,8 @@ GPUd() int16_t GPUTPCCFDecodeZSDenseLink::DecodeTBMultiThread(
739692 const header::RAWDataHeader* rawDataHeader,
740693 int32_t firstHBF,
741694 int32_t cru,
742- uint16_t nSamplesLeftInPage,
743- const uint8_t * payloadEnd,
744- const uint8_t * nextPage)
695+ [[maybe_unused]] const uint8_t * payloadEnd,
696+ [[maybe_unused]] const uint8_t * nextPage)
745697{
746698#define MAYBE_PAGE_OVERFLOW (pagePtr ) \
747699 if constexpr (PayloadExtendsToNextPage) { \
@@ -751,9 +703,7 @@ GPUd() int16_t GPUTPCCFDecodeZSDenseLink::DecodeTBMultiThread(
751703 ConsumeBytes (pagePtr, sizeof (header::RAWDataHeader) + diff); \
752704 } \
753705 } else { \
754- if (pagePtr > payloadEnd) { \
755- return -GPUErrors::ERROR_TPCZS_PAGE_OVERFLOW; \
756- } \
706+ assert (pagePtr <= payloadEnd); \
757707 }
758708
759709#define PEEK_OVERFLOW (pagePtr, offset ) \
@@ -778,7 +728,7 @@ GPUd() int16_t GPUTPCCFDecodeZSDenseLink::DecodeTBMultiThread(
778728 uint16_t linkBC = (tbbHdr & 0xFFF0 ) >> 4 ;
779729 int32_t timeBin = (linkBC + (uint64_t )(raw::RDHUtils::getHeartBeatOrbit (*rawDataHeader) - firstHBF) * constants::lhc::LHCMaxBunches) / LHCBCPERTIMEBIN;
780730
781- int16_t nSamplesInTB = 0 ;
731+ uint16_t nSamplesInTB = 0 ;
782732
783733 // Read timebin link headers
784734 for (uint8_t iLink = 0 ; iLink < nLinksInTimebin; iLink++) {
@@ -797,6 +747,7 @@ GPUd() int16_t GPUTPCCFDecodeZSDenseLink::DecodeTBMultiThread(
797747 }
798748
799749 int32_t nBytesBitmask = CAMath::Popcount (bitmaskL2);
750+ assert (nBytesBitmask <= 10 );
800751
801752 for (int32_t chan = iThread; chan < CAMath::nextMultipleOf<NTHREADS>(80 ); chan += NTHREADS) {
802753 int32_t chanL2Idx = chan / 8 ;
@@ -805,6 +756,7 @@ GPUd() int16_t GPUTPCCFDecodeZSDenseLink::DecodeTBMultiThread(
805756 int32_t chanByteOffset = nBytesBitmask - 1 - CAMath::Popcount (bitmaskL2 >> (chanL2Idx + 1 ));
806757
807758 uint8_t myChannelHasData = (chan < 80 && l2 ? TEST_BIT (PEEK_OVERFLOW (page, chanByteOffset), chan % 8 ) : 0 );
759+ assert (myChannelHasData == 0 || myChannelHasData == 1 );
808760
809761 int32_t nSamplesStep;
810762 int32_t threadSampleOffset = CfUtils::warpPredicateScan (myChannelHasData, &nSamplesStep);
@@ -827,17 +779,13 @@ GPUd() int16_t GPUTPCCFDecodeZSDenseLink::DecodeTBMultiThread(
827779
828780 GPUbarrierWarp (); // Ensure all writes to shared memory are finished, before reading it
829781
830- if (nSamplesInTB > nSamplesLeftInPage) {
831- return -GPUErrors::ERROR_TPCZS_INVALID_NADC;
832- }
782+ const uint8_t * adcData = ConsumeBytes (page, (nSamplesInTB * DECODE_BITS + 7 ) / 8 );
783+ MAYBE_PAGE_OVERFLOW (page); // TODO: We don't need this check?
833784
834785 if (not fragment.contains (timeBin)) {
835786 return FillWithInvalid (clusterer, iThread, NTHREADS, pageDigitOffset, nSamplesInTB);
836787 }
837788
838- const uint8_t * adcData = ConsumeBytes (page, (nSamplesInTB * DECODE_BITS + 7 ) / 8 );
839- MAYBE_PAGE_OVERFLOW (page);
840-
841789 // Unpack ADC
842790 int32_t iLink = 0 ;
843791 for (uint16_t sample = iThread; sample < nSamplesInTB; sample += NTHREADS) {
@@ -873,6 +821,9 @@ GPUd() int16_t GPUTPCCFDecodeZSDenseLink::DecodeTBMultiThread(
873821
874822 GPUbarrierWarp (); // Ensure all reads to shared memory are finished, before decoding next header into shmem
875823
824+ assert (PayloadExtendsToNextPage || adcData <= page);
825+ assert (PayloadExtendsToNextPage || page <= payloadEnd);
826+
876827 return nSamplesInTB;
877828
878829#undef TEST_BIT
@@ -881,14 +832,13 @@ GPUd() int16_t GPUTPCCFDecodeZSDenseLink::DecodeTBMultiThread(
881832}
882833
883834template <bool PayloadExtendsToNextPage>
884- GPUd () int16_t GPUTPCCFDecodeZSDenseLink::DecodeTBSingleThread (
835+ GPUd () uint16_t GPUTPCCFDecodeZSDenseLink::DecodeTBSingleThread (
885836 processorType& clusterer,
886837 const uint8_t *& page,
887838 uint32_t pageDigitOffset,
888839 const header::RAWDataHeader* rawDataHeader,
889840 int32_t firstHBF,
890841 int32_t cru,
891- uint16_t nSamplesLeftInPage,
892842 [[maybe_unused]] const uint8_t * payloadEnd,
893843 [[maybe_unused]] const uint8_t * nextPage)
894844{
@@ -900,9 +850,7 @@ GPUd() int16_t GPUTPCCFDecodeZSDenseLink::DecodeTBSingleThread(
900850 ConsumeBytes (pagePtr, sizeof (header::RAWDataHeader) + diff); \
901851 } \
902852 } else { \
903- if (pagePtr > payloadEnd) { \
904- return -GPUErrors::ERROR_TPCZS_PAGE_OVERFLOW; \
905- } \
853+ assert (pagePtr <= payloadEnd); \
906854 }
907855
908856 using zerosupp_link_based::ChannelPerTBHeader;
@@ -950,18 +898,14 @@ GPUd() int16_t GPUTPCCFDecodeZSDenseLink::DecodeTBSingleThread(
950898
951899 } // for (uint8_t iLink = 0; iLink < nLinksInTimebin; iLink++)
952900
953- if (nSamplesInTB > nSamplesLeftInPage) {
954- return -GPUErrors::ERROR_TPCZS_INVALID_NADC;
955- }
901+ const uint8_t * adcData = ConsumeBytes (page, (nSamplesInTB * DECODE_BITS + 7 ) / 8 );
902+ MAYBE_PAGE_OVERFLOW (page);
956903
957904 if (not fragment.contains (timeBin)) {
958905 FillWithInvalid (clusterer, 0 , 1 , pageDigitOffset, nSamplesInTB);
959906 return nSamplesInTB;
960907 }
961908
962- const uint8_t * adcData = ConsumeBytes (page, (nSamplesInTB * DECODE_BITS + 7 ) / 8 );
963- MAYBE_PAGE_OVERFLOW (page);
964-
965909 // Unpack ADC
966910 uint32_t byte = 0 , bits = 0 ;
967911 uint16_t rawFECChannel = 0 ;
@@ -993,6 +937,10 @@ GPUd() int16_t GPUTPCCFDecodeZSDenseLink::DecodeTBSingleThread(
993937 } // while (bits >= DECODE_BITS)
994938 } // while (nSamplesWritten < nAdc)
995939
940+ assert (PayloadExtendsToNextPage || adcData <= page);
941+ assert (PayloadExtendsToNextPage || page <= payloadEnd);
942+ assert (nSamplesWritten == nSamplesInTB);
943+
996944 return nSamplesWritten;
997945
998946#undef MAYBE_PAGE_OVERFLOW
0 commit comments