* XVARIABLES.CMN - COMMON/ XVARIABLES /
* array declarations and information for variables stored in memory and
* information on variables that can be computed
* variable-naming:
* 2/88 - removed "num_file_vars"
* 3/88 - modulo_var_pri 2000 --> 100000
* 7/88 - added mv_flink/blink and mblk_flink/size for
*	 efficient memory management  -  eliminated blk_in_use
*      - split into 3 distinct COMMON areas:
*	XBLOCK_MEM - with array memory, only
*	XMR	   - with memory variable information
*	XINTERP    - with instance table and interpretation stack information
* 8/88 - dummy_mr moved from FERRET.PARM to here
* 1/89 - added mr_unstand_grid and mr_regrid_trans
* V200:  5/89 - major changes for FERRET 2.00.  4D-symmetrical memory variables
* 	      - delete priorities handled through linked lists
*	      - eliminated "named" variables ("nvar")
*	      - all cvar-related stuff into XCALC_VARS
* 	 2/90 - max_uvars 20 --> 100
* V200 Unix/RISC port - eliminated REAL*8 boundary alignment problem
*		        by placing REAL*8 variables first
*    10/22/92 - added uvar_units, increased uvar_name_code to *24,
*	        increased max_uvar to 250
* V301: increased mem_blk_size x4  !!!
* V312: 5/17/94  removed "memory" array from COMMON altogether

* V402: 7/20/95 - added uvar_dset (for LET/D=...)
* V420: 11/95   - added hash pile for "un_cached" results
*	12/95	- added uvar_mod_pseudo to postpone modulo ops on uvars with
*		  pseudo vars X,Y,Z,T,I,J,K, or L
* V450: 7/97   - added uvar_parent and increates max_uvar
* V491: 12/97  - increased max_uvar_items from 40 to 100 *kob*
* v500: 3/99 - increased uvar_name_code, uvar_units to 64 and uvar_title
*              to 128
* V510: 8/99 *sh* allow other categories of cached mvars (mpv_nocache area)
*	12/99 *sh* added uvar_lo/hi_ss/ww and uvar_by_ss
*		(also fixed messed up comments)
* V510: 5/00 *sh* added variable uvar_bad_data
* V530: 8/00 *sh* added variable mr_c_pointer and mr_type
* 	10/00 *sh* - increased max_intrp to support more complex commands
*		     and uvar_text_len to support longer expressions
* V533: 6/01 *sh* added variable mr_delta
*	7/01 *sh* added variable uvar_data_type
* V534: 9/01 *sh* doubled default memory size
* v5.50 *acm*9/02 - up max_uvar from 400 to 2000
* v552  *acm4/03 - increase uvar_name_code to 128 (also change test in xeq_define)
* V600 2/06 *kob* - declare uvar_name_code_head etc as double, for 64-bit build
* V608 9/07 *acm*  increase uvar_text_len to 2048; var defs can contain long URLs
* V609 1/08 *acm*  increase max_mrs, pmv_npiles, max_intrp and max_uvar_items. 
*                  The first 3 of these needed for LAS scripts doing comparisons 
*                  along with seasonal averages; max_uvar_items reported once or 
*                  twice as a limit that users have run into.
* V61  3/08 *acm*  increase max_mrs again to 501.
* V62  2/09 *acm*  increase initial memory by 4.
* V671 7/11  *acm* Ticket 1868 IFV - masking expressions with ifValid, treating 
*		   zero as valid. 
*       2/12 *kms* Add E and F dimensions (set to nferdims);
*                  added mr_lo_s5 & 6, mr_hi_s5 & 6;
*                  reordered to remove padding
* V685 1/13  *acm* implement LET/REMOTE
* V690 9/13-1/14 *sh*  added aux var regridding,
*	           including is_aux_ptr, and uvar_curvi_var/cat
*		   added space at the top of the isp stack for nferdims auxvars
* V695+ *sh* 5/15  added uvar_c_cache_ptr for c-malloc caching of aux vars
* V698+ *sh* 6/15  changed is_sum from REAL to INTEGER
* V701 *acm* 10/16 Ticket 2422: variables uvar_grid, uvar_data_type, uvar_aux_cat, 
*                  uvar_aux_var to be replaced with calls to LIST routines in NCF_Util.c 
* V702 *sh* 1/17   implement malloc-based dynamic memory management
*                  remove block-managed "memory" array
* V720: 4/17 *acm* Add direction-changing functions as a subset of grid-changing ones

