Silverfrost Forums

Welcome to our forums

How program knows that it is 64bit or 32bit?

21 Apr 2018 9:03 #21904

Any way for running program to know about itself is it 32 or 64bit ? If there is no such facility then would be great to create one

21 Apr 2018 9:56 #21905

You could use /VPARAM and set the variable to a value when it is compiled.

In the Help file, under the 64 bit ClearWin+ section (Parallel Development using FTN95) is also described how one can use this facility to conditionally compile the code, thus using the appropriate USE or INCLUDE.

I use conditional compilation for two different reasons in my compilations. Works great!

21 Apr 2018 10:21 #21906

Examples:

This one allows me to set a parameter that defines an array size. The variable named, if it is NOT a /VPARAM, sets the parameter via the #else side.

#ifdef RESTRICTED
	INTEGER*4,PARAMETER:: MAX_REFERENCES = 5
#else
	INTEGER*4,PARAMETER:: MAX_REFERENCES = 8192
#endif

This one is used with my .INS files to initialize the variables only when being compiled in a BLOCK DATA program. This way, I can keep the variables AND the initialization in a single file, making changes much easier. The /VPARAM is there only on the compilation of the BLOCK DATA sections.

	common/select_holeid_common_INTS/n,catalog_index_list,select_catalog_entry,direction_holeid,
     $		fieldid_quad,fieldid_state,fieldid_scale_code,fieldid_scale_actual,fieldid_project,fieldid_logid_start,
     $		num_records,quad_selector,hole_selector,quad_select_holeid_time,quad_select_holeid_keystroke
#ifdef INIT_ME
	DATA	quad_selector/' '/,hole_selector/' '/
	DATA	select_catalog_entry/max_catalog_records*0/ ! for the LV control
	DATA	catalog_index_list/max_catalog_records*0/
	DATA	fieldid_quad/0/,fieldid_state/0/,fieldid_scale_code/0/,fieldid_scale_actual/0/,fieldid_project/0/,fieldid_logid_start/0/
	DATA	num_records/0/
	DATA	direction_holeid/10*.false./
	DATA	quad_select_holeid_keystroke/.false./
	DATA	quad_select_holeid_time/0.0/

#endif

