forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

PACK function
Goto page 1, 2  Next
 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support
View previous topic :: View next topic  
Author Message
Martin_K



Joined: 09 Apr 2020
Posts: 227

PostPosted: Sat Mar 06, 2021 12:49 pm    Post subject: PACK function Reply with quote

Hello,

I have a large one-dimensional array consisting of about 2000 elements, most of them has ZERO values and only small part of them contains NON-zero value: I need to extract from it the NON-zero values only.

So, I used the PACK function with mask as follows:

Code:

...
INTEGER, ALLOCATABLE :: D(:)
...

IF (.not. ALLOCATED (D)) ALLOCATE (D(en))

d=pack(up,mask=up.ne.0)

....


The number of non-zero elements (en) is found in a procedure preceding the call to the PACK function.

Basically, the PACK function works fine and I get the array D(en) with non-zero values only, which becomes then an one-dimensional array with 20 non-zero values only.

If I create a release EXE version - it runs (apart from a problem with DRAW_POLYLINED@ which does not join the lines).

However, when I check the /UNDEF option for debugging and run the debug process - the debugger says:

RUN-TIME error 112. Reference to undefined variable, array element or function result (/UNDEF) and points to the newly created one-dimensional array with 20 elements (array named UP in the code above).

My question is: when I use the PACK function, it creates a new array of the same dimension (one dimension with 20 non-zero elements in my case) and the rest zero elements are disregarded (I suppose so) or not
and still keeps the information about the original input array (in my case - one-dimensional array named UP with 2000 elements)?

Thanks!

Martin
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Sat Mar 06, 2021 1:21 pm    Post subject: Reply with quote

Martin

Can you demonstrate the runtime error in a short program and post it here?
Back to top
View user's profile Send private message AIM Address
Martin_K



Joined: 09 Apr 2020
Posts: 227

PostPosted: Sat Mar 06, 2021 8:45 pm    Post subject: Reply with quote

Paul,

here is the link to download main program and the module along with the input data file:
https://www.dropbox.com/h?preview=TEST_PACK_FUNCTION.zip

I also included two JPG screen shots, one with RUN-TIME error message and the other one with a look in compiler options in my PLATO test project
for this purpose.

I repeat once again, when I uncheck the option CHECK FOR UNDEFINED VARIABLES, the program runs problem free both in RELEASE/X64 and DEBUG/X64 (the results are output to the screen and are correct).
As soon as I check the above mentioned option, the program crashes in both variants (release and debug).

I think, when this will be explained, where I am wrong, it could have the connection to my problem with DRAW_POLYLINED@.

DO not forget to setup the option UNICODE UTF8 without signature, when you load in both files into a PLATO project. The OC_points.TXT file with the input data is also attached to test the problem on real data.
Back to top
View user's profile Send private message
Martin_K



Joined: 09 Apr 2020
Posts: 227

PostPosted: Sat Mar 06, 2021 9:55 pm    Post subject: Reply with quote

Something went wrong with the previous link - here is once again:

https://www.dropbox.com/s/etoj5vrfjsxrv9r/TEST_PACK_FUNCTION.zip?dl=0
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Sun Mar 07, 2021 6:02 am    Post subject: Reply with quote

The use of PACK in Fortran 90/95 has some limitations, as there is no report of the extent of D that has been used.

for your statement:
d=pack(up,mask=up.ne.0)

What part of D has been initialised ?
Also, was UP initialised ?

It is probably easier not to use PACK and just keep a list of active points as they are reviewed.

In F03, using PACK with auto-allocate, it works much better using:
INTEGER, ALLOCATABLE :: D(:)
D=pack(up,mask=up.ne.0) ; num = size (D)

Imagine the problems if UP was real !!
Back to top
View user's profile Send private message
Martin_K



Joined: 09 Apr 2020
Posts: 227

PostPosted: Sun Mar 07, 2021 10:25 am    Post subject: Reply with quote

Thanks John.

I initialised neither D nor UP. Now, I did so (all elements of both arrays are
after initialising equal zero), but the symptoms
are the same (when CHECK FOR UNDEFINED VARIABLE is active,
program crashes, without this checking, program runs fine).
Back to top
View user's profile Send private message
Kenneth_Smith



Joined: 18 May 2012
Posts: 697
Location: Hamilton, Lanarkshire, Scotland.

PostPosted: Sun Mar 07, 2021 1:22 pm    Post subject: Reply with quote

Paul,

I think there may be an issue with allocate on assignment for logical arrays. The following code does not behave as expected:

Code:
program t
implicit none
integer, parameter :: dp=kind(1.d0)
integer, parameter :: n = 20
real(kind=dp) a(1:n)
logical, allocatable :: mask(:)
real(kind=dp), allocatable :: copy_a(:)

integer i, counter

a = 0.d0
do i = 1, n, 5
  call random_number(a(i))
end do

do i = 1, n ; print*, i, a(i) ; end do

counter = 0
do i = 1, n
  if ( a(i) .ne. 0.d0) counter = counter + 1
end do
print*
print*, 'No of non-zero entries ', counter

mask = (a .ne. 0.d0)   !Allocate mask on assignment
print*
print*, 'Size of auto-allocated mask array', size(mask)   

copy_a = a
print*
print*, 'Size of auto-allocated copy of a', size(copy_a)
end program t

!Size(mask):-
!Checkmate + Win32 returns 0
!Release   + Win32 fails on access violation
!Checkmate + x64 returns 0
!Release   + x64 fails on access violation
!
!Alternative compiler returns 20 as expected.