* Terminology:
*	"mr"	- "memory resident"
*	("mv")	  table of information about variables currently stored in
*		  memory
*	"uvar"	- information about user-defined variables (and implicit user-
*		  defined variables given as command arguments)
*	"is"	- pertaining to the "interpretation stack" on which user 
*		  variables are evaluated, axis transformations are executed
*		  and grids in awkward planes are assembled

* BULK FERRET VARIABLE MEMORY MANAGEMENT:
*  Each line number in the memory variable table is the index into a FORTRAN 90
*  array of memory pointers.  under the hood those pointers are actually
*  created by calls to malloc in c (or equivalent in python)

* MEMORY RESIDENT TABLE MANAGEMENT:
*  The slots of the memory variable table are organized as a number of doubly
*   linked lists using mv_flink & mv_blink.  When a variable is to be stored in
*   memory its context (data set, variable, category, etc.) is hashed to 
*   produce a pile number (which linked list contains it).  This greatly
*   reduces the number of table slots that must be searched locating a variable
*   in memory.  The start link for each list is in subscript -1*pile# of
*   mv_flink.
*  Unused table slots are organized into a singly linked list starting at
*   subscript 0 of mv_flink.

* DELETION PRIORITIES
*  Deletion priorities are handled through a doubly linked deletion priority
*   list.  The most recently used/acquired variables are added to the head of
*   the list indicating the lowest priority for deletion.  Variables may be
*   removed from the list if they are in-progress or in-use.  See mr_protected.

* explanation of selected variables:
*	memry	  - array of F90 pointers for memory resident (mr) vars
*	workmem   - array of temporary "work" memory pointers
*                   (index 1 is managed specially -- plegacy_work_buffer)
*	total_mem - total amount of mr memory currently in use
*	peak_mem  - peak amount of mr memory used since last SET MEM/SIZE
*	permanent_mem - amount of mr memory memory used by LOAD/PERMANENT
*	essential_mem - amount of mr memory essential to current command
*                       i.e. mr_protected flagged as mr_temporary,
*                            mr_in_progress or in use (> mr_not_protected)
*       completed_args_mem - amount of mr memory tied up by command arg already
*	               computed (also included in the essential_mem total)
*	mr_size	  - memory size occupied by each mr
*	ws_size   - memory size occupied by each work buffer
*	max_mem_allowed - size as specified by SET MEMORY/SIZE=
*
*       mr_size	    - number of words of storage allocated for this variable
*			See further documemtation in GET_MEMORY
*	mr_trans    -   designates what mathematical transformations have been
*			applied to the data along each axis (see FERRET.PARM)
*	mv_flink      - forward and backwards links into the memory variable
*	mv_blink	table.  Stored variables are hashed into pmv_npiles
*			piles with start pointers stored in the negative
*			subscripts of these arrays
*
*	mr_del_flink  -	forward and backwards links for the chain of variables
*	mr_del_blink	that are available to be deleted if memory space runs
*			short
*	mr_del_last_size - size of memory region freed by the last deletion
*
*	mr_protected  - flags variables as "deleted", "in_progress",
*			"perm_protrcted" or "not_protected".  Variables which
*			are needed as future components of calculations may
*			be reserved (protecting them from deletion) by
*			incrementing mr_protected.  This mechanism allows
*			multiple calculations to claim the same component and
*			still easily keep track of when all claims on the
*			component have been released.
*	
*       mr_naux   	- number of auxiliary variables used in regridding
*  	mr_aux_var,_cat	- var and cat of auxiliary vars (always in parent dset)
*	uvar_title	- title text for plots, etc. of user-defined variables
*	uvar_title_w_text
*			- logical to determine if variable definition is part 
*			  of title
*	uvar_name_code	- 128 character user variable name
*	uvar_units	- units string for variable
*	uvar_text	- text of the algebraic expression defining the variable
*	uvar_num_items	- number of "items" (functions,variables,operators,...)
*			  in the text
*	uvar_item_type	- coded (see alg_ in GFDLPROGRAM.PARM) item types
*	uvar_item_start	- positions in text for starts of item text substrings
*	uvar_item_end	- positions in text for ends   of item text substrings
*	uvar_grid	- defining grid for the expression   xxx removed Ferret v7.02
*	uvar_data_type	- data type for the expression       xxx removed Ferret v7.02
*	uvar_aux_var	- points to the curvi aux coord var for each axis
*	uvar_aux_cat	- points to the curvi aux coord var for each axis
*	uvar_aux_stat	- tells if aux axis has been regridded or remains free
*	uvar_need_dset  - flag if the uvar def'n is independent of dset
*	uvar_given	- indicate degree to which definition of uvar specifies
*			  limits along each axis
*	uvar_dset	- name of data set to which uvar **belongs** (7/95)
*	uvar_by_ss	- when uvlims are given in expression this tells how
*	uvar_lo/hi_ss	- when uvlims are given in expression this tells what
*	uvar_lo/hi_ww	- when uvlims are given in expression this tells what
*	uvar_bad_data	- missing value flag to be used for this variable
*	uvar_c_cache_ptr- pointer to c-cahce of full range variable
*	has_uvar_gc	- variable is a grid-changing variable
*	has_uvar_dc	- a grid-changing variable where the function changes based 
*			  on argument(s) which tell which dimension(s) to operateon
*	is_uvar_const	- variable is a constant-array variable

