Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29274 Discussions

Checking for changes in a data structure

acar
Beginner
660 Views
I've asked a question on this previously but have not really managed to find a simple effective way of doing this. So I shall pose a slightly different question:
What I need is a simple effective way of checking whether the data in a type structure has been changed by a routine. I've tried checksums but they are not reliable as two different sets of data can produce the same checksum, i.e. the mapping is not necessarily unique.
It seems to me that if I could convert my data (before and after editing) into binary then I could do a bit by bit check to see if any change had occurred. In looking in the Fortran help I don't seem to come across any routines that would help me in implementing this.
Does anyone know of how I could implement this idea?
Thanks, ACAR.
0 Kudos
8 Replies
anthonyrichards
New Contributor III
660 Views
If it just a question of knowing whether the routine use and/or tinkered with the data, then why not supply a flag for the routine to set according to what it did to the data? Put your flags in a module that follows the data through your code and USE it wherever you need to check on the data's status.

More difficult I presume is the case where, when you say 'changed', you mean that even though data within the structure may have been accessed, used and manipulated within the routine, the actual values remain or were reset exactly to their original values? In which case the routine would have played with the values and - perhaps unknowingly - left the data overall unchanged. Short of have the routine make a temporary copy and then test the final data on exit against it byte by byte and setting a flag according to the result, I do not see how it can easily be done.
0 Kudos
mecej4
Honored Contributor III
660 Views
It would be useful for you to disclose what you want to do upon detecting a change.

There are "perfect hashing" algorithms available, but they tend to be slow if not properly used.

Do you know all the segments of source code that can change the structure in question? If so, set a global variable (or a logical variable in a common block) after each recognizable change to .TRUE.

Initialize the flag to .FALSE. at the beginning of your program.

Then, at the places where you want to check for a change, do the check, take appropriate action, and reset the flag to .FALSE.
0 Kudos
acar
Beginner
660 Views
It is the latter case that I want to guard against - tinkering with the data but leaving the final results unchanged. Byte-by-byte is probably what I need but I'm not sure how to do it. Is this something you might be able to help with Anthony. Thanks, ACAR.
0 Kudos
acar
Beginner
660 Views
One of the reasons I want to do this is that my application can run in a 'real-time' mode such that if this mode is on and I change, say, the geometry of a model, a new analysis is conducted and results reported. I could add code to check for changes but I am looking for a more generic approach to checking for changes that can be applied to an arbitrary structure of data. The data I'm looking at is generally small, for example it may simply be a few reals, integers and logical variables. So speed is not going to bean issue.
0 Kudos
anthonyrichards
New Contributor III
660 Views
Brief consideration makes me think you will need two threads running - one being the main program and the other being a thread that is continuously testing your data and setting and unsetting a flag when it detects a change and after you have noted the change. The testing of equality IF(A_manipulatedType.eq.The_latest_versiontype) will have to be done in a routine, plus you have to duplicate your data to keep the 'before' for comparison purposes with the 'after' versions.
0 Kudos
acar
Beginner
660 Views
Thanks Anthony. What I don't yet understand is how to do the comparison in a general way. I will keep a copy of the structure before editing and want to compare with the current structure as editing proceeds. I could write a routine to check variable by variable the difference between the two structures but I'd need a different routine for each structure in the application that I want to check. I would like to convert the structure into, say, binary, and do a bit-by-bit check for equality or otherwise so that I can apply a general subroutine to an arbitrary structure:


subroutine edit_structure(structure_for_edit)

use definition_for_boris

type(boris)::structure_for_edit
type(boris)::structure_before
type(boris)::structure_after
! record the structure before editing
structure_before=structure_for_edit
! change the structure
structure_for_edit%coordinates(1)=5d0
if(structures_identical(structure_before,structure_for_edit))then
! take some action
endif
return
end
logical function structures_identical(structure_before,structure_after)
use definition_for_boris

implicit none

integer::i
type(boris)::structure_before
type(boris)::structure_after
structures_identical=.true.
do i=1,number_of_bits_in_structure
if(bit_of_structure_before(i).ne.bit_of_structure_after(i))then
structures_identical=.false.
exit
endif
enddo
return
end function
My problem is that I don't know whether or how I can perform the operations required in the functionstructures_identical, i.e. convert my arbitrary structure into a set of bits for comparison purposes.
Is this possible and how might I perform this operation?
Many thanks for your continued input.
0 Kudos
anthonyrichards
New Contributor III
660 Views
Well, here is a simple program to get access to a structure as an array of bytes. Note that the structure size is 24 bytes, one more than the total made from adding the sizes of individual components, due to packing I guess.

program typetest

implicit none
integer(4) siztype, LOCTYPE

type mytype
real*8 D1
real*4 r1
integer*4 I1
integer*2 i2
character(5) string
end type

INTEGER J
INTEGER(1) I(30)

POINTER (PTYPE,I)

TYPE(MYTYPE) SAMPLE

SAMPLE%D1=1234.567D+10
SAMPLE%R1=567.89
SAMPLE%I1=2**10
SAMPLE%I2=2**5
SAMPLE%STRING='SAMPLE'


SIZTYPE=SIZEOF(SAMPLE)
LOCTYPE=LOC(SAMPLE)
PTYPE=LOCTYPE

print *, 'Hello World', 'SIZE OF TYPE =',SIZTYPE,', ADDRESS= ',LOCTYPE
PRINT *, (I(J),J=1,SIZTYPE)
PAUSE
SAMPLE%D1=1234.568D+10
PRINT *, (I(J),J=1,SIZTYPE)
PAUSE

end program typetest

If you want to test structures of different sizes, just make the byte array larger than your largest structure and use the SIZEOF value to limit the bytes used for comparison.

Edit: I added a small change to the first element of the structure. When run, the print out shows changes to bytes 3,4 and 5.
0 Kudos
acar
Beginner
660 Views
Many thanks Anthony, I'll give this a try and report back on progress.
0 Kudos
Reply