This may be relevant to the issue that Martin is experiencing.

PS Curiosity got the better of me. It appears there are issues with allocate on assignment for complex arrays:-

Code:
program t
implicit none
integer, parameter :: dp=kind(1.d0)
complex(kind=dp) :: mat(1:3,1:3)
complex(kind=dp), allocatable :: mat_c(:,:)
integer i

!Create matrix with j on main diagonal, zero otherwise
mat = 0.d0
do i = 1, 3, 1
  mat(i,i) = cmplx(0.d0,1.d0,kind=dp)
end do

print*, mat

mat_c = mat

print*
print*, mat_c

end program t

! Checkmate + Win32  "Nonconformant arrays"
! Release + Win32    Process hangs
! Checkmate + X64    "Nonconformant arrays"
! Release + X64      OK
Back to top
View user's profile Send private message Visit poster's website
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Sun Mar 07, 2021 3:09 pm    Post subject: Reply with quote

Martin

John has pointed out that the arrays must be initialised. Also D must have the right number of elements.

en has the correct value which is COUNT(up.ne.0) but this must be the current size of D. So you could write...

Code:
           
     IF(ALLOCATED(D)) DEALLOCATE(D)
     ALLOCATE (D(en))
     D = 0
Back to top
View user's profile Send private message AIM Address
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Sun Mar 07, 2021 3:27 pm    Post subject: Reply with quote

Ken

Thank you for the feedback. I have made a note of that allocate on assignment does not work in these cases.
Back to top
View user's profile Send private message AIM Address
Martin_K



Joined: 09 Apr 2020
Posts: 227

PostPosted: Sun Mar 07, 2021 4:22 pm    Post subject: Reply with quote

Thanks guys for your comments.

Paul,

I did exactly what John said:

Code:

IF (.not. ALLOCATED (D)) ALLOCATE (D(en))
D(en)=0

print*,d
pause

d=pack(up,mask=up.ne.0)


The same I did for the UP(K).

The result can be seen here (in yellow are the D(en) values after initialisation. Their number is correct and also - after executing
the PACK commad (last three lines in the picture below), the number
of D(en) values is correct and filled up with correct values.



Nevertheless, it does not help, the symptoms remain
the same (program crashes when using /UNDEF option).

An additional observation: Originally, I used for initialisation
the commands UP = 0 and D = 0.

When I run the program after such initialisation, when I want to print the values UP(k) and D(en), it displays only the UP values and exits automatically, although after every initialisation I use the PAUSE command. It also should display D values. It displays them
(the initialised D values) for a second and program ends automattically,
although I also used the PAUSE command after the PACK function, when
it is executed.

Therefore I used UP(K) = 0 and D(en) = 0, instead of UP = 0 and D = 0.
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Sun Mar 07, 2021 5:07 pm    Post subject: Reply with quote

Martin

It works for me but with the changes that I have recommended.

UP(K) = 0 sets just one element to zero whilst UP = 0 sets all the array values to zero.

Also the array D must be the right size which is why I have suggested that you you deallocate D and re-allocate to the current size.
Back to top
View user's profile Send private message AIM Address
Martin_K



Joined: 09 Apr 2020
Posts: 227

PostPosted: Sun Mar 07, 2021 5:08 pm    Post subject: Reply with quote

I forgot to mention that I also used the Paulīs alternative:

Code:

IF (ALLOCATED (D)) DEALLOCATE (D)
ALLOCATE (D(en))

D(en)=0


All results and behaviour are exactly the same as in my alternative:

Code:

IF (.not. ALLOCATED (D)) ALLOCATE (D(en))
D(en)=0
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Sun Mar 07, 2021 5:11 pm    Post subject: Reply with quote

Martin

Our posts may have crossed.

D(en) = 0 is not the same as D = 0.
Back to top
View user's profile Send private message AIM Address
Martin_K



Joined: 09 Apr 2020
Posts: 227

PostPosted: Sun Mar 07, 2021 5:53 pm    Post subject: Reply with quote

Paul,

here are two 20s videos that demonstrate what I wrote
about D = 0 and D(en) =0:

https://www.dropbox.com/s/d4bdgz81hd9by5f/videos.zip?dl=0

Simply, when I use D=0, program ignores the PAUSE command located immediately after initialisation
D=0 and PRINT*,D command
Code:

IF (ALLOCATED (D)) DEALLOCATE (D)
ALLOCATE (D(en))
D=0
print*,d
pause

d=pack(up,mask=up.ne.0) ! to select ONLY the points with NON-ZERO values

print*,'Now - below - follows D(en) array correctly filled up with correct NON-ZERO values:'
print*,d
pause


and neither displays the PACK results, nor wait for pressing END, simply ends automatically without any intervention.

When I use (D(en) = 0 because D=0 does not work well with me, you say that only one element (which one of 20 elements?) has assigned the ZERO value. But as can be seen in one of my video, after such assignment (D(en) = 0) all 20 elements have assigned ZERO values. Or am I wrong?

Moreover, even when I use your alternative method for allocation with /UNDEF option, program always crashes. Both things are mystery for me.
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Sun Mar 07, 2021 9:19 pm    Post subject: Reply with quote

Martin

Try running the debugger SDBG or SDBG64. Set a break point at the point you talk about and then look at the array elements.
Back to top
View user's profile Send private message AIM Address
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support All times are GMT + 1 Hour
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group