*	isp	 	- interpretation stack pointer
*	is_act   	- activity currently in progress
*	is_cx		- default context buffer at current stack level
*	is_big_cx	- context of full expression at current stack level
*	is_phase 	- current  looping value for stack level
*	is_obj   	- class of object for stack level
*	is_axis  	- grid axis of transformation for this level
*	is_uvar  	- pointer to text,name,etc. of uvar
*	is_mr		- pointer to memory grid for result
*	is_sum   	- stores a value that is accumulated at stack level
*	is_aux_ptr      - pointer to nferdims of curvilinear vars at stack top

*	uvar_remote	- is the user-variable a LET/REMOTE variable
*	rvar_on_server	- indicates if F-TDS server knows about the LET def
*	rvar_uvar	- associates the remote variable with a uvar
*	rvar_dset	- dataset that hosts the remote definition
*	rvar_varid	- netCDF var id of the remotely defined variable

********************************************************************************
******			PARAMETER DEFINITIONS				  ******

* memory storage capacity
	INTEGER		max_mrs,
     .			max_mr_avail,
     .			pmax_mem_default,
     .			pint_size_test,
     .			max_ws,
     .			plegacy_work_buffer,
     .			pmv_npiles,
     .			pmv_nocache_pile,
     .			pmv_work_var_pile,
     .			pmv_adjoint_var_pile,
     .			pmv_lowest_head,
     .			dummy_mr,
     .			max_splits
	PARAMETER     ( max_mrs   = 501,
     .			dummy_mr  = max_mrs,
     .			max_ws    = 8,
     .			plegacy_work_buffer = 1,
     .			max_mr_avail = max_mrs - 1,
     .			pmax_mem_default = 25600000,  !25.6 megawords
     .			pint_size_test = -999,   ! if needed use c __WORDSIZE
     .			pmv_npiles     = 299,	! prime # of hash piles
     .			pmv_nocache_pile = -pmv_npiles - 1,
     .			pmv_work_var_pile = -pmv_npiles - 2,
     .			pmv_adjoint_var_pile = -pmv_npiles - 3,
     .			pmv_lowest_head = -pmv_npiles - 5,  ! -4, -5 unused
     .			max_splits = 10 )
! pmv_adjoint_pile reserved for future EF's returning multiple results

	INTEGER		max_uvar,
     .			max_uvar_items,
     .			uvar_text_len,
     .			max_intrp,
     .			max_rvar
	PARAMETER     (	max_uvar      	  = 2000,! total # uvars incl. "EX#."
     .			max_uvar_items    =  200,! complexity of uvar expression
     .			uvar_text_len	  = 2048,! max length of uvar expression
     .			max_intrp	  =  400 ,! max depth of interp stack
     .			max_rvar	  = 2000  )

********************************************************************************
******				COMMON DECLARATION			  ******
* ******* added 1/17
* dynamic memory pointer areas
* 2 tables: mr, ws (work storage), (possible 3rd future cs - coordinate store)
* ... an array of pointers to 1D arrays in F90
        TYPE mem_table_slot
           SEQUENCE     ! force data elements to be memory-contiguous
           REAL(8), POINTER :: ptr(:)
        END TYPE
        TYPE(mem_table_slot) :: memry(max_mrs)
        TYPE(mem_table_slot) :: workmem(max_ws)
        INTEGER*8 total_mem, peak_mem, permanent_mem, essential_mem,
     .		  peak_essential_mem, completed_args_mem, max_mem_allowed
	INTEGER mr_size, ws_size
	LOGICAL need_memlim_warning
        COMMON / XDYN_MEM /  
     .          memry,
     .		workmem,
     .          total_mem,
     .		peak_mem,
     .		permanent_mem,
     .	        essential_mem,
     .		peak_essential_mem,
     .		completed_args_mem,
     .		max_mem_allowed,
     .		mr_size(max_mrs),
     .		ws_size(max_ws),
     .		need_memlim_warning

