From 8a03988eae3913117908cd104d78a4235455db28 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Tue, 6 Feb 2024 06:18:59 -0700 Subject: [PATCH 01/16] more work on index --- src/g2_gbytesc.F90 | 89 ++++++++++++++++++++++++++++++++++++++++++- tests/test_gbytec.F90 | 74 +++++++++++++++++------------------ 2 files changed, 125 insertions(+), 38 deletions(-) diff --git a/src/g2_gbytesc.F90 b/src/g2_gbytesc.F90 index de841bd0..55f890b3 100644 --- a/src/g2_gbytesc.F90 +++ b/src/g2_gbytesc.F90 @@ -30,7 +30,7 @@ end subroutine g2_gbytec !> interation. !> !> This should be used when input array IN has only one element. If IN -!> has more elements, use G2_SBYTESC(). +!> has more elements, use g2_sbytesc(). !> !> @param[inout] out packed array output !> @param[in] in unpacked array input @@ -169,3 +169,90 @@ subroutine g2_sbytesc(out, in, iskip, nbits, nskip, n) enddo end subroutine g2_sbytesc + +!> Put arbitrary size values into a packed bit string, taking the low +!> order bits from each value in the unpacked array without skip and +!> interation. +!> +!> This should be used when input array IN has only one element. If IN +!> has more elements, use g2_sbytesc(). +!> +!> @param[inout] out packed array output +!> @param[in] in unpacked array input +!> @param[in] iskip initial number of bits to skip +!> @param[in] nbits Number of bits of each integer in OUT to fill. +!> +!> @author Stephen Gilbert @date 2004-04-27 +subroutine g2_sbytec8(out, in, iskip, nbits) + implicit none + + character*1, intent(inout) :: out(*) + integer (kind = 8), intent(in) :: in(*) + integer, intent(in) :: iskip, nbits + call g2_sbytesc8(out, in, iskip, nbits, 0, 1) +end subroutine g2_sbytec8 + +!> Put arbitrary size values into a packed bit string, taking the low +!> order bits from each value in the unpacked array with skip and +!> interation options. +!> +!> @param[out] out Packed array output. +!> @param[in] in Unpacked array input. +!> @param[in] iskip Initial number of bits to skip. +!> @param[in] nbits Number of bits of each integer in OUT to fill. +!> @param[in] nskip Additional number of bits to skip on each iteration. +!> @param[in] n Number of iterations. +!> +!> @author Stephen Gilbert @date 2004-04-27 +subroutine g2_sbytesc8(out, in, iskip, nbits, nskip, n) + implicit none + + character*1, intent(out) :: out(*) + integer (kind = 8), intent(in) :: in(n) + integer, intent(in) :: iskip, nbits, nskip, n + + integer :: bitcnt, tbit + integer, parameter :: ones(8)=(/ 1, 3, 7, 15, 31, 63, 127, 255/) + integer :: nbit, i, itmp, index, ibit, imask, itmp2, itmp3 + integer, external :: mova2i + + ! number bits from zero to ... + ! nbit is the last bit of the field to be filled + nbit = iskip + nbits - 1 + do i = 1, n + itmp = int(in(i), kind(8)) + bitcnt = nbits + index = nbit / 8 + 1 + ibit = mod(nbit, 8) + nbit = nbit + nbits + nskip + + ! make byte aligned + if (ibit .ne. 7) then + tbit = min(bitcnt, ibit + 1) + imask = ishft(ones(tbit), 7 - ibit) + itmp2 = iand(ishft(itmp, 7 - ibit),imask) + itmp3 = iand(mova2i(out(index)), 255 - imask) + out(index) = char(ior(itmp2, itmp3)) + bitcnt = bitcnt - tbit + itmp = ishft(itmp, -tbit) + index = index - 1 + endif + + ! now byte aligned + + ! do by bytes + do while (bitcnt .ge. 8) + out(index) = char(iand(itmp, 255)) + itmp = ishft(itmp, -8) + bitcnt = bitcnt - 8 + index = index - 1 + enddo + + ! do last byte + if (bitcnt .gt. 0) then + itmp2 = iand(itmp, ones(bitcnt)) + itmp3 = iand(mova2i(out(index)), 255 - ones(bitcnt)) + out(index) = char(ior(itmp2, itmp3)) + endif + enddo +end subroutine g2_sbytesc8 diff --git a/tests/test_gbytec.F90 b/tests/test_gbytec.F90 index 6064e2e2..a34cd45a 100644 --- a/tests/test_gbytec.F90 +++ b/tests/test_gbytec.F90 @@ -135,17 +135,17 @@ program test_gbytec ! used, because I am passing in a real array instead of an int array ! for the in parameter. This is how g2_sbytesc() is called in ! addfield.F90. - print *, ' testing g2_sbytesc() with a real array (size 1) instead of an int array...' - iskip = 0 - nbits = 32 - nskip = 0 - num = 1 - r_in(1) = 1 - call g2_sbytesc(out4, r_in, iskip, nbits, nskip, num) - ! Note that the 32-bit IEEE representation of 1.0 is 3f800000. The - ! decimal for 3f is 63, the decimal for 80 is 128. - if (ichar(out4(1)) .ne. 63 .and. ichar(out4(2)) .ne. 128 .and. & - ichar(out4(3)) .ne. 0 .and. ichar(out4(4)) .ne. 0) stop 80 + ! print *, ' testing g2_sbytesc() with a real array (size 1) instead of an int array...' + ! iskip = 0 + ! nbits = 32 + ! nskip = 0 + ! num = 1 + ! r_in(1) = 1 + ! call g2_sbytesc(out4, r_in, iskip, nbits, nskip, num) + ! ! Note that the 32-bit IEEE representation of 1.0 is 3f800000. The + ! ! decimal for 3f is 63, the decimal for 80 is 128. + ! if (ichar(out4(1)) .ne. 63 .and. ichar(out4(2)) .ne. 128 .and. & + ! ichar(out4(3)) .ne. 0 .and. ichar(out4(4)) .ne. 0) stop 80 ! print '(z2.2)', out4(1) ! This test is the same as above, but does not require the @@ -167,20 +167,20 @@ program test_gbytec ! used, because I am passing in a real array instead of an int array ! for the in parameter. This is how g2_sbytesc() is called in ! addfield.F90. - print *, ' testing g2_sbytesc() with a real array instead of an int array...' - iskip = 0 - nbits = 32 - nskip = 0 - num = 2 - r_in2(1) = 1 - r_in2(2) = 1 - call g2_sbytesc(out8, r_in2, iskip, nbits, nskip, num) - ! Note that the 32-bit IEEE representation of 1.0 is 3f800000. The - ! decimal for 3f is 63, the decimal for 80 is 128. - if (ichar(out8(1)) .ne. 63 .and. ichar(out8(2)) .ne. 128 .and. & - ichar(out8(3)) .ne. 0 .and. ichar(out8(4)) .ne. 0) stop 100 - if (ichar(out8(5)) .ne. 63 .and. ichar(out8(6)) .ne. 128 .and. & - ichar(out8(7)) .ne. 0 .and. ichar(out8(8)) .ne. 0) stop 110 + ! print *, ' testing g2_sbytesc() with a real array instead of an int array...' + ! iskip = 0 + ! nbits = 32 + ! nskip = 0 + ! num = 2 + ! r_in2(1) = 1 + ! r_in2(2) = 1 + ! call g2_sbytesc(out8, r_in2, iskip, nbits, nskip, num) + ! ! Note that the 32-bit IEEE representation of 1.0 is 3f800000. The + ! ! decimal for 3f is 63, the decimal for 80 is 128. + ! if (ichar(out8(1)) .ne. 63 .and. ichar(out8(2)) .ne. 128 .and. & + ! ichar(out8(3)) .ne. 0 .and. ichar(out8(4)) .ne. 0) stop 100 + ! if (ichar(out8(5)) .ne. 63 .and. ichar(out8(6)) .ne. 128 .and. & + ! ichar(out8(7)) .ne. 0 .and. ichar(out8(8)) .ne. 0) stop 110 ! print '(z2.2)', out8(1) ! This test is the same as above, but does not require the -fallow-argument-mismatch flag. @@ -206,7 +206,7 @@ program test_gbytec do i = 1, 8 out8(i) = char(0) end do - call g2_sbytec(out8, in8, iskip, 64) + call g2_sbytec8(out8, in8, iskip, 64) do i = 1, 8 !print '(z2.2)', out8(i) if (i .lt. 8) then @@ -216,10 +216,10 @@ program test_gbytec endif end do - print *, ' now unpack into 1 64-bit int with g2_gbytesc()...' - in8_1(1) = 0 - call g2_gbytesc(out8, in8_1, iskip, 64, 0, 1) - if (in8_1(1) .ne. in8(1)) stop 150 + ! print *, ' now unpack into 1 64-bit int with g2_gbytesc()...' + ! in8_1(1) = 0 + ! call g2_gbytesc(out8, in8_1, iskip, 64, 0, 1) + ! if (in8_1(1) .ne. in8(1)) stop 150 print *, ' testing g2_sbytec() with 32-bit int array of size 4...' do i = 1, 4 @@ -250,17 +250,17 @@ program test_gbytec out32(i) = char(0) end do print *, in84 - call g2_sbytesc(out32, in84, iskip, 64, 0, 4) + call g2_sbytesc8(out32, in84, iskip, 64, 0, 4) do i = 1, 32 print '(i3, x, z2.2)', i, out32(i) end do - print *, ' now unpack into 4 64-bit ints with g2_gbytesc()...' - do i = 1, 4 - in84_1(i) = 0 - end do - call g2_gbytesc(out32, in84_1, iskip, 64, 0, 4) - print *, in84_1 + ! print *, ' now unpack into 4 64-bit ints with g2_gbytesc()...' + ! do i = 1, 4 + ! in84_1(i) = 0 + ! end do + ! call g2_gbytesc8(out32, in84_1, iskip, 64, 0, 4) + ! print *, in84_1 print *, 'SUCCESS!' From b297297b1ac6258c28b811c99f67f2242372fe9f Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Tue, 6 Feb 2024 06:31:04 -0700 Subject: [PATCH 02/16] more work on index --- src/g2_gbytesc.F90 | 154 ++++++++++++++++++++++++++++++++---------- tests/test_gbytec.F90 | 4 +- 2 files changed, 120 insertions(+), 38 deletions(-) diff --git a/src/g2_gbytesc.F90 b/src/g2_gbytesc.F90 index 55f890b3..867daeb2 100644 --- a/src/g2_gbytesc.F90 +++ b/src/g2_gbytesc.F90 @@ -3,9 +3,8 @@ !> string and unpacked array. !> @author Stephen Gilbert @date 2004-04-27 -!> Extract arbitrary size values from a packed bit string, right -!> justifying each value in the unpacked array without skip and -!> interations. +!> Extract one arbitrary size value (up to 32 bits) from a packed bit +!> string, right justifying each value in the unpacked array. !> !> This should be used when input array IN has only one element. If in !> has more elements, use g2_sbytesc(). @@ -13,7 +12,8 @@ !> @param[in] in Array input. !> @param[inout] iout Unpacked array output. !> @param[in] iskip Initial number of bits to skip. -!> @param[in] nbits Number of bits of each integer in IN to take. +!> @param[in] nbits Number of bits of each integer in IN to take. Must +!> be 32 or less. !> !> @author Stephen Gilbert @date 2004-04-27 subroutine g2_gbytec(in, iout, iskip, nbits) @@ -25,45 +25,102 @@ subroutine g2_gbytec(in, iout, iskip, nbits) call g2_gbytesc(in, iout, iskip, nbits, 0, 1) end subroutine g2_gbytec -!> Put arbitrary size values into a packed bit string, taking the low -!> order bits from each value in the unpacked array without skip and -!> interation. +!> Extract arbitrary size values (up to 32 bits each) from a packed +!> bit string, right justifying each value in the unpacked array. !> -!> This should be used when input array IN has only one element. If IN +!> @param[in] in array input +!> @param[out] iout unpacked array output +!> @param[in] iskip initial number of bits to skip +!> @param[in] nbits Number of bits of each integer in IN to take. Must +!> be 32 or less. +!> @param[in] nskip Additional number of bits to skip on each iteration. +!> @param[in] n Number of integers to extract. +!> +!> @author Stephen Gilbert @date 2004-04-27 +subroutine g2_gbytesc(in, iout, iskip, nbits, nskip, n) + implicit none + + character*1, intent(in) :: in(*) + integer, intent(out) :: iout(*) + integer, intent(in) :: iskip, nbits, nskip, n + integer :: tbit, bitcnt + integer, parameter :: ones(8) = (/ 1, 3, 7, 15, 31, 63, 127, 255 /) + + integer :: nbit, i, index, ibit, itmp + integer, external :: mova2i + + ! nbit is the start position of the field in bits + nbit = iskip + do i = 1, n + bitcnt = nbits + index = nbit / 8 + 1 + ibit = mod(nbit, 8) + nbit = nbit + nbits + nskip + + ! first byte + tbit = min(bitcnt, 8 - ibit) + itmp = iand(mova2i(in(index)), ones(8 - ibit)) + if (tbit .ne. 8 - ibit) itmp = ishft(itmp, tbit - 8 + ibit) + index = index + 1 + bitcnt = bitcnt - tbit + + ! now transfer whole bytes + do while (bitcnt .ge. 8) + itmp = ior(ishft(itmp,8), mova2i(in(index))) + bitcnt = bitcnt - 8 + index = index + 1 + enddo + + ! get data from last byte + if (bitcnt .gt. 0) then + itmp = ior(ishft(itmp, bitcnt), iand(ishft(mova2i(in(index)), & + - (8 - bitcnt)), ones(bitcnt))) + endif + + iout(i) = itmp + enddo + +end subroutine g2_gbytesc + +!> Extract one arbitrary sized (up to 64-bits) values from a packed bit +!> string, right justifying each value in the unpacked array. +!> +!> This should be used when input array in has only one element. If in !> has more elements, use g2_sbytesc(). !> -!> @param[inout] out packed array output -!> @param[in] in unpacked array input -!> @param[in] iskip initial number of bits to skip -!> @param[in] nbits Number of bits of each integer in OUT to fill. +!> @param[in] in Array input. +!> @param[inout] iout Unpacked array output. +!> @param[in] iskip Initial number of bits to skip. +!> @param[in] nbits Number of bits of each integer in IN to take. Must +!> be 64 or less. !> !> @author Stephen Gilbert @date 2004-04-27 -subroutine g2_sbytec(out, in, iskip, nbits) +subroutine g2_gbytec8(in, iout, iskip, nbits) implicit none - character*1, intent(inout) :: out(*) - integer, intent(in) :: in(*) + character*1, intent(in) :: in(*) + integer (kind = 8), intent(inout) :: iout(*) integer, intent(in) :: iskip, nbits - call g2_sbytesc(out, in, iskip, nbits, 0, 1) -end subroutine g2_sbytec + call g2_gbytesc(in, iout, iskip, nbits, 0, 1) +end subroutine g2_gbytec8 -!> Extract arbitrary size values from a packed bit string, right -!> justifying each value in the unpacked array with skip and -!> interation options. +!> Extract arbitrary sized (up to 64-bits) values from a packed bit +!> string, right justifying each value in the unpacked array. !> !> @param[in] in array input !> @param[out] iout unpacked array output !> @param[in] iskip initial number of bits to skip -!> @param[in] nbits Number of bits of each integer in IN to take. +!> @param[in] nbits Number of bits of each integer in IN to take. Must +!> be 64 or less. !> @param[in] nskip Additional number of bits to skip on each iteration. !> @param[in] n Number of integers to extract. !> !> @author Stephen Gilbert @date 2004-04-27 -subroutine g2_gbytesc(in, iout, iskip, nbits, nskip, n) +subroutine g2_gbytesc8(in, iout, iskip, nbits, nskip, n) implicit none character*1, intent(in) :: in(*) - integer, intent(out) :: iout(*) + integer (kind = 8), intent(out) :: iout(*) integer, intent(in) :: iskip, nbits, nskip, n integer :: tbit, bitcnt integer, parameter :: ones(8) = (/ 1, 3, 7, 15, 31, 63, 127, 255 /) @@ -102,16 +159,39 @@ subroutine g2_gbytesc(in, iout, iskip, nbits, nskip, n) iout(i) = itmp enddo -end subroutine g2_gbytesc +end subroutine g2_gbytesc8 -!> Put arbitrary size values into a packed bit string, taking the low -!> order bits from each value in the unpacked array with skip and -!> interation options. +!> Put one arbitrary sized (up to 32 bits) values into a packed bit +!> string, taking the low order bits from the value in the unpacked +!> array. +!> +!> This should be used when input array IN has only one element. If IN +!> has more elements, use g2_sbytesc(). +!> +!> @param[inout] out packed array output +!> @param[in] in unpacked array input +!> @param[in] iskip initial number of bits to skip +!> @param[in] nbits Number of bits of each integer in OUT to fill. +!> +!> @author Stephen Gilbert @date 2004-04-27 +subroutine g2_sbytec(out, in, iskip, nbits) + implicit none + + character*1, intent(inout) :: out(*) + integer, intent(in) :: in(*) + integer, intent(in) :: iskip, nbits + call g2_sbytesc(out, in, iskip, nbits, 0, 1) +end subroutine g2_sbytec + +!> Put arbitrary size (up to 32 bits each) values into a packed bit +!> string, taking the low order bits from each value in the unpacked +!> array. !> !> @param[out] out Packed array output. !> @param[in] in Unpacked array input. !> @param[in] iskip Initial number of bits to skip. -!> @param[in] nbits Number of bits of each integer in OUT to fill. +!> @param[in] nbits Number of bits of each integer in OUT to +!> fill. Must be 32 or less. !> @param[in] nskip Additional number of bits to skip on each iteration. !> @param[in] n Number of iterations. !> @@ -170,9 +250,9 @@ subroutine g2_sbytesc(out, in, iskip, nbits, nskip, n) end subroutine g2_sbytesc -!> Put arbitrary size values into a packed bit string, taking the low -!> order bits from each value in the unpacked array without skip and -!> interation. +!> Put one arbitrary sized (up to 64 bits) values into a packed bit +!> string, taking the low order bits from each value in the unpacked +!> array. !> !> This should be used when input array IN has only one element. If IN !> has more elements, use g2_sbytesc(). @@ -180,7 +260,8 @@ end subroutine g2_sbytesc !> @param[inout] out packed array output !> @param[in] in unpacked array input !> @param[in] iskip initial number of bits to skip -!> @param[in] nbits Number of bits of each integer in OUT to fill. +!> @param[in] nbits Number of bits of each integer in OUT to +!> fill. Must be 64 or less. !> !> @author Stephen Gilbert @date 2004-04-27 subroutine g2_sbytec8(out, in, iskip, nbits) @@ -192,14 +273,15 @@ subroutine g2_sbytec8(out, in, iskip, nbits) call g2_sbytesc8(out, in, iskip, nbits, 0, 1) end subroutine g2_sbytec8 -!> Put arbitrary size values into a packed bit string, taking the low -!> order bits from each value in the unpacked array with skip and -!> interation options. +!> Put arbitrary sized (up to 64 bits each) values into a packed bit +!> string, taking the low order bits from each value in the unpacked +!> array. !> !> @param[out] out Packed array output. !> @param[in] in Unpacked array input. !> @param[in] iskip Initial number of bits to skip. -!> @param[in] nbits Number of bits of each integer in OUT to fill. +!> @param[in] nbits Number of bits of each integer in OUT to +!> fill. Must be 64 or less. !> @param[in] nskip Additional number of bits to skip on each iteration. !> @param[in] n Number of iterations. !> diff --git a/tests/test_gbytec.F90 b/tests/test_gbytec.F90 index a34cd45a..a2cd1c29 100644 --- a/tests/test_gbytec.F90 +++ b/tests/test_gbytec.F90 @@ -201,7 +201,7 @@ program test_gbytec ichar(out8(7)) .ne. 0 .and. ichar(out8(8)) .ne. 0) stop 130 ! print '(z2.2)', out4(1) - print *, ' testing g2_sbytec() with 64-bit int...' + print *, ' testing g2_sbytec8() with 64-bit int...' in8(1) = 1 do i = 1, 8 out8(i) = char(0) @@ -221,7 +221,7 @@ program test_gbytec ! call g2_gbytesc(out8, in8_1, iskip, 64, 0, 1) ! if (in8_1(1) .ne. in8(1)) stop 150 - print *, ' testing g2_sbytec() with 32-bit int array of size 4...' + print *, ' testing g2_sbytec8() with 32-bit int array of size 4...' do i = 1, 4 in44(i) = 1 end do From dc6a118839bbf7f8e0482365620ad80b20030da1 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Tue, 6 Feb 2024 06:31:49 -0700 Subject: [PATCH 03/16] more index work --- tests/test_gbytec.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_gbytec.F90 b/tests/test_gbytec.F90 index a2cd1c29..36d52321 100644 --- a/tests/test_gbytec.F90 +++ b/tests/test_gbytec.F90 @@ -216,10 +216,10 @@ program test_gbytec endif end do - ! print *, ' now unpack into 1 64-bit int with g2_gbytesc()...' - ! in8_1(1) = 0 - ! call g2_gbytesc(out8, in8_1, iskip, 64, 0, 1) - ! if (in8_1(1) .ne. in8(1)) stop 150 + print *, ' now unpack into 1 64-bit int with g2_gbytesc()...' + in8_1(1) = 0 + call g2_gbytesc8(out8, in8_1, iskip, 64, 0, 1) + if (in8_1(1) .ne. in8(1)) stop 150 print *, ' testing g2_sbytec8() with 32-bit int array of size 4...' do i = 1, 4 From a7122d84f192a9d3612868cbfec1e2ecd09e9274 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Tue, 6 Feb 2024 06:33:49 -0700 Subject: [PATCH 04/16] more index work --- tests/test_gbytec.F90 | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tests/test_gbytec.F90 b/tests/test_gbytec.F90 index 36d52321..b5d60e35 100644 --- a/tests/test_gbytec.F90 +++ b/tests/test_gbytec.F90 @@ -255,12 +255,15 @@ program test_gbytec print '(i3, x, z2.2)', i, out32(i) end do - ! print *, ' now unpack into 4 64-bit ints with g2_gbytesc()...' - ! do i = 1, 4 - ! in84_1(i) = 0 - ! end do - ! call g2_gbytesc8(out32, in84_1, iskip, 64, 0, 4) - ! print *, in84_1 + print *, ' now unpack into 4 64-bit ints with g2_gbytesc()...' + do i = 1, 4 + in84_1(i) = 0 + end do + call g2_gbytesc8(out32, in84_1, iskip, 64, 0, 4) + print *, in84_1 + do i = 1, 4 + if (in84_1(i) .ne. in84(i)) stop 200 + end do print *, 'SUCCESS!' From 00b4f434106af2b741dd65f029bbe1757aad55c0 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Tue, 6 Feb 2024 07:14:05 -0700 Subject: [PATCH 05/16] more index work --- tests/test_gbytec.F90 | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/tests/test_gbytec.F90 b/tests/test_gbytec.F90 index b5d60e35..756b9ab5 100644 --- a/tests/test_gbytec.F90 +++ b/tests/test_gbytec.F90 @@ -242,7 +242,7 @@ program test_gbytec if (in44_1(i) .ne. in44(i)) stop 160 end do - print *, ' testing g2_sbytec() with 64-bit int array of size 4...' + print *, ' testing g2_sbytec8() with 64-bit int array of size 4...' do i = 1, 4 in84(i) = 1 end do @@ -255,7 +255,7 @@ program test_gbytec print '(i3, x, z2.2)', i, out32(i) end do - print *, ' now unpack into 4 64-bit ints with g2_gbytesc()...' + print *, ' now unpack into 4 64-bit ints with g2_gbytesc8()...' do i = 1, 4 in84_1(i) = 0 end do @@ -265,6 +265,24 @@ program test_gbytec if (in84_1(i) .ne. in84(i)) stop 200 end do + print *, ' testing g2_sbytec8() with very large 64-bit int...' + ! largest 4 byte signed int, plus 1. + in8(1) = 2147483647 + 1 + do i = 1, 8 + out8(i) = char(0) + end do + call g2_sbytec8(out8, in8, iskip, 64) + do i = 1, 8 + print '(z2.2)', out8(i) + end do + + print *, ' now unpack into 1 64-bit int with g2_gbytesc8()...' + in8_1(1) = 0 + call g2_gbytesc8(out8, in8_1, iskip, 64, 0, 1) + print *, in8_1 +! if (in8_1(1) .ne. in8(1)) stop 150 + + print *, 'SUCCESS!' end program test_gbytec From 0479f9287bf96c481ee6eee98f3432db0f39173b Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Wed, 7 Feb 2024 05:43:59 -0700 Subject: [PATCH 06/16] working on 64-bit index data --- src/g2_gbytesc.F90 | 34 ++-- tests/test_gbytec.F90 | 421 ++++++++++++++++++++++-------------------- 2 files changed, 241 insertions(+), 214 deletions(-) diff --git a/src/g2_gbytesc.F90 b/src/g2_gbytesc.F90 index 867daeb2..a3e8a1e5 100644 --- a/src/g2_gbytesc.F90 +++ b/src/g2_gbytesc.F90 @@ -101,7 +101,7 @@ subroutine g2_gbytec8(in, iout, iskip, nbits) character*1, intent(in) :: in(*) integer (kind = 8), intent(inout) :: iout(*) integer, intent(in) :: iskip, nbits - call g2_gbytesc(in, iout, iskip, nbits, 0, 1) + call g2_gbytesc8(in, iout, iskip, nbits, 0, 1) end subroutine g2_gbytec8 !> Extract arbitrary sized (up to 64-bits) values from a packed bit @@ -211,13 +211,15 @@ subroutine g2_sbytesc(out, in, iskip, nbits, nskip, n) ! number bits from zero to ... ! nbit is the last bit of the field to be filled nbit = iskip + nbits - 1 + !print *, 'nbit', nbit, 'nbits ', nbits, 'nskip', nskip, 'n', n do i = 1, n itmp = in(i) bitcnt = nbits index = nbit / 8 + 1 ibit = mod(nbit, 8) nbit = nbit + nbits + nskip - + !print *, 'i', i, 'itmp', itmp, 'bitcnt', bitcnt, 'index', index, 'ibit', ibit, 'nbit', nbit + ! make byte aligned if (ibit .ne. 7) then tbit = min(bitcnt, ibit + 1) @@ -235,14 +237,16 @@ subroutine g2_sbytesc(out, in, iskip, nbits, nskip, n) ! do by bytes do while (bitcnt .ge. 8) out(index) = char(iand(itmp, 255)) + !print '(z2.2, x, z2.2, x, z2.2)', out(index), itmp, iand(itmp, 255) itmp = ishft(itmp, -8) bitcnt = bitcnt - 8 index = index - 1 enddo - ! do last byte + ! Do left over bits. if (bitcnt .gt. 0) then itmp2 = iand(itmp, ones(bitcnt)) + !print '(z2.2, x, z2.2)', ones(bitcnt), itmp2 itmp3 = iand(mova2i(out(index)), 255 - ones(bitcnt)) out(index) = char(ior(itmp2, itmp3)) endif @@ -295,44 +299,50 @@ subroutine g2_sbytesc8(out, in, iskip, nbits, nskip, n) integer :: bitcnt, tbit integer, parameter :: ones(8)=(/ 1, 3, 7, 15, 31, 63, 127, 255/) - integer :: nbit, i, itmp, index, ibit, imask, itmp2, itmp3 + integer :: nbit, i, index, ibit, imask, itmp1, itmp2, itmp3 + integer (kind = 8) :: itmp8, itmp8_2 integer, external :: mova2i ! number bits from zero to ... ! nbit is the last bit of the field to be filled nbit = iskip + nbits - 1 + !print *, 'nbit', nbit, 'nbits ', nbits, 'nskip', nskip, 'n', n do i = 1, n - itmp = int(in(i), kind(8)) + itmp8 = in(i) bitcnt = nbits index = nbit / 8 + 1 ibit = mod(nbit, 8) nbit = nbit + nbits + nskip + !print *, 'i', i, 'itmp8', itmp8, 'bitcnt', bitcnt, 'index', index, 'ibit', ibit, 'nbit', nbit ! make byte aligned if (ibit .ne. 7) then tbit = min(bitcnt, ibit + 1) imask = ishft(ones(tbit), 7 - ibit) - itmp2 = iand(ishft(itmp, 7 - ibit),imask) + itmp1 = int(ishft(itmp8, int(7 - ibit, kind(8))), kind(4)) + itmp2 = iand(itmp1, imask) itmp3 = iand(mova2i(out(index)), 255 - imask) out(index) = char(ior(itmp2, itmp3)) bitcnt = bitcnt - tbit - itmp = ishft(itmp, -tbit) + itmp8 = ishft(itmp8, -tbit) index = index - 1 endif ! now byte aligned - ! do by bytes + ! Process a byte at a time. do while (bitcnt .ge. 8) - out(index) = char(iand(itmp, 255)) - itmp = ishft(itmp, -8) + !print *, bitcnt, iand(itmp8, 255_8) + out(index) = char(iand(itmp8, 255_8)) + itmp8 = ishft(itmp8, -8) bitcnt = bitcnt - 8 index = index - 1 enddo - ! do last byte + ! Take care of left over bits. if (bitcnt .gt. 0) then - itmp2 = iand(itmp, ones(bitcnt)) + itmp8_2 = int(ones(bitcnt), kind(8)) + itmp2 = int(iand(itmp8, itmp8_2), kind(4)) itmp3 = iand(mova2i(out(index)), 255 - ones(bitcnt)) out(index) = char(ior(itmp2, itmp3)) endif diff --git a/tests/test_gbytec.F90 b/tests/test_gbytec.F90 index 756b9ab5..cbbb1e67 100644 --- a/tests/test_gbytec.F90 +++ b/tests/test_gbytec.F90 @@ -32,254 +32,271 @@ program test_gbytec print *, 'Testing g2_gbytesc.F90 subroutines.' - print *, ' testing g2_sbytec()...' - in(1) = 3 - out(1) = char(0) - call g2_sbytec(out, in, iskip, nbits) - if (ichar(out(1)) .ne. in(1)) stop 10 + ! print *, ' testing g2_sbytec(), packing one 32-bit int into 8 bits of a char array in big-endian...' + ! in(1) = 3 + ! out(1) = char(0) + ! call g2_sbytec(out, in, iskip, nbits) + ! if (ichar(out(1)) .ne. in(1)) stop 10 + ! print '(z2.2)', out(1) + + ! print *, ' packing one 32-bit int into 32 bits of a char array in big-endian...' + ! in(1) = 3 + ! do i = 1, 4 + ! out4(i) = char(0) + ! end do + ! call g2_sbytec(out4, in, 0, 32) + ! do i = 1, 4 + ! print '(z2.2)', out4(i) + ! end do + + ! print *, ' testing g2_gbytec()...' + ! call g2_gbytec(out, in, iskip, nbits) + ! if (ichar(out(1)) .ne. in(1)) stop 11 - print *, ' testing g2_gbytec()...' - call g2_gbytec(out, in, iskip, nbits) - if (ichar(out(1)) .ne. in(1)) stop 11 + ! print *, ' testing g2_sbytesc()...' + ! in(1) = 3 + ! out(1) = char(0) + ! call g2_sbytesc(out, in, iskip, nbits, nskip, n) + ! if (ichar(out(1)) .ne. in(1)) stop 20 - print *, ' testing g2_sbytesc()...' - in(1) = 3 - out(1) = char(0) - call g2_sbytesc(out, in, iskip, nbits, nskip, n) - if (ichar(out(1)) .ne. in(1)) stop 20 + ! ! This will pack the numbers 1 and 2 into the first two chars of the + ! ! buffer. The rest of the output buffer will remain zeros. + ! print *, ' testing g2_sbytesc() packing 2 values...' + ! in2(1) = 1 + ! in2(2) = 2 + ! do i = 1, 8 + ! out8(i) = char(0) + ! end do + ! nbits = 8 + ! call g2_sbytesc(out8, in2, iskip, nbits, nskip, n2) + ! do i = 1, 8 + ! if (i .le. 2) then + ! if (ichar(out8(i)) .ne. in2(i)) stop 30; + ! else + ! if (ichar(out8(i)) .ne. 0) stop 31; + ! endif + ! end do - ! This will pack the numbers 1 and 2 into the first two chars of the - ! buffer. The rest of the output buffer will remain zeros. - print *, ' testing g2_sbytesc() packing 2 values...' - in2(1) = 1 - in2(2) = 2 - do i = 1, 8 - out8(i) = char(0) - end do - nbits = 8 - call g2_sbytesc(out8, in2, iskip, nbits, nskip, n2) - do i = 1, 8 - if (i .le. 2) then - if (ichar(out8(i)) .ne. in2(i)) stop 30; - else - if (ichar(out8(i)) .ne. 0) stop 31; - endif - end do - - ! Now pack 5 values into the 5 character array out5. - print *, ' testing g2_sbytesc() packing 5 values...' - in5(1) = 1 - in5(2) = 2 - in5(3) = 3 - in5(4) = 4 - in5(5) = 5 - nbits = 8 - nskip = 0 - do i = 1, 5 - out5(i) = char(0) - end do - call g2_sbytesc(out5, in5, iskip, nbits, nskip, n5) - do i = 1, 5 - if (ichar(out5(i)) .ne. in5(i)) stop 40; - end do + ! ! Now pack 5 values into the 5 character array out5. + ! print *, ' testing g2_sbytesc() packing 5 values...' + ! in5(1) = 1 + ! in5(2) = 2 + ! in5(3) = 3 + ! in5(4) = 4 + ! in5(5) = 5 + ! nbits = 8 + ! nskip = 0 + ! do i = 1, 5 + ! out5(i) = char(0) + ! end do + ! call g2_sbytesc(out5, in5, iskip, nbits, nskip, n5) + ! do i = 1, 5 + ! if (ichar(out5(i)) .ne. in5(i)) stop 40; + ! end do - ! Now pack 5 values into the 10 character array out10. Skip every - ! other byte in the output. - print *, ' testing g2_sbytesc() packing 5 values, skipping every other byte...' - nbits = 8 - nskip = 0 - do i = 1, 10 - out10(i) = char(0) - end do - call g2_sbytesc(out10, in5, iskip, nbits, 8, 5) - do i = 1, 10 - ! print '(z2.2)', out10(i) - if (mod(i, 2) .gt. 0) then - if (ichar(out10(i)) .ne. in5(int(i/2) + 1)) stop 51; - else - if (ichar(out10(i)) .ne. 0) stop 52; - endif - end do + ! ! Now pack 5 values into the 10 character array out10. Skip every + ! ! other byte in the output. + ! print *, ' testing g2_sbytesc() packing 5 values, skipping every other byte...' + ! nbits = 8 + ! nskip = 0 + ! do i = 1, 10 + ! out10(i) = char(0) + ! end do + ! call g2_sbytesc(out10, in5, iskip, nbits, 8, 5) + ! do i = 1, 10 + ! ! print '(z2.2)', out10(i) + ! if (mod(i, 2) .gt. 0) then + ! if (ichar(out10(i)) .ne. in5(int(i/2) + 1)) stop 51; + ! else + ! if (ichar(out10(i)) .ne. 0) stop 52; + ! endif + ! end do - print *, ' testing g2_sbytec() with iskip of 1...' - in(1) = 1 - out(1) = char(0) - call g2_sbytec(out, in, 1, 6) - if (ichar(out(1)) .ne. 2) stop 53 + ! print *, ' testing g2_sbytec() with iskip of 1...' + ! in(1) = 1 + ! out(1) = char(0) + ! call g2_sbytec(out, in, 1, 6) + ! if (ichar(out(1)) .ne. 2) stop 53 - print *, ' testing g2_sbytesc() with a size 4 output array...' - iskip = 0 - nbits = 32 - nskip = 0 - num = 1 - in(1) = 1 - call g2_sbytesc(out4, in, iskip, nbits, nskip, num) - if (ichar(out4(1)) .ne. 0 .and. ichar(out4(2)) .ne. 0 .and. & - ichar(out4(3)) .ne. 0 .and. ichar(out4(4)) .ne. 1) stop 60 + ! print *, ' testing g2_sbytesc() with a size 4 output array...' + ! iskip = 0 + ! nbits = 32 + ! nskip = 0 + ! num = 1 + ! in(1) = 1 + ! call g2_sbytesc(out4, in, iskip, nbits, nskip, num) + ! if (ichar(out4(1)) .ne. 0 .and. ichar(out4(2)) .ne. 0 .and. & + ! ichar(out4(3)) .ne. 0 .and. ichar(out4(4)) .ne. 1) stop 60 - print *, ' now unpack into 4 ints with g2_gbytesc()...' - call g2_gbytesc(out4, in4, iskip, 8, 0, 4) - do i = 1, 4 - if (i < 4) then - if (in4(i) .ne. 0) stop 61 - else - if (in4(i) .ne. 1) stop 62 - endif - end do + ! print *, ' now unpack into 4 ints with g2_gbytesc()...' + ! call g2_gbytesc(out4, in4, iskip, 8, 0, 4) + ! do i = 1, 4 + ! if (i < 4) then + ! if (in4(i) .ne. 0) stop 61 + ! else + ! if (in4(i) .ne. 1) stop 62 + ! endif + ! end do - print *, ' now unpack into 1 int with g2_gbytesc()...' - call g2_gbytesc(out4, in1, iskip, 32, 0, 1) - if (in1(1) .ne. 1) stop 70 + ! print *, ' now unpack into 1 int with g2_gbytesc()...' + ! call g2_gbytesc(out4, in1, iskip, 32, 0, 1) + ! if (in1(1) .ne. 1) stop 70 - ! For this test to pass the -fallow-argument-mismatch flag must be - ! used, because I am passing in a real array instead of an int array - ! for the in parameter. This is how g2_sbytesc() is called in - ! addfield.F90. - ! print *, ' testing g2_sbytesc() with a real array (size 1) instead of an int array...' + ! ! For this test to pass the -fallow-argument-mismatch flag must be + ! ! used, because I am passing in a real array instead of an int array + ! ! for the in parameter. This is how g2_sbytesc() is called in + ! ! addfield.F90. + ! ! print *, ' testing g2_sbytesc() with a real array (size 1) instead of an int array...' + ! ! iskip = 0 + ! ! nbits = 32 + ! ! nskip = 0 + ! ! num = 1 + ! ! r_in(1) = 1 + ! ! call g2_sbytesc(out4, r_in, iskip, nbits, nskip, num) + ! ! ! Note that the 32-bit IEEE representation of 1.0 is 3f800000. The + ! ! ! decimal for 3f is 63, the decimal for 80 is 128. + ! ! if (ichar(out4(1)) .ne. 63 .and. ichar(out4(2)) .ne. 128 .and. & + ! ! ichar(out4(3)) .ne. 0 .and. ichar(out4(4)) .ne. 0) stop 80 + ! ! print '(z2.2)', out4(1) + + ! ! This test is the same as above, but does not require the + ! ! -fallow-argument-mismatch flag. + ! print *, ' testing g2_sbytesc() with a size 1 real array instead of an int array, using transfer()...' ! iskip = 0 ! nbits = 32 ! nskip = 0 ! num = 1 - ! r_in(1) = 1 - ! call g2_sbytesc(out4, r_in, iskip, nbits, nskip, num) + ! r_in(1) = 1 + ! in = transfer(r_in, in) + ! call g2_sbytesc(out4, in, iskip, nbits, nskip, num) ! ! Note that the 32-bit IEEE representation of 1.0 is 3f800000. The ! ! decimal for 3f is 63, the decimal for 80 is 128. ! if (ichar(out4(1)) .ne. 63 .and. ichar(out4(2)) .ne. 128 .and. & - ! ichar(out4(3)) .ne. 0 .and. ichar(out4(4)) .ne. 0) stop 80 - ! print '(z2.2)', out4(1) + ! ichar(out4(3)) .ne. 0 .and. ichar(out4(4)) .ne. 0) stop 90 - ! This test is the same as above, but does not require the - ! -fallow-argument-mismatch flag. - print *, ' testing g2_sbytesc() with a size 1 real array instead of an int array, using transfer()...' - iskip = 0 - nbits = 32 - nskip = 0 - num = 1 - r_in(1) = 1 - in = transfer(r_in, in) - call g2_sbytesc(out4, in, iskip, nbits, nskip, num) - ! Note that the 32-bit IEEE representation of 1.0 is 3f800000. The - ! decimal for 3f is 63, the decimal for 80 is 128. - if (ichar(out4(1)) .ne. 63 .and. ichar(out4(2)) .ne. 128 .and. & - ichar(out4(3)) .ne. 0 .and. ichar(out4(4)) .ne. 0) stop 90 + ! ! For this test to pass the -fallow-argument-mismatch flag must be + ! ! used, because I am passing in a real array instead of an int array + ! ! for the in parameter. This is how g2_sbytesc() is called in + ! ! addfield.F90. + ! ! print *, ' testing g2_sbytesc() with a real array instead of an int array...' + ! ! iskip = 0 + ! ! nbits = 32 + ! ! nskip = 0 + ! ! num = 2 + ! ! r_in2(1) = 1 + ! ! r_in2(2) = 1 + ! ! call g2_sbytesc(out8, r_in2, iskip, nbits, nskip, num) + ! ! ! Note that the 32-bit IEEE representation of 1.0 is 3f800000. The + ! ! ! decimal for 3f is 63, the decimal for 80 is 128. + ! ! if (ichar(out8(1)) .ne. 63 .and. ichar(out8(2)) .ne. 128 .and. & + ! ! ichar(out8(3)) .ne. 0 .and. ichar(out8(4)) .ne. 0) stop 100 + ! ! if (ichar(out8(5)) .ne. 63 .and. ichar(out8(6)) .ne. 128 .and. & + ! ! ichar(out8(7)) .ne. 0 .and. ichar(out8(8)) .ne. 0) stop 110 + ! ! print '(z2.2)', out8(1) - ! For this test to pass the -fallow-argument-mismatch flag must be - ! used, because I am passing in a real array instead of an int array - ! for the in parameter. This is how g2_sbytesc() is called in - ! addfield.F90. - ! print *, ' testing g2_sbytesc() with a real array instead of an int array...' + ! ! This test is the same as above, but does not require the -fallow-argument-mismatch flag. + ! print *, ' testing g2_sbytesc() with a real array instead of an int array, using transfer() intrinsic...' ! iskip = 0 ! nbits = 32 ! nskip = 0 ! num = 2 ! r_in2(1) = 1 ! r_in2(2) = 1 - ! call g2_sbytesc(out8, r_in2, iskip, nbits, nskip, num) + ! in = transfer(r_in2, in2) + ! call g2_sbytesc(out8, in2, iskip, nbits, nskip, num) ! ! Note that the 32-bit IEEE representation of 1.0 is 3f800000. The ! ! decimal for 3f is 63, the decimal for 80 is 128. - ! if (ichar(out8(1)) .ne. 63 .and. ichar(out8(2)) .ne. 128 .and. & - ! ichar(out8(3)) .ne. 0 .and. ichar(out8(4)) .ne. 0) stop 100 + ! if (ichar(out4(1)) .ne. 63 .and. ichar(out4(2)) .ne. 128 .and. & + ! ichar(out4(3)) .ne. 0 .and. ichar(out4(4)) .ne. 0) stop 120 ! if (ichar(out8(5)) .ne. 63 .and. ichar(out8(6)) .ne. 128 .and. & - ! ichar(out8(7)) .ne. 0 .and. ichar(out8(8)) .ne. 0) stop 110 - ! print '(z2.2)', out8(1) - - ! This test is the same as above, but does not require the -fallow-argument-mismatch flag. - print *, ' testing g2_sbytesc() with a real array instead of an int array, using transfer() intrinsic...' - iskip = 0 - nbits = 32 - nskip = 0 - num = 2 - r_in2(1) = 1 - r_in2(2) = 1 - in = transfer(r_in2, in2) - call g2_sbytesc(out8, in2, iskip, nbits, nskip, num) - ! Note that the 32-bit IEEE representation of 1.0 is 3f800000. The - ! decimal for 3f is 63, the decimal for 80 is 128. - if (ichar(out4(1)) .ne. 63 .and. ichar(out4(2)) .ne. 128 .and. & - ichar(out4(3)) .ne. 0 .and. ichar(out4(4)) .ne. 0) stop 120 - if (ichar(out8(5)) .ne. 63 .and. ichar(out8(6)) .ne. 128 .and. & - ichar(out8(7)) .ne. 0 .and. ichar(out8(8)) .ne. 0) stop 130 + ! ichar(out8(7)) .ne. 0 .and. ichar(out8(8)) .ne. 0) stop 130 ! print '(z2.2)', out4(1) - print *, ' testing g2_sbytec8() with 64-bit int...' - in8(1) = 1 - do i = 1, 8 - out8(i) = char(0) - end do - call g2_sbytec8(out8, in8, iskip, 64) - do i = 1, 8 - !print '(z2.2)', out8(i) - if (i .lt. 8) then - if (ichar(out8(i)) .ne. 0) stop 140 - else - if (ichar(out8(i)) .ne. 1) stop 140 - endif - end do + ! print *, ' testing g2_sbytec8() with 64-bit int...' + ! in8(1) = 1 + ! do i = 1, 8 + ! out8(i) = char(0) + ! end do + ! call g2_sbytec8(out8, in8, iskip, 64) + ! do i = 1, 8 + ! !print '(z2.2)', out8(i) + ! if (i .lt. 8) then + ! if (ichar(out8(i)) .ne. 0) stop 140 + ! else + ! if (ichar(out8(i)) .ne. 1) stop 140 + ! endif + ! end do - print *, ' now unpack into 1 64-bit int with g2_gbytesc()...' - in8_1(1) = 0 - call g2_gbytesc8(out8, in8_1, iskip, 64, 0, 1) - if (in8_1(1) .ne. in8(1)) stop 150 + ! print *, ' now unpack into 1 64-bit int with g2_gbytesc()...' + ! in8_1(1) = 0 + ! call g2_gbytesc8(out8, in8_1, iskip, 64, 0, 1) + ! if (in8_1(1) .ne. in8(1)) stop 150 - print *, ' testing g2_sbytec8() with 32-bit int array of size 4...' - do i = 1, 4 - in44(i) = 1 - end do - do i = 1, 16 - out16(i) = char(0) - end do - call g2_sbytesc(out16, in44, iskip, 32, 0, 4) - do i = 1, 16 - print '(i3, x, z2.2)', i, out16(i) - end do + ! print *, ' testing g2_sbytec8() with 32-bit int array of size 4...' + ! do i = 1, 4 + ! in44(i) = 1 + ! end do + ! do i = 1, 16 + ! out16(i) = char(0) + ! end do + ! call g2_sbytesc(out16, in44, iskip, 32, 0, 4) + ! do i = 1, 16 + ! print '(i3, x, z2.2)', i, out16(i) + ! end do - print *, ' now unpack into 4 32-bit ints with g2_gbytesc()...' - do i = 1, 4 - in44_1(i) = 0 - end do - call g2_gbytesc(out16, in44_1, iskip, 32, 0, 4) - do i = 1, 4 - if (in44_1(i) .ne. in44(i)) stop 160 - end do + ! print *, ' now unpack into 4 32-bit ints with g2_gbytesc()...' + ! do i = 1, 4 + ! in44_1(i) = 0 + ! end do + ! call g2_gbytesc(out16, in44_1, iskip, 32, 0, 4) + ! do i = 1, 4 + ! if (in44_1(i) .ne. in44(i)) stop 160 + ! end do - print *, ' testing g2_sbytec8() with 64-bit int array of size 4...' - do i = 1, 4 - in84(i) = 1 - end do - do i = 1, 32 - out32(i) = char(0) - end do - print *, in84 - call g2_sbytesc8(out32, in84, iskip, 64, 0, 4) - do i = 1, 32 - print '(i3, x, z2.2)', i, out32(i) - end do + ! print *, ' testing g2_sbytec8() with 64-bit int array of size 4...' + ! do i = 1, 4 + ! in84(i) = 1 + ! end do + ! do i = 1, 32 + ! out32(i) = char(0) + ! end do + ! print *, in84 + ! call g2_sbytesc8(out32, in84, iskip, 64, 0, 4) + ! do i = 1, 32 + ! print '(i3, x, z2.2)', i, out32(i) + ! end do - print *, ' now unpack into 4 64-bit ints with g2_gbytesc8()...' - do i = 1, 4 - in84_1(i) = 0 - end do - call g2_gbytesc8(out32, in84_1, iskip, 64, 0, 4) - print *, in84_1 - do i = 1, 4 - if (in84_1(i) .ne. in84(i)) stop 200 - end do + ! print *, ' now unpack into 4 64-bit ints with g2_gbytesc8()...' + ! do i = 1, 4 + ! in84_1(i) = 0 + ! end do + ! call g2_gbytesc8(out32, in84_1, iskip, 64, 0, 4) + ! print *, in84_1 + ! do i = 1, 4 + ! if (in84_1(i) .ne. in84(i)) stop 200 + ! end do print *, ' testing g2_sbytec8() with very large 64-bit int...' ! largest 4 byte signed int, plus 1. in8(1) = 2147483647 + 1 + print '(z16.16)', in8(1) do i = 1, 8 out8(i) = char(0) end do call g2_sbytec8(out8, in8, iskip, 64) do i = 1, 8 print '(z2.2)', out8(i) + if (i .eq. 5) then + if (ichar(out8(i)) .ne. 128) stop 210 + else + if (ichar(out8(i)) .ne. 0) stop 210 + endif end do - print *, ' now unpack into 1 64-bit int with g2_gbytesc8()...' - in8_1(1) = 0 - call g2_gbytesc8(out8, in8_1, iskip, 64, 0, 1) - print *, in8_1 + ! print *, ' now unpack into 1 64-bit int with g2_gbytesc8()...' + ! in8_1(1) = 0 + ! call g2_gbytesc8(out8, in8_1, iskip, 64, 0, 1) + ! print *, in8_1 ! if (in8_1(1) .ne. in8(1)) stop 150 From 85039e0bd01367b2d39a93c67184d893900fe75c Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Wed, 7 Feb 2024 06:51:18 -0700 Subject: [PATCH 07/16] now can pack/unpack 64-bit ints --- src/g2_gbytesc.F90 | 13 +- src/mova2i.c | 36 +++- tests/test_gbytec.F90 | 413 +++++++++++++++++++++--------------------- 3 files changed, 243 insertions(+), 219 deletions(-) diff --git a/src/g2_gbytesc.F90 b/src/g2_gbytesc.F90 index a3e8a1e5..9f62c041 100644 --- a/src/g2_gbytesc.F90 +++ b/src/g2_gbytesc.F90 @@ -126,7 +126,9 @@ subroutine g2_gbytesc8(in, iout, iskip, nbits, nskip, n) integer, parameter :: ones(8) = (/ 1, 3, 7, 15, 31, 63, 127, 255 /) integer :: nbit, i, index, ibit, itmp + integer (kind = 8) :: itmp8, itmp8_2, itmp8_3 integer, external :: mova2i + integer (kind = 8), external :: mova2i8 ! nbit is the start position of the field in bits nbit = iskip @@ -138,25 +140,30 @@ subroutine g2_gbytesc8(in, iout, iskip, nbits, nskip, n) ! first byte tbit = min(bitcnt, 8 - ibit) + itmp8 = iand(mova2i8(in(index)), int(ones(8 - ibit), kind = 8)) itmp = iand(mova2i(in(index)), ones(8 - ibit)) if (tbit .ne. 8 - ibit) itmp = ishft(itmp, tbit - 8 + ibit) + if (tbit .ne. 8 - ibit) itmp8 = ishft(itmp8, tbit - 8 + ibit) index = index + 1 bitcnt = bitcnt - tbit ! now transfer whole bytes do while (bitcnt .ge. 8) itmp = ior(ishft(itmp,8), mova2i(in(index))) + itmp8 = ior(ishft(itmp8,8), mova2i8(in(index))) bitcnt = bitcnt - 8 index = index + 1 enddo ! get data from last byte if (bitcnt .gt. 0) then - itmp = ior(ishft(itmp, bitcnt), iand(ishft(mova2i(in(index)), & - - (8 - bitcnt)), ones(bitcnt))) + itmp = ior(ishft(itmp, bitcnt), iand(ishft(mova2i(in(index)), - (8 - bitcnt)), ones(bitcnt))) + itmp8_2 = ishft(mova2i8(in(index)), int(-(8 - bitcnt), kind(8))) + itmp8_3 = int(ones(bitcnt), kind(8)) + itmp8 = ior(ishft(itmp8, bitcnt), iand(itmp8_2, itmp8_3)) endif - iout(i) = itmp + iout(i) = itmp8 enddo end subroutine g2_gbytesc8 diff --git a/src/mova2i.c b/src/mova2i.c index ee563843..4db7920a 100644 --- a/src/mova2i.c +++ b/src/mova2i.c @@ -1,19 +1,21 @@ /** * @file - * @brief mova2i Moves a bit string from a char*1 to int + * @brief Move bits from a char*1 to an int. * @author Stephen Gilbert @date 2002-08-15 */ /** - * This Function copies a bit string from a Character*1 variable - * to an integer variable. It is intended to replace the Fortran Intrinsic - * Function ICHAR, which only supports 0 <= ICHAR(a) <= 127 on the - * IBM SP. If "a" is greater than 127 in the collating sequence, - * ICHAR(a) does not return the expected bit value. - * This function can be used for all values 0 <= ICHAR(a) <= 255. + * Derefrence char pointer and cast result as 32-bit int. + * + * This function is intended to replace the Fortran Intrinsic Function + * ICHAR, which only supports 0 <= ICHAR(a) <= 127 on the IBM SP. If + * "a" is greater than 127 in the collating sequence, ICHAR(a) does + * not return the expected bit value. This function can be used for + * all values 0 <= ICHAR(a) <= 255. * - * @param[in] a - Character*1 variable that holds the bitstring to extract - * @return - > mova2i - Integer value of the bitstring in character a + * @param a Pointer to char. + * + * @return 32-bit integer containing the value of the bits. * * @author Stephen Gilbert @date 2002-08-15 * */ @@ -21,3 +23,19 @@ int mova2i_(unsigned char *a) { return (int)(*a); } + +/** + * Derefrence char pointer and cast result as 64-bit int. + * + * See mova2i_() for details. + * + * @param a Pointer to char. + * + * @return 64-bit integer containing value of the bits. + * + * @author Ed Hartnett @date Feb 7, 2024 + * */ +int mova2i8_(unsigned char *a) +{ + return (long long int)(*a); +} diff --git a/tests/test_gbytec.F90 b/tests/test_gbytec.F90 index cbbb1e67..627eb66d 100644 --- a/tests/test_gbytec.F90 +++ b/tests/test_gbytec.F90 @@ -32,260 +32,260 @@ program test_gbytec print *, 'Testing g2_gbytesc.F90 subroutines.' - ! print *, ' testing g2_sbytec(), packing one 32-bit int into 8 bits of a char array in big-endian...' - ! in(1) = 3 - ! out(1) = char(0) - ! call g2_sbytec(out, in, iskip, nbits) - ! if (ichar(out(1)) .ne. in(1)) stop 10 - ! print '(z2.2)', out(1) + print *, ' testing g2_sbytec(), packing one 32-bit int into 8 bits of a char array in big-endian...' + in(1) = 3 + out(1) = char(0) + call g2_sbytec(out, in, iskip, nbits) + if (ichar(out(1)) .ne. in(1)) stop 10 + !print '(z2.2)', out(1) - ! print *, ' packing one 32-bit int into 32 bits of a char array in big-endian...' - ! in(1) = 3 - ! do i = 1, 4 - ! out4(i) = char(0) - ! end do - ! call g2_sbytec(out4, in, 0, 32) + print *, ' packing one 32-bit int into 32 bits of a char array in big-endian...' + in(1) = 3 + do i = 1, 4 + out4(i) = char(0) + end do + call g2_sbytec(out4, in, 0, 32) ! do i = 1, 4 ! print '(z2.2)', out4(i) ! end do - ! print *, ' testing g2_gbytec()...' - ! call g2_gbytec(out, in, iskip, nbits) - ! if (ichar(out(1)) .ne. in(1)) stop 11 + print *, ' testing g2_gbytec()...' + call g2_gbytec(out, in, iskip, nbits) + if (ichar(out(1)) .ne. in(1)) stop 11 - ! print *, ' testing g2_sbytesc()...' - ! in(1) = 3 - ! out(1) = char(0) - ! call g2_sbytesc(out, in, iskip, nbits, nskip, n) - ! if (ichar(out(1)) .ne. in(1)) stop 20 + print *, ' testing g2_sbytesc()...' + in(1) = 3 + out(1) = char(0) + call g2_sbytesc(out, in, iskip, nbits, nskip, n) + if (ichar(out(1)) .ne. in(1)) stop 20 - ! ! This will pack the numbers 1 and 2 into the first two chars of the - ! ! buffer. The rest of the output buffer will remain zeros. - ! print *, ' testing g2_sbytesc() packing 2 values...' - ! in2(1) = 1 - ! in2(2) = 2 - ! do i = 1, 8 - ! out8(i) = char(0) - ! end do - ! nbits = 8 - ! call g2_sbytesc(out8, in2, iskip, nbits, nskip, n2) - ! do i = 1, 8 - ! if (i .le. 2) then - ! if (ichar(out8(i)) .ne. in2(i)) stop 30; - ! else - ! if (ichar(out8(i)) .ne. 0) stop 31; - ! endif - ! end do + ! This will pack the numbers 1 and 2 into the first two chars of the + ! buffer. The rest of the output buffer will remain zeros. + print *, ' testing g2_sbytesc() packing 2 values...' + in2(1) = 1 + in2(2) = 2 + do i = 1, 8 + out8(i) = char(0) + end do + nbits = 8 + call g2_sbytesc(out8, in2, iskip, nbits, nskip, n2) + do i = 1, 8 + if (i .le. 2) then + if (ichar(out8(i)) .ne. in2(i)) stop 30; + else + if (ichar(out8(i)) .ne. 0) stop 31; + endif + end do - ! ! Now pack 5 values into the 5 character array out5. - ! print *, ' testing g2_sbytesc() packing 5 values...' - ! in5(1) = 1 - ! in5(2) = 2 - ! in5(3) = 3 - ! in5(4) = 4 - ! in5(5) = 5 - ! nbits = 8 - ! nskip = 0 - ! do i = 1, 5 - ! out5(i) = char(0) - ! end do - ! call g2_sbytesc(out5, in5, iskip, nbits, nskip, n5) - ! do i = 1, 5 - ! if (ichar(out5(i)) .ne. in5(i)) stop 40; - ! end do + ! Now pack 5 values into the 5 character array out5. + print *, ' testing g2_sbytesc() packing 5 values...' + in5(1) = 1 + in5(2) = 2 + in5(3) = 3 + in5(4) = 4 + in5(5) = 5 + nbits = 8 + nskip = 0 + do i = 1, 5 + out5(i) = char(0) + end do + call g2_sbytesc(out5, in5, iskip, nbits, nskip, n5) + do i = 1, 5 + if (ichar(out5(i)) .ne. in5(i)) stop 40; + end do - ! ! Now pack 5 values into the 10 character array out10. Skip every - ! ! other byte in the output. - ! print *, ' testing g2_sbytesc() packing 5 values, skipping every other byte...' - ! nbits = 8 - ! nskip = 0 - ! do i = 1, 10 - ! out10(i) = char(0) - ! end do - ! call g2_sbytesc(out10, in5, iskip, nbits, 8, 5) - ! do i = 1, 10 - ! ! print '(z2.2)', out10(i) - ! if (mod(i, 2) .gt. 0) then - ! if (ichar(out10(i)) .ne. in5(int(i/2) + 1)) stop 51; - ! else - ! if (ichar(out10(i)) .ne. 0) stop 52; - ! endif - ! end do + ! Now pack 5 values into the 10 character array out10. Skip every + ! other byte in the output. + print *, ' testing g2_sbytesc() packing 5 values, skipping every other byte...' + nbits = 8 + nskip = 0 + do i = 1, 10 + out10(i) = char(0) + end do + call g2_sbytesc(out10, in5, iskip, nbits, 8, 5) + do i = 1, 10 + ! print '(z2.2)', out10(i) + if (mod(i, 2) .gt. 0) then + if (ichar(out10(i)) .ne. in5(int(i/2) + 1)) stop 51; + else + if (ichar(out10(i)) .ne. 0) stop 52; + endif + end do - ! print *, ' testing g2_sbytec() with iskip of 1...' - ! in(1) = 1 - ! out(1) = char(0) - ! call g2_sbytec(out, in, 1, 6) - ! if (ichar(out(1)) .ne. 2) stop 53 + print *, ' testing g2_sbytec() with iskip of 1...' + in(1) = 1 + out(1) = char(0) + call g2_sbytec(out, in, 1, 6) + if (ichar(out(1)) .ne. 2) stop 53 - ! print *, ' testing g2_sbytesc() with a size 4 output array...' - ! iskip = 0 - ! nbits = 32 - ! nskip = 0 - ! num = 1 - ! in(1) = 1 - ! call g2_sbytesc(out4, in, iskip, nbits, nskip, num) - ! if (ichar(out4(1)) .ne. 0 .and. ichar(out4(2)) .ne. 0 .and. & - ! ichar(out4(3)) .ne. 0 .and. ichar(out4(4)) .ne. 1) stop 60 + print *, ' testing g2_sbytesc() with a size 4 output array...' + iskip = 0 + nbits = 32 + nskip = 0 + num = 1 + in(1) = 1 + call g2_sbytesc(out4, in, iskip, nbits, nskip, num) + if (ichar(out4(1)) .ne. 0 .and. ichar(out4(2)) .ne. 0 .and. & + ichar(out4(3)) .ne. 0 .and. ichar(out4(4)) .ne. 1) stop 60 - ! print *, ' now unpack into 4 ints with g2_gbytesc()...' - ! call g2_gbytesc(out4, in4, iskip, 8, 0, 4) - ! do i = 1, 4 - ! if (i < 4) then - ! if (in4(i) .ne. 0) stop 61 - ! else - ! if (in4(i) .ne. 1) stop 62 - ! endif - ! end do + print *, ' now unpack into 4 ints with g2_gbytesc()...' + call g2_gbytesc(out4, in4, iskip, 8, 0, 4) + do i = 1, 4 + if (i < 4) then + if (in4(i) .ne. 0) stop 61 + else + if (in4(i) .ne. 1) stop 62 + endif + end do - ! print *, ' now unpack into 1 int with g2_gbytesc()...' - ! call g2_gbytesc(out4, in1, iskip, 32, 0, 1) - ! if (in1(1) .ne. 1) stop 70 + print *, ' now unpack into 1 int with g2_gbytesc()...' + call g2_gbytesc(out4, in1, iskip, 32, 0, 1) + if (in1(1) .ne. 1) stop 70 - ! ! For this test to pass the -fallow-argument-mismatch flag must be - ! ! used, because I am passing in a real array instead of an int array - ! ! for the in parameter. This is how g2_sbytesc() is called in - ! ! addfield.F90. - ! ! print *, ' testing g2_sbytesc() with a real array (size 1) instead of an int array...' - ! ! iskip = 0 - ! ! nbits = 32 - ! ! nskip = 0 - ! ! num = 1 - ! ! r_in(1) = 1 - ! ! call g2_sbytesc(out4, r_in, iskip, nbits, nskip, num) - ! ! ! Note that the 32-bit IEEE representation of 1.0 is 3f800000. The - ! ! ! decimal for 3f is 63, the decimal for 80 is 128. - ! ! if (ichar(out4(1)) .ne. 63 .and. ichar(out4(2)) .ne. 128 .and. & - ! ! ichar(out4(3)) .ne. 0 .and. ichar(out4(4)) .ne. 0) stop 80 - ! ! print '(z2.2)', out4(1) - - ! ! This test is the same as above, but does not require the - ! ! -fallow-argument-mismatch flag. - ! print *, ' testing g2_sbytesc() with a size 1 real array instead of an int array, using transfer()...' + ! For this test to pass the -fallow-argument-mismatch flag must be + ! used, because I am passing in a real array instead of an int array + ! for the in parameter. This is how g2_sbytesc() is called in + ! addfield.F90. + ! print *, ' testing g2_sbytesc() with a real array (size 1) instead of an int array...' ! iskip = 0 ! nbits = 32 ! nskip = 0 ! num = 1 - ! r_in(1) = 1 - ! in = transfer(r_in, in) - ! call g2_sbytesc(out4, in, iskip, nbits, nskip, num) + ! r_in(1) = 1 + ! call g2_sbytesc(out4, r_in, iskip, nbits, nskip, num) ! ! Note that the 32-bit IEEE representation of 1.0 is 3f800000. The ! ! decimal for 3f is 63, the decimal for 80 is 128. ! if (ichar(out4(1)) .ne. 63 .and. ichar(out4(2)) .ne. 128 .and. & - ! ichar(out4(3)) .ne. 0 .and. ichar(out4(4)) .ne. 0) stop 90 + ! ichar(out4(3)) .ne. 0 .and. ichar(out4(4)) .ne. 0) stop 80 + ! print '(z2.2)', out4(1) - ! ! For this test to pass the -fallow-argument-mismatch flag must be - ! ! used, because I am passing in a real array instead of an int array - ! ! for the in parameter. This is how g2_sbytesc() is called in - ! ! addfield.F90. - ! ! print *, ' testing g2_sbytesc() with a real array instead of an int array...' - ! ! iskip = 0 - ! ! nbits = 32 - ! ! nskip = 0 - ! ! num = 2 - ! ! r_in2(1) = 1 - ! ! r_in2(2) = 1 - ! ! call g2_sbytesc(out8, r_in2, iskip, nbits, nskip, num) - ! ! ! Note that the 32-bit IEEE representation of 1.0 is 3f800000. The - ! ! ! decimal for 3f is 63, the decimal for 80 is 128. - ! ! if (ichar(out8(1)) .ne. 63 .and. ichar(out8(2)) .ne. 128 .and. & - ! ! ichar(out8(3)) .ne. 0 .and. ichar(out8(4)) .ne. 0) stop 100 - ! ! if (ichar(out8(5)) .ne. 63 .and. ichar(out8(6)) .ne. 128 .and. & - ! ! ichar(out8(7)) .ne. 0 .and. ichar(out8(8)) .ne. 0) stop 110 - ! ! print '(z2.2)', out8(1) + ! This test is the same as above, but does not require the + ! -fallow-argument-mismatch flag. + print *, ' testing g2_sbytesc() with a size 1 real array instead of an int array, using transfer()...' + iskip = 0 + nbits = 32 + nskip = 0 + num = 1 + r_in(1) = 1 + in = transfer(r_in, in) + call g2_sbytesc(out4, in, iskip, nbits, nskip, num) + ! Note that the 32-bit IEEE representation of 1.0 is 3f800000. The + ! decimal for 3f is 63, the decimal for 80 is 128. + if (ichar(out4(1)) .ne. 63 .and. ichar(out4(2)) .ne. 128 .and. & + ichar(out4(3)) .ne. 0 .and. ichar(out4(4)) .ne. 0) stop 90 - ! ! This test is the same as above, but does not require the -fallow-argument-mismatch flag. - ! print *, ' testing g2_sbytesc() with a real array instead of an int array, using transfer() intrinsic...' + ! For this test to pass the -fallow-argument-mismatch flag must be + ! used, because I am passing in a real array instead of an int array + ! for the in parameter. This is how g2_sbytesc() is called in + ! addfield.F90. + ! print *, ' testing g2_sbytesc() with a real array instead of an int array...' ! iskip = 0 ! nbits = 32 ! nskip = 0 ! num = 2 ! r_in2(1) = 1 ! r_in2(2) = 1 - ! in = transfer(r_in2, in2) - ! call g2_sbytesc(out8, in2, iskip, nbits, nskip, num) + ! call g2_sbytesc(out8, r_in2, iskip, nbits, nskip, num) ! ! Note that the 32-bit IEEE representation of 1.0 is 3f800000. The ! ! decimal for 3f is 63, the decimal for 80 is 128. - ! if (ichar(out4(1)) .ne. 63 .and. ichar(out4(2)) .ne. 128 .and. & - ! ichar(out4(3)) .ne. 0 .and. ichar(out4(4)) .ne. 0) stop 120 + ! if (ichar(out8(1)) .ne. 63 .and. ichar(out8(2)) .ne. 128 .and. & + ! ichar(out8(3)) .ne. 0 .and. ichar(out8(4)) .ne. 0) stop 100 ! if (ichar(out8(5)) .ne. 63 .and. ichar(out8(6)) .ne. 128 .and. & - ! ichar(out8(7)) .ne. 0 .and. ichar(out8(8)) .ne. 0) stop 130 - ! print '(z2.2)', out4(1) + ! ichar(out8(7)) .ne. 0 .and. ichar(out8(8)) .ne. 0) stop 110 + ! print '(z2.2)', out8(1) - ! print *, ' testing g2_sbytec8() with 64-bit int...' - ! in8(1) = 1 - ! do i = 1, 8 - ! out8(i) = char(0) - ! end do - ! call g2_sbytec8(out8, in8, iskip, 64) - ! do i = 1, 8 - ! !print '(z2.2)', out8(i) - ! if (i .lt. 8) then - ! if (ichar(out8(i)) .ne. 0) stop 140 - ! else - ! if (ichar(out8(i)) .ne. 1) stop 140 - ! endif - ! end do + ! This test is the same as above, but does not require the -fallow-argument-mismatch flag. + print *, ' testing g2_sbytesc() with a real array instead of an int array, using transfer() intrinsic...' + iskip = 0 + nbits = 32 + nskip = 0 + num = 2 + r_in2(1) = 1 + r_in2(2) = 1 + in = transfer(r_in2, in2) + call g2_sbytesc(out8, in2, iskip, nbits, nskip, num) + ! Note that the 32-bit IEEE representation of 1.0 is 3f800000. The + ! decimal for 3f is 63, the decimal for 80 is 128. + if (ichar(out4(1)) .ne. 63 .and. ichar(out4(2)) .ne. 128 .and. & + ichar(out4(3)) .ne. 0 .and. ichar(out4(4)) .ne. 0) stop 120 + if (ichar(out8(5)) .ne. 63 .and. ichar(out8(6)) .ne. 128 .and. & + ichar(out8(7)) .ne. 0 .and. ichar(out8(8)) .ne. 0) stop 130 + !print '(z2.2)', out4(1) + + print *, ' testing g2_sbytec8() with 64-bit int...' + in8(1) = 1 + do i = 1, 8 + out8(i) = char(0) + end do + call g2_sbytec8(out8, in8, iskip, 64) + do i = 1, 8 + !print '(z2.2)', out8(i) + if (i .lt. 8) then + if (ichar(out8(i)) .ne. 0) stop 140 + else + if (ichar(out8(i)) .ne. 1) stop 140 + endif + end do - ! print *, ' now unpack into 1 64-bit int with g2_gbytesc()...' - ! in8_1(1) = 0 - ! call g2_gbytesc8(out8, in8_1, iskip, 64, 0, 1) - ! if (in8_1(1) .ne. in8(1)) stop 150 + print *, ' now unpack into 1 64-bit int with g2_gbytesc()...' + in8_1(1) = 0 + call g2_gbytesc8(out8, in8_1, iskip, 64, 0, 1) + if (in8_1(1) .ne. in8(1)) stop 150 - ! print *, ' testing g2_sbytec8() with 32-bit int array of size 4...' - ! do i = 1, 4 - ! in44(i) = 1 - ! end do - ! do i = 1, 16 - ! out16(i) = char(0) - ! end do - ! call g2_sbytesc(out16, in44, iskip, 32, 0, 4) + print *, ' testing g2_sbytec8() with 32-bit int array of size 4...' + do i = 1, 4 + in44(i) = 1 + end do + do i = 1, 16 + out16(i) = char(0) + end do + call g2_sbytesc(out16, in44, iskip, 32, 0, 4) ! do i = 1, 16 ! print '(i3, x, z2.2)', i, out16(i) ! end do - ! print *, ' now unpack into 4 32-bit ints with g2_gbytesc()...' - ! do i = 1, 4 - ! in44_1(i) = 0 - ! end do - ! call g2_gbytesc(out16, in44_1, iskip, 32, 0, 4) - ! do i = 1, 4 - ! if (in44_1(i) .ne. in44(i)) stop 160 - ! end do + print *, ' now unpack into 4 32-bit ints with g2_gbytesc()...' + do i = 1, 4 + in44_1(i) = 0 + end do + call g2_gbytesc(out16, in44_1, iskip, 32, 0, 4) + do i = 1, 4 + if (in44_1(i) .ne. in44(i)) stop 160 + end do - ! print *, ' testing g2_sbytec8() with 64-bit int array of size 4...' - ! do i = 1, 4 - ! in84(i) = 1 - ! end do - ! do i = 1, 32 - ! out32(i) = char(0) - ! end do - ! print *, in84 - ! call g2_sbytesc8(out32, in84, iskip, 64, 0, 4) + print *, ' testing g2_sbytec8() with 64-bit int array of size 4...' + do i = 1, 4 + in84(i) = 1 + end do + do i = 1, 32 + out32(i) = char(0) + end do + !print *, in84 + call g2_sbytesc8(out32, in84, iskip, 64, 0, 4) ! do i = 1, 32 ! print '(i3, x, z2.2)', i, out32(i) ! end do - ! print *, ' now unpack into 4 64-bit ints with g2_gbytesc8()...' - ! do i = 1, 4 - ! in84_1(i) = 0 - ! end do - ! call g2_gbytesc8(out32, in84_1, iskip, 64, 0, 4) - ! print *, in84_1 - ! do i = 1, 4 - ! if (in84_1(i) .ne. in84(i)) stop 200 - ! end do + print *, ' now unpack into 4 64-bit ints with g2_gbytesc8()...' + do i = 1, 4 + in84_1(i) = 0 + end do + call g2_gbytesc8(out32, in84_1, iskip, 64, 0, 4) + !print *, in84_1 + do i = 1, 4 + if (in84_1(i) .ne. in84(i)) stop 200 + end do print *, ' testing g2_sbytec8() with very large 64-bit int...' ! largest 4 byte signed int, plus 1. in8(1) = 2147483647 + 1 - print '(z16.16)', in8(1) + !print '(z16.16)', in8(1) do i = 1, 8 out8(i) = char(0) end do call g2_sbytec8(out8, in8, iskip, 64) do i = 1, 8 - print '(z2.2)', out8(i) + !print '(z2.2)', out8(i) if (i .eq. 5) then if (ichar(out8(i)) .ne. 128) stop 210 else @@ -293,12 +293,11 @@ program test_gbytec endif end do - ! print *, ' now unpack into 1 64-bit int with g2_gbytesc8()...' - ! in8_1(1) = 0 - ! call g2_gbytesc8(out8, in8_1, iskip, 64, 0, 1) - ! print *, in8_1 -! if (in8_1(1) .ne. in8(1)) stop 150 - + print *, ' now unpack into 1 64-bit int with g2_gbytesc8()...' + in8_1(1) = 0 + call g2_gbytesc8(out8, in8_1, iskip, 64, 0, 1) + !print *, in8_1 + if (in8_1(1) .ne. in8(1)) stop 150 print *, 'SUCCESS!' From 3a9e0269ea7709108b7862fd67f0e78b4f00da7a Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Wed, 7 Feb 2024 06:56:49 -0700 Subject: [PATCH 08/16] now can pack/unpack 64-bit ints --- tests/test_gbytec.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_gbytec.F90 b/tests/test_gbytec.F90 index 627eb66d..3d5c9c42 100644 --- a/tests/test_gbytec.F90 +++ b/tests/test_gbytec.F90 @@ -285,7 +285,7 @@ program test_gbytec end do call g2_sbytec8(out8, in8, iskip, 64) do i = 1, 8 - !print '(z2.2)', out8(i) + print '(z2.2)', out8(i) if (i .eq. 5) then if (ichar(out8(i)) .ne. 128) stop 210 else From a9bd392ab4fc3e7d1dc2e3599ad62f31904d70e0 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Wed, 7 Feb 2024 07:02:16 -0700 Subject: [PATCH 09/16] now can pack/unpack 64-bit ints --- tests/test_gbytec.F90 | 55 ++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/tests/test_gbytec.F90 b/tests/test_gbytec.F90 index 3d5c9c42..7accc650 100644 --- a/tests/test_gbytec.F90 +++ b/tests/test_gbytec.F90 @@ -29,6 +29,7 @@ program test_gbytec integer :: num integer(kind = 4) :: in44(4), in44_1(4) integer(kind = 8) :: in8(1), in8_1(1), in84(4), in84_1(4) + integer, external :: mova2i print *, 'Testing g2_gbytesc.F90 subroutines.' @@ -36,7 +37,7 @@ program test_gbytec in(1) = 3 out(1) = char(0) call g2_sbytec(out, in, iskip, nbits) - if (ichar(out(1)) .ne. in(1)) stop 10 + if (mova2i(out(1)) .ne. in(1)) stop 10 !print '(z2.2)', out(1) print *, ' packing one 32-bit int into 32 bits of a char array in big-endian...' @@ -51,13 +52,13 @@ program test_gbytec print *, ' testing g2_gbytec()...' call g2_gbytec(out, in, iskip, nbits) - if (ichar(out(1)) .ne. in(1)) stop 11 + if (mova2i(out(1)) .ne. in(1)) stop 11 print *, ' testing g2_sbytesc()...' in(1) = 3 out(1) = char(0) call g2_sbytesc(out, in, iskip, nbits, nskip, n) - if (ichar(out(1)) .ne. in(1)) stop 20 + if (mova2i(out(1)) .ne. in(1)) stop 20 ! This will pack the numbers 1 and 2 into the first two chars of the ! buffer. The rest of the output buffer will remain zeros. @@ -71,9 +72,9 @@ program test_gbytec call g2_sbytesc(out8, in2, iskip, nbits, nskip, n2) do i = 1, 8 if (i .le. 2) then - if (ichar(out8(i)) .ne. in2(i)) stop 30; + if (mova2i(out8(i)) .ne. in2(i)) stop 30; else - if (ichar(out8(i)) .ne. 0) stop 31; + if (mova2i(out8(i)) .ne. 0) stop 31; endif end do @@ -91,7 +92,7 @@ program test_gbytec end do call g2_sbytesc(out5, in5, iskip, nbits, nskip, n5) do i = 1, 5 - if (ichar(out5(i)) .ne. in5(i)) stop 40; + if (mova2i(out5(i)) .ne. in5(i)) stop 40; end do ! Now pack 5 values into the 10 character array out10. Skip every @@ -106,9 +107,9 @@ program test_gbytec do i = 1, 10 ! print '(z2.2)', out10(i) if (mod(i, 2) .gt. 0) then - if (ichar(out10(i)) .ne. in5(int(i/2) + 1)) stop 51; + if (mova2i(out10(i)) .ne. in5(int(i/2) + 1)) stop 51; else - if (ichar(out10(i)) .ne. 0) stop 52; + if (mova2i(out10(i)) .ne. 0) stop 52; endif end do @@ -116,7 +117,7 @@ program test_gbytec in(1) = 1 out(1) = char(0) call g2_sbytec(out, in, 1, 6) - if (ichar(out(1)) .ne. 2) stop 53 + if (mova2i(out(1)) .ne. 2) stop 53 print *, ' testing g2_sbytesc() with a size 4 output array...' iskip = 0 @@ -125,8 +126,8 @@ program test_gbytec num = 1 in(1) = 1 call g2_sbytesc(out4, in, iskip, nbits, nskip, num) - if (ichar(out4(1)) .ne. 0 .and. ichar(out4(2)) .ne. 0 .and. & - ichar(out4(3)) .ne. 0 .and. ichar(out4(4)) .ne. 1) stop 60 + if (mova2i(out4(1)) .ne. 0 .and. mova2i(out4(2)) .ne. 0 .and. & + mova2i(out4(3)) .ne. 0 .and. mova2i(out4(4)) .ne. 1) stop 60 print *, ' now unpack into 4 ints with g2_gbytesc()...' call g2_gbytesc(out4, in4, iskip, 8, 0, 4) @@ -155,8 +156,8 @@ program test_gbytec ! call g2_sbytesc(out4, r_in, iskip, nbits, nskip, num) ! ! Note that the 32-bit IEEE representation of 1.0 is 3f800000. The ! ! decimal for 3f is 63, the decimal for 80 is 128. - ! if (ichar(out4(1)) .ne. 63 .and. ichar(out4(2)) .ne. 128 .and. & - ! ichar(out4(3)) .ne. 0 .and. ichar(out4(4)) .ne. 0) stop 80 + ! if (mova2i(out4(1)) .ne. 63 .and. mova2i(out4(2)) .ne. 128 .and. & + ! mova2i(out4(3)) .ne. 0 .and. mova2i(out4(4)) .ne. 0) stop 80 ! print '(z2.2)', out4(1) ! This test is the same as above, but does not require the @@ -171,8 +172,8 @@ program test_gbytec call g2_sbytesc(out4, in, iskip, nbits, nskip, num) ! Note that the 32-bit IEEE representation of 1.0 is 3f800000. The ! decimal for 3f is 63, the decimal for 80 is 128. - if (ichar(out4(1)) .ne. 63 .and. ichar(out4(2)) .ne. 128 .and. & - ichar(out4(3)) .ne. 0 .and. ichar(out4(4)) .ne. 0) stop 90 + if (mova2i(out4(1)) .ne. 63 .and. mova2i(out4(2)) .ne. 128 .and. & + mova2i(out4(3)) .ne. 0 .and. mova2i(out4(4)) .ne. 0) stop 90 ! For this test to pass the -fallow-argument-mismatch flag must be ! used, because I am passing in a real array instead of an int array @@ -188,10 +189,10 @@ program test_gbytec ! call g2_sbytesc(out8, r_in2, iskip, nbits, nskip, num) ! ! Note that the 32-bit IEEE representation of 1.0 is 3f800000. The ! ! decimal for 3f is 63, the decimal for 80 is 128. - ! if (ichar(out8(1)) .ne. 63 .and. ichar(out8(2)) .ne. 128 .and. & - ! ichar(out8(3)) .ne. 0 .and. ichar(out8(4)) .ne. 0) stop 100 - ! if (ichar(out8(5)) .ne. 63 .and. ichar(out8(6)) .ne. 128 .and. & - ! ichar(out8(7)) .ne. 0 .and. ichar(out8(8)) .ne. 0) stop 110 + ! if (mova2i(out8(1)) .ne. 63 .and. mova2i(out8(2)) .ne. 128 .and. & + ! mova2i(out8(3)) .ne. 0 .and. mova2i(out8(4)) .ne. 0) stop 100 + ! if (mova2i(out8(5)) .ne. 63 .and. mova2i(out8(6)) .ne. 128 .and. & + ! mova2i(out8(7)) .ne. 0 .and. mova2i(out8(8)) .ne. 0) stop 110 ! print '(z2.2)', out8(1) ! This test is the same as above, but does not require the -fallow-argument-mismatch flag. @@ -206,10 +207,10 @@ program test_gbytec call g2_sbytesc(out8, in2, iskip, nbits, nskip, num) ! Note that the 32-bit IEEE representation of 1.0 is 3f800000. The ! decimal for 3f is 63, the decimal for 80 is 128. - if (ichar(out4(1)) .ne. 63 .and. ichar(out4(2)) .ne. 128 .and. & - ichar(out4(3)) .ne. 0 .and. ichar(out4(4)) .ne. 0) stop 120 - if (ichar(out8(5)) .ne. 63 .and. ichar(out8(6)) .ne. 128 .and. & - ichar(out8(7)) .ne. 0 .and. ichar(out8(8)) .ne. 0) stop 130 + if (mova2i(out4(1)) .ne. 63 .and. mova2i(out4(2)) .ne. 128 .and. & + mova2i(out4(3)) .ne. 0 .and. mova2i(out4(4)) .ne. 0) stop 120 + if (mova2i(out8(5)) .ne. 63 .and. mova2i(out8(6)) .ne. 128 .and. & + mova2i(out8(7)) .ne. 0 .and. mova2i(out8(8)) .ne. 0) stop 130 !print '(z2.2)', out4(1) print *, ' testing g2_sbytec8() with 64-bit int...' @@ -221,9 +222,9 @@ program test_gbytec do i = 1, 8 !print '(z2.2)', out8(i) if (i .lt. 8) then - if (ichar(out8(i)) .ne. 0) stop 140 + if (mova2i(out8(i)) .ne. 0) stop 140 else - if (ichar(out8(i)) .ne. 1) stop 140 + if (mova2i(out8(i)) .ne. 1) stop 140 endif end do @@ -287,9 +288,9 @@ program test_gbytec do i = 1, 8 print '(z2.2)', out8(i) if (i .eq. 5) then - if (ichar(out8(i)) .ne. 128) stop 210 + if (mova2i(out8(i)) .ne. 128) stop 210 else - if (ichar(out8(i)) .ne. 0) stop 210 + if (mova2i(out8(i)) .ne. 0) stop 210 endif end do From 0b7b35a4e3f8236da5e3a21219d32c1af7ffb850 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Wed, 7 Feb 2024 08:12:16 -0700 Subject: [PATCH 10/16] now can pack/unpack 64-bit ints --- tests/test_gbytec.F90 | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/tests/test_gbytec.F90 b/tests/test_gbytec.F90 index 7accc650..11198488 100644 --- a/tests/test_gbytec.F90 +++ b/tests/test_gbytec.F90 @@ -277,28 +277,28 @@ program test_gbytec if (in84_1(i) .ne. in84(i)) stop 200 end do - print *, ' testing g2_sbytec8() with very large 64-bit int...' - ! largest 4 byte signed int, plus 1. - in8(1) = 2147483647 + 1 - !print '(z16.16)', in8(1) - do i = 1, 8 - out8(i) = char(0) - end do - call g2_sbytec8(out8, in8, iskip, 64) - do i = 1, 8 - print '(z2.2)', out8(i) - if (i .eq. 5) then - if (mova2i(out8(i)) .ne. 128) stop 210 - else - if (mova2i(out8(i)) .ne. 0) stop 210 - endif - end do + ! print *, ' testing g2_sbytec8() with very large 64-bit int...' + ! ! largest 4 byte signed int, plus 1. + ! in8(1) = 2147483647 + 1 + ! !print '(z16.16)', in8(1) + ! do i = 1, 8 + ! out8(i) = char(0) + ! end do + ! call g2_sbytec8(out8, in8, iskip, 64) + ! do i = 1, 8 + ! print '(z2.2)', out8(i) + ! if (i .eq. 5) then + ! if (mova2i(out8(i)) .ne. 128) stop 210 + ! else + ! if (mova2i(out8(i)) .ne. 0) stop 210 + ! endif + ! end do - print *, ' now unpack into 1 64-bit int with g2_gbytesc8()...' - in8_1(1) = 0 - call g2_gbytesc8(out8, in8_1, iskip, 64, 0, 1) - !print *, in8_1 - if (in8_1(1) .ne. in8(1)) stop 150 + ! print *, ' now unpack into 1 64-bit int with g2_gbytesc8()...' + ! in8_1(1) = 0 + ! call g2_gbytesc8(out8, in8_1, iskip, 64, 0, 1) + ! !print *, in8_1 + ! if (in8_1(1) .ne. in8(1)) stop 150 print *, 'SUCCESS!' From e4b2ac5e33db1a83904353fabe90f6f57201b0e2 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Wed, 7 Feb 2024 08:21:14 -0700 Subject: [PATCH 11/16] debugging intel problem --- tests/test_gbytec.F90 | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/test_gbytec.F90 b/tests/test_gbytec.F90 index 11198488..7b6f3b93 100644 --- a/tests/test_gbytec.F90 +++ b/tests/test_gbytec.F90 @@ -277,22 +277,22 @@ program test_gbytec if (in84_1(i) .ne. in84(i)) stop 200 end do - ! print *, ' testing g2_sbytec8() with very large 64-bit int...' - ! ! largest 4 byte signed int, plus 1. - ! in8(1) = 2147483647 + 1 - ! !print '(z16.16)', in8(1) - ! do i = 1, 8 - ! out8(i) = char(0) - ! end do - ! call g2_sbytec8(out8, in8, iskip, 64) - ! do i = 1, 8 - ! print '(z2.2)', out8(i) - ! if (i .eq. 5) then - ! if (mova2i(out8(i)) .ne. 128) stop 210 - ! else - ! if (mova2i(out8(i)) .ne. 0) stop 210 - ! endif - ! end do + print *, ' testing g2_sbytec8() with very large 64-bit int...' + ! largest 4 byte signed int, plus 1. + in8(1) = 2147483647 + 1 + !print '(z16.16)', in8(1) + do i = 1, 8 + out8(i) = char(0) + end do + call g2_sbytec8(out8, in8, iskip, 64) + do i = 1, 8 + print '(z2.2)', out8(i) + if (i .eq. 5) then + if (mova2i(out8(i)) .ne. 128) stop 210 + else + if (mova2i(out8(i)) .ne. 0) stop 210 + endif + end do ! print *, ' now unpack into 1 64-bit int with g2_gbytesc8()...' ! in8_1(1) = 0 From 3f7c0a94044a8bc40aaeac6798d4e55624c0841a Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Wed, 7 Feb 2024 08:55:58 -0700 Subject: [PATCH 12/16] debugging intel problem --- tests/test_gbytec.F90 | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/test_gbytec.F90 b/tests/test_gbytec.F90 index 7b6f3b93..11198488 100644 --- a/tests/test_gbytec.F90 +++ b/tests/test_gbytec.F90 @@ -277,22 +277,22 @@ program test_gbytec if (in84_1(i) .ne. in84(i)) stop 200 end do - print *, ' testing g2_sbytec8() with very large 64-bit int...' - ! largest 4 byte signed int, plus 1. - in8(1) = 2147483647 + 1 - !print '(z16.16)', in8(1) - do i = 1, 8 - out8(i) = char(0) - end do - call g2_sbytec8(out8, in8, iskip, 64) - do i = 1, 8 - print '(z2.2)', out8(i) - if (i .eq. 5) then - if (mova2i(out8(i)) .ne. 128) stop 210 - else - if (mova2i(out8(i)) .ne. 0) stop 210 - endif - end do + ! print *, ' testing g2_sbytec8() with very large 64-bit int...' + ! ! largest 4 byte signed int, plus 1. + ! in8(1) = 2147483647 + 1 + ! !print '(z16.16)', in8(1) + ! do i = 1, 8 + ! out8(i) = char(0) + ! end do + ! call g2_sbytec8(out8, in8, iskip, 64) + ! do i = 1, 8 + ! print '(z2.2)', out8(i) + ! if (i .eq. 5) then + ! if (mova2i(out8(i)) .ne. 128) stop 210 + ! else + ! if (mova2i(out8(i)) .ne. 0) stop 210 + ! endif + ! end do ! print *, ' now unpack into 1 64-bit int with g2_gbytesc8()...' ! in8_1(1) = 0 From 165e9d0eb765d62435a6d948e791ab58616015ab Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Wed, 7 Feb 2024 09:39:37 -0700 Subject: [PATCH 13/16] debugging intel problem --- tests/test_gbytec.F90 | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/test_gbytec.F90 b/tests/test_gbytec.F90 index 11198488..7b6f3b93 100644 --- a/tests/test_gbytec.F90 +++ b/tests/test_gbytec.F90 @@ -277,22 +277,22 @@ program test_gbytec if (in84_1(i) .ne. in84(i)) stop 200 end do - ! print *, ' testing g2_sbytec8() with very large 64-bit int...' - ! ! largest 4 byte signed int, plus 1. - ! in8(1) = 2147483647 + 1 - ! !print '(z16.16)', in8(1) - ! do i = 1, 8 - ! out8(i) = char(0) - ! end do - ! call g2_sbytec8(out8, in8, iskip, 64) - ! do i = 1, 8 - ! print '(z2.2)', out8(i) - ! if (i .eq. 5) then - ! if (mova2i(out8(i)) .ne. 128) stop 210 - ! else - ! if (mova2i(out8(i)) .ne. 0) stop 210 - ! endif - ! end do + print *, ' testing g2_sbytec8() with very large 64-bit int...' + ! largest 4 byte signed int, plus 1. + in8(1) = 2147483647 + 1 + !print '(z16.16)', in8(1) + do i = 1, 8 + out8(i) = char(0) + end do + call g2_sbytec8(out8, in8, iskip, 64) + do i = 1, 8 + print '(z2.2)', out8(i) + if (i .eq. 5) then + if (mova2i(out8(i)) .ne. 128) stop 210 + else + if (mova2i(out8(i)) .ne. 0) stop 210 + endif + end do ! print *, ' now unpack into 1 64-bit int with g2_gbytesc8()...' ! in8_1(1) = 0 From 77c25caba1fe80a0acd36e601612d119c807b24e Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Wed, 7 Feb 2024 09:49:03 -0700 Subject: [PATCH 14/16] debugging intel problem --- src/g2_gbytesc.F90 | 4 ++-- tests/test_gbytec.F90 | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/g2_gbytesc.F90 b/src/g2_gbytesc.F90 index 9f62c041..de9f69bc 100644 --- a/src/g2_gbytesc.F90 +++ b/src/g2_gbytesc.F90 @@ -313,14 +313,14 @@ subroutine g2_sbytesc8(out, in, iskip, nbits, nskip, n) ! number bits from zero to ... ! nbit is the last bit of the field to be filled nbit = iskip + nbits - 1 - !print *, 'nbit', nbit, 'nbits ', nbits, 'nskip', nskip, 'n', n + print *, 'nbit', nbit, 'nbits ', nbits, 'nskip', nskip, 'n', n do i = 1, n itmp8 = in(i) bitcnt = nbits index = nbit / 8 + 1 ibit = mod(nbit, 8) nbit = nbit + nbits + nskip - !print *, 'i', i, 'itmp8', itmp8, 'bitcnt', bitcnt, 'index', index, 'ibit', ibit, 'nbit', nbit + print *, 'i', i, 'itmp8', itmp8, 'bitcnt', bitcnt, 'index', index, 'ibit', ibit, 'nbit', nbit ! make byte aligned if (ibit .ne. 7) then diff --git a/tests/test_gbytec.F90 b/tests/test_gbytec.F90 index 7b6f3b93..c13d3df2 100644 --- a/tests/test_gbytec.F90 +++ b/tests/test_gbytec.F90 @@ -280,7 +280,7 @@ program test_gbytec print *, ' testing g2_sbytec8() with very large 64-bit int...' ! largest 4 byte signed int, plus 1. in8(1) = 2147483647 + 1 - !print '(z16.16)', in8(1) + print '(z16.16)', in8(1) do i = 1, 8 out8(i) = char(0) end do From 0a2d31641456f6f51698e7cbbd7571a895a29206 Mon Sep 17 00:00:00 2001 From: Ed Date: Wed, 7 Feb 2024 10:17:50 -0700 Subject: [PATCH 15/16] more intel debugging --- tests/test_gbytec.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_gbytec.F90 b/tests/test_gbytec.F90 index c13d3df2..923b7123 100644 --- a/tests/test_gbytec.F90 +++ b/tests/test_gbytec.F90 @@ -279,7 +279,7 @@ program test_gbytec print *, ' testing g2_sbytec8() with very large 64-bit int...' ! largest 4 byte signed int, plus 1. - in8(1) = 2147483647 + 1 + in8(1) = 2147483647_8 + 1_8 print '(z16.16)', in8(1) do i = 1, 8 out8(i) = char(0) From a6e42cdfc4f7f3087562b5ed837fd54a25d92323 Mon Sep 17 00:00:00 2001 From: Ed Date: Wed, 7 Feb 2024 10:25:00 -0700 Subject: [PATCH 16/16] more intel debugging --- tests/test_gbytec.F90 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/test_gbytec.F90 b/tests/test_gbytec.F90 index 923b7123..57880236 100644 --- a/tests/test_gbytec.F90 +++ b/tests/test_gbytec.F90 @@ -294,11 +294,11 @@ program test_gbytec endif end do - ! print *, ' now unpack into 1 64-bit int with g2_gbytesc8()...' - ! in8_1(1) = 0 - ! call g2_gbytesc8(out8, in8_1, iskip, 64, 0, 1) - ! !print *, in8_1 - ! if (in8_1(1) .ne. in8(1)) stop 150 + print *, ' now unpack into 1 64-bit int with g2_gbytesc8()...' + in8_1(1) = 0 + call g2_gbytesc8(out8, in8_1, iskip, 64, 0, 1) + !print *, in8_1 + if (in8_1(1) .ne. in8(1)) stop 150 print *, 'SUCCESS!'