I find using the existence (or non-existence #ifndef) better for me that using the value of the parameter name.

#ifndef RESTRICTED	
		sw_version	= my_block%sw_version
		serial		= my_block%serlno ! get the serial number
		download_link	= my_block%download_link
#else
		sw_version	= 'For Evaluation Only' 
		serial		= 'Evaluation' 
		download_link	= 'http://cjdsoftware.com'
#endif

That said, I have used the value assigned to a /VPARAM parameter for another purpose earlier in my development process.

22 Apr 2018 3:05 (Edited: 23 Apr 2018 11:10) #21907

Bill, Never heard about /VPARAM so now despite of using this compiler for 3 decades starting from FTN77 i am like a novice looking at the new option and for me of course the most difficult part is just to start using it after reading the 'FTN95 HELL-P' (everyone knows my idiosyncrasy to snobism of HELP or /HELP or error reporting of this compiler).

OK, let's look with the eyes of novice, this will be a good example: suppose i have the simplest 2 line code in the file aaa.f95

Print*, 'kk=',kk
end 

which i compile

ftn95 aaa.f95 /debug /link /vparam kk 1 >z

to give kk the value 1 via /vparam. It is reasonable to expect based on HELP file the /vparam will assign kk value 1 during compilation, right? This is how novice thinks (novice may think about 10 different other ways of what's to do based on HELP file). So why this does not work always giving kk zero? And because this did not work for me no matter what i have done, i started with swearing more and more to try more crazy variants to make it work. I even tried to use your #ifdef in Fortran source code and got swear of compiler error in respond. Why HELP did not provide the complete example of usage in 3 decades?

Based on ideology of this compiler I'd expect to implement some kind of key in the form kk=IsThis64Bits@() . The /vparam if figure out how it actually works is probably more powerful then that but most probably there is nothing in other Fortran compilers to warrant that this feature will be in the Standard at least not in too distant future...

23 Apr 2018 1:36 (Edited: 23 Apr 2018 11:54) #21911

From my text above it is clear that i tried to 'translate' the general English text ( clearly, England is the country of Shakespeare) into something related to Fortran, so words, words, words. But seems this English words info in Help file have to be translated into some unknown specific command language of compilation? OMG. So many translations of something into something.

If the example would be there we'd translate it into something anyone on the planet would understands, even penguins in my Antarctica without necessity of additional translation of one more intermediate language, which are regular words in English in this case, into binary computer code.

If talk about verbosity I'd prefer that the Fortran compiler told me where is my errors instead of keeping mum and just crash with access violation. At least %pl has to do that for broader range of errors similar way like it already started to do when it sees zero in data with LOG scale

23 Apr 2018 6:22 #21913

Here is an extract from the notes on 64 bit FTN95....

CIF conditional compilation

_WIN32 and _WIN64 are predefined for use with CIF. For example:

CIF(_WIN64) k = 64 CELSE k = 32 CENDIF print*, k

will print '64' if /64 (with /fpp) is used on the FTN95 command line. This is particularly useful with CODE/EDOC blocks. In other contexts it is possible to use an equivalent run-time condition...

IF(KIND(1_7) == 4)THEN k = 64 ELSE k = 32 ENDIF print*, k

23 Apr 2018 8:58 #21919

Dan,

#ifdef relates to the C preprocessor and hence you would have to use option /cfpp when compiling the source with ftn95. Using C processeor statements Paul's code (using CIF) would read

#IF _WIN64     
      k = 64   
#ELSE          
      k = 32   
#ENDIF         
      print*, k

.

Paul, are there other (preprocessor) symbols defined by ftn95 like _WIN64?

Regards, Dietmar

23 Apr 2018 9:21 #21920

Dietmar

Yes there are others but they are not documented and I doubt that they remain useful. Here are two others that are easy to understand.

_DEBUG (indicates that /DEBUG has been used or implied)

_CLR (indicates that /CLR has been used)

23 Apr 2018 5:40 #21936

Dan, yes, I was also unable to get the value to 'show up'. Also, the SPECIAL PARAMETER statement does no eliminate the error if IMPLICIT NONE is specified.

That said, the #ifdef and #endif do work (with /CFPP), and knowing that _WIN32 and _WIN64 will allow detection of the compilation target is helpful.

I like the #ifdef because it is easier to see in the code that the other form of conditional compilation using CIF, et. al.

The 'C' compiler does not have the problem you described and we both experienced with the compile-time value not getting 'assigned'.

22 May 2019 2:13 #23615

Paul,

does ftn95 supply a C-style preprocessor symbol for the version number of the ftn95 compiler?

Having one you could display the version number of the ftn95 compiler with which an executable has been built.

Moreover you would be able to write version dependent code then.

Regards, Dietmar

23 May 2019 4:55 #23616

Paul has previously supplied us with an example of calling GlobalMemoryStatusEx. This includes the Size of virtual address space. A review of this will indicate if 32 or 64 bit I think I have posted this before but I just tested and it works for 32-bit and 64-bit FTN95. You could easily cut it down to generate a logical function IS_64_bit.

  call report_memory_usage ('FTN95_Version')
  end
  
subroutine report_memory_usage (string)
  character string*(*)
!
 integer, parameter:: knd = 4 

 stdcall GlobalMemoryStatusEx 'GlobalMemoryStatusEx'(REF):logical 

 type MEMORYSTATUSEX 
 sequence 
   integer dwLength; 
   integer dwMemoryLoad; 
   integer(knd) ullTotalPhys; 
   integer(knd) ullAvailPhys; 
   integer(knd) ullTotalPageFile; 
   integer(knd) ullAvailPageFile; 
   integer(knd) ullTotalVirtual; 
   integer(knd) ullAvailVirtual; 
   integer(knd) ullAvailExtendedVirtual; 
 end type  

 type(MEMORYSTATUSEX)::mdata 
!
 integer(knd) :: lastAvailPhys = 0
  real*8 gb
  external gb
  
 mdata%dwLength = 64 

 if (GlobalMemoryStatusEx(mdata)) then 

  write (*,11) mdata%ullAvailPhys, (lastAvailPhys-mdata%ullAvailPhys), string

  lastAvailPhys = mdata%ullAvailPhys

   print *,  'Percentage of physical memory in use        ', mdata%dwMemoryLoad            
   print 10, 'Amount of actual physical memory            ', gb(mdata%ullTotalPhys)
   print 10, 'Amount of physical memory available         ', gb(mdata%ullAvailPhys)
   print 10, 'Committed memory limit                      ', gb(mdata%ullTotalPageFile)
   print 10, 'Amount of memory current process can commit ', gb(mdata%ullAvailPageFile)
   print 10, 'Size of virtual address space               ', gb(mdata%ullTotalVirtual)
   print 10, 'Amount of unreserved/uncommitted memory     ', gb(mdata%ullAvailVirtual)
 10 format(1x,a,f0.3) 

 else 
   print*,'Report Memory Failed ', string  
 end if 

 11 format (B'---,---,---,--#',B'---,---,---,--#',2x,a)
 
end subroutine report_memory_usage

 real*8 function gb ( bytes )
   integer*8 :: bytes
   real*8    :: one_gb = 1024.*1024.*1024.   ! size of 1 gb 
!
   gb = dble (bytes) / one_gb

 end function gb
23 May 2019 5:15 #23617

The following simplified logical function appears to work with FTN95 logical function is_64_bitx () ! stdcall GlobalMemoryStatusEx 'GlobalMemoryStatusEx'(REF):logical integer8, parameter :: two = 2 integer8 :: gb_32 = two**32 integer8 mdata(8) integer4 leng equivalence (mdata, leng) ! mdata = 0 leng = 64

 if ( GlobalMemoryStatusEx(mdata) ) then 

!   Size of virtual address space
   print*,'Virtual Memory =',mdata(6), gb_32
   is_64_bitx = ( mdata(6) > gb_32 )

 else 
   print*,'Report Memory Failed '
   is_64_bitx = .false.
 end if 

end function is_64_bitx
23 May 2019 10:53 #23620

John,

thank-you for the code example you posted. I now learnt how to check at runtime if an app executed is a 64 bit app or not.

In the same post Paul gave the hint to preprocessor symbol _WIN64 (and _Win32) which is known at compile time if ftn95 option /fpp [using preprocessor if clause CIF(_WIN64) ] or /cfpp [using C style preprocessor if clause #IF _WIN64) is used. The samples in the post show how you would use this symbol to print if the app is a 64 bit app or a 32 bit app.

Now I am interested in a C style preprocessor symbol say FTN95_VERSION containing the version information of ftn95 (i.e. 8.50, 8.40 or 8.30) depending on the version used for compilation. If we had such a symbol the version number of the compiler which has been used for building an app could be printed.

I could use it for my test samples for the big number ftn95 versions installed on my machine automatically (printing the version number and if it is a 64 bit or 32 bit executable).

If such a symbol existed that would be fine. That's why my question 😉

Regards, Dietmar

23 May 2019 11:07 #23621

Rather than going the C preprocessor route, I think that the better solution to obtaining the compiler version, etc., is to use the F2008 intrinsics COMPILER_VERSION() and COMPILER_OPTIONS(), which are part of the module ISO_FORTRAN_ENV.

We can request Paul to consider implementing these intrinsics.

23 May 2019 12:10 #23624

mecej4,

I have been requesting for a few of these new system routines for a while, see: https://forums.silverfrost.com/Forum/Topic/1894&postdays=0&postorder=asc&start=120

A few more requesting some of these utility routines may help identify those that are more useful.

Support for a FTN95 version of the module ISO_FORTRAN_ENV could also be helpful, which would provide some guidance for making code more portable.

The idea of more flexibility on KIND values could also help. More consensus on this idea could lead to a better approach.

John

23 May 2019 2:44 #23628

It turns out that the version number is intended to be provided via _SAL_VER but this seems to have been forgotten and not updated from 450 which presumably refers to FTN95 v4.50.

We can add a new macro (say _FTN95_VER) and aim to keep it up to date.

I have made a note of the request for COMPILE_VERSION() etc.

24 May 2019 7:03 #23638

I have my own solution for compiler_version , which is: subroutine get_compiler_version ( version ) character version*() character ftn95_ver80 ! include <ftn95_ver.ins> version = ftn95_ver end subroutine get_compiler_version

The include file in C:\Program Files (x86)\Silverfrost\ftn95\include looks like

      ftn95_ver = '[FTN95/x64 Ver. 8.40.0 Nov18 Copyright (c) Silverfrost Ltd 1993-2018]'

It would be good if a similar (or different) approach could be applied to salflibc.dll or where suitable.

24 May 2019 7:43 #23641

For future releases of FTN95, _SAL_VER will be kept up to date and _FTN95_VER will be provided as an alternative.

24 May 2019 10:05 #23646

Thanks Paul, John and mecej4 for your information/discussion (@Paul ... and for providing the symbols 😃

John, did you create include file ftn95_ver.ins? I could not find it in my SALFORD installations.

Regards, Dietmar

24 May 2019 10:14 #23647

Dietmar,

Yes, for each new version I create the file, by running ftn95 > zz, editing zz then copying into ...ftn95..\include\ftn95_ver.ins

With difficulty, as you need to copy as administrator. C:\Program Files (x86)\Silverfrost\ftn95\include is now too protected.

Please login to reply.