* *******

	INTEGER nsplits, split_var, split_cat, split_axis, split_frag,
     .			 split_trans, split_repeats
	INTEGER*8 deferred_committed_mem
        COMMON / XSPLIT_GATHER /  
     .		deferred_committed_mem,
     .		nsplits,
     .		split_var  (max_splits),
     .		split_cat  (max_splits),
     .		split_axis (max_splits),
     .		split_trans(max_splits),
     .		split_frag (max_splits),
     .		split_repeats(max_splits)

* Reordered as REAL*8, REAL (which may be REAL*8 or REAL*4), INTEGER, LOGICAL,
* CHARACTER to eliminate padding requirements from the compiler.
* uvar_name_code_head should be immediately followed by uvar_name_code_padding
* uvar_num_items_head should be immediately followed by uvar_num_items_padding
	COMMON / XMR / 
     .		mr_lo_ww	( nferdims, max_mrs ),
     .		mr_hi_ww	( nferdims, max_mrs ),
     .		mr_delta	( nferdims, max_mrs ),
     .		uvar_lo_ww	( nferdims, max_uvar ),
     .		uvar_hi_ww	( nferdims, max_uvar ),
     .		mr_c_pointer    ( max_mrs ),
     .          uvar_name_code_head,
     .          uvar_name_code_padding,
     .          uvar_num_items_head,
     .          uvar_num_items_padding,
     .		uvar_c_cache_ptr ( max_uvar ),
     .
     .		mr_trans_arg	( nferdims, max_mrs ),
     .		mr_bad_data   	( max_mrs ),
     .		uvar_bad_data	( max_uvar ),
     .		is_sum  	( max_intrp ),
     .
     .		mr_trans	( nferdims, max_mrs ),
     .		mr_regrid_trans	( nferdims, max_mrs ),
     .		mr_lo_ss	( max_mrs, nferdims ),
     .		mr_hi_ss	( max_mrs, nferdims ),
     .		mr_protected	( max_mrs ),
     .		mr_data_set	( max_mrs ),
     .		mr_category	( max_mrs ),
     .		mr_variable	( max_mrs ),
     .		mr_grid   	( max_mrs ),
     .		mr_type   	( max_mrs ),
     .		mr_naux   	( max_mrs ),
     .		mr_aux_var	( nferdims, max_mrs ),
     .		mr_aux_cat	( nferdims, max_mrs ),
     .		mv_flink        ( pmv_lowest_head:max_mrs ),
     .		mv_blink        ( pmv_lowest_head:max_mrs ),
     .		mr_del_flink    ( 0:max_mrs ),
     .		mr_del_blink    ( 0:max_mrs ),
     .		mr_del_last_size,
     .		num_uvars_in_cmnd,
     .		current_cmnd_uvar,
     .		uvar_lo_ss	 ( max_uvar, nferdims ),
     .		uvar_hi_ss	 ( max_uvar, nferdims ),
     .		uvar_num_items   ( max_uvar ),
     .		uvar_parent	 ( max_uvar ),
     .		uvar_aux_stat	 ( max_uvar, nferdims ),
     .		uvar_item_start	 ( max_uvar_items, max_uvar ),
     .		uvar_item_end	 ( max_uvar_items, max_uvar ),
     .		uvar_item_type	 ( max_uvar_items, max_uvar ),
     .		uvar_given	 ( nferdims, max_uvar ),
     .		uvar_dset	 ( max_uvar ),
     .		uvar_remote	 ( max_uvar ),
     .		rvar_on_server	 ( max_rvar ),
     .		rvar_uvar	 ( max_rvar ),
     .		rvar_dset	 ( max_rvar ),
     .		rvar_varid	 ( max_rvar ),
     .          deleted_list_result(max_uvar),
     .          string_array_result(max_uvar),
     .		max_usable_intrp,
     .		isp,
     .		is_act		( max_intrp ),
     .		is_cx		( max_intrp ),
     .		is_big_cx	( max_intrp ),
     .		is_phase	( max_intrp ),
     .		is_obj  	( max_intrp ),
     .		is_axis 	( max_intrp ),
     .		is_uvar 	( max_intrp ),
     .		is_mr		( max_intrp ),
     .		is_aux_ptr 	( max_intrp ),
     .		is_deferred_mem ( max_intrp ),
     .
     .		mr_unstand_grid	 ( max_mrs ),
     .		uvar_by_ss	 ( nferdims, max_uvar ),
     .		uvar_mod_pseudo	 ( nferdims, max_uvar ),
     .		uvar_ifv	 ( max_uvar ),
     .		uvar_title_w_text( max_uvar ),
     .		uvar_need_dset	 ( max_uvar ),
     .		has_uvar_gc,
     .		has_uvar_dc,
     .		is_uvar_const,
     .
     .		uvar_text	 ( max_uvar ),
     .		uvar_title	 ( max_uvar ),
     .		uvar_name_code	 ( max_uvar ),
     .		uvar_units	 ( max_uvar )

********************************************************************************
******			COMMON VARIABLE TYPE DECLARATIONS		  ******

	INTEGER	mv_flink,
     .		mv_blink,
     .		mr_del_flink,
     .		mr_del_blink,
     .		mr_del_last_size

	INTEGER		num_uvars_in_cmnd,
     .		        current_cmnd_uvar

	LOGICAL		mr_unstand_grid

	REAL		mr_bad_data  	,
     .			mr_trans_arg	,
     .			uvar_bad_data

	REAL*8		mr_lo_ww	,
     .			mr_hi_ww	,
     .			mr_delta	,
     .			uvar_lo_ww	,
     .			uvar_hi_ww	,
     .			mr_c_pointer      ! see note
! Note: the actual data type for mr_c_pointer is **char
! we allocate 8 bytes for 64-bit pointers

	INTEGER		mr_lo_ss	,
     .			mr_hi_ss	,
     .			mr_trans	,
     .			mr_data_set	,
     .			mr_category	,
     .			mr_variable	,
     .			mr_protected	,
     .			mr_grid 	,
     .			mr_type 	,
     .			mr_naux		,
     .			mr_aux_var	,
     .			mr_aux_cat	,
     .			mr_regrid_trans

	CHARACTER*128	uvar_title, uvar_name_code
	CHARACTER*64	uvar_units
	CHARACTER*2048	uvar_text	
	LOGICAL		uvar_title_w_text,
     .			uvar_need_dset,
     .			uvar_mod_pseudo,
     .			uvar_by_ss,
     .			has_uvar_gc,
     .			has_uvar_dc,
     .			is_uvar_const,
     .			uvar_ifv,
     .			uvar_remote,
     .			rvar_on_server
	REAL*8          uvar_name_code_head,
     .                  uvar_name_code_padding,       
     .                  uvar_num_items_head,
     .                  uvar_num_items_padding,
     .			uvar_c_cache_ptr

        INTEGER		uvar_num_items  ,
     .			uvar_aux_stat	,
     .			uvar_item_start	,
     .			uvar_item_end	,
     .			uvar_item_type	,
     .			uvar_given	,
     .			uvar_parent	,
     .			uvar_dset       ,
     .			uvar_lo_ss	,
     .			uvar_hi_ss      ,
     .                  deleted_list_result,
     .                  string_array_result,
     .			rvar_uvar,
     .			rvar_dset,
     .			rvar_varid

	INTEGER		isp,
     .			max_usable_intrp,
     .			is_act  ,
     .			is_cx ,
     .			is_big_cx ,
     .			is_phase,
     .			is_obj  ,
     .			is_axis ,
     .			is_uvar ,
     .			is_mr,
     .			is_aux_ptr,
     .			is_sum

	INTEGER*8	is_deferred_mem

* equivalences to assist with declaration statements
	INTEGER mr_lo_s1( max_mrs ),
     .		mr_lo_s2( max_mrs ),
     .		mr_lo_s3( max_mrs ),
     .		mr_lo_s4( max_mrs ),
     .		mr_lo_s5( max_mrs ),
     .		mr_lo_s6( max_mrs ),
     .		mr_hi_s1( max_mrs ),
     .		mr_hi_s2( max_mrs ),
     .		mr_hi_s3( max_mrs ),
     .		mr_hi_s4( max_mrs ),
     .		mr_hi_s5( max_mrs ),
     .		mr_hi_s6( max_mrs )
	EQUIVALENCE
     .		( mr_lo_s1, mr_lo_ss(1,1) ),
     .		( mr_lo_s2, mr_lo_ss(1,2) ),
     .		( mr_lo_s3, mr_lo_ss(1,3) ),
     .		( mr_lo_s4, mr_lo_ss(1,4) ),
     .		( mr_lo_s5, mr_lo_ss(1,5) ),
     .		( mr_lo_s6, mr_lo_ss(1,6) ),
     .		( mr_hi_s1, mr_hi_ss(1,1) ),
     .		( mr_hi_s2, mr_hi_ss(1,2) ),
     .		( mr_hi_s3, mr_hi_ss(1,3) ),
     .		( mr_hi_s4, mr_hi_ss(1,4) ),
     .		( mr_hi_s5, mr_hi_ss(1,5) ),
     .		( mr_hi_s6, mr_hi_ss(1,6) )

