Alpsize-03 Fortran Application Development

Alpsize-03 Fortran Application Development

ALPS Fortran is the Fortran interface modules of ALPS. Using ALPS Fortran, You can run Fortran code program easily on ALPS by implementing some necessary subroutine. This chapter describes the procedures for writing the Fortran code to run on ALPS. In addition, also described in this chapter on how to modify (CMakeList.txt) file setting procedures and build the Fortran code to be ported to the existing ALPS Fortran.

Introduction ALPS Fortran

The following figure shows the relationship diagram between ALPS system,ALPS Fortran,and user fortran program.

(ALPS Fortran module)(missing picture)

ALPS Fortran is called from the ALPS, call the Subroutine of the user program as necessary.Thus, ALPS can control the Program has been implemented in Fortran as well as the C++ Program.On the other hand, ALPS Fortran has provided a Subroutine call the functions of ALPS.Therefore, user program will be able to use the ALPS functions as well as to call the normal Fortran Subroutine.

call flows subroutine

The following figure shows the flow chart of the ALPS system and user program. Subroutines for each of the below, refer to the [2.3.3].

(missing picture)

Preparation fortran source code

To implement the Program using ALPS Fortran, you will need to prepare following two source code.

  • C++ source code for implementing main function(entory point of Program).
  • Fortran source code for implementing according to a rule of the ALPS Fortran.

Entry Point 

This section describes the setting Program function main, such as main function(entry point of the Program) and the worker name. Main function is only to describe the fixed contents, usually does not need to be changed. Settings with Program, please refer to the following code,

  • Program version numbers
  • Program copyright
  • Worker name
  • Evaluator name

The following is an example of a C + + source code.

1:    #include <alps/parapack/parapack.h>
2:    #include "fortran_wrapper.h"
3:    
4:    // Version number setting
5:    PARAPACK_SET_VERSION("my version");
6:    
7:    // Copywrite display setting
8:    PARAPACK_SET_COPYRIGHT("my copyright");
9:    
10:    // Worker name setting
11:    PARAPACK_REGISTER_WORKER(alps::fortran_wrapper, "worker name</span>");
12:    
13:    // Evaluator setting
14:    PARAPACK_REGISTER_EVALUATOR(alps::parapack::simple_evaluator,"evaluator name");
15:    
16:    
17:    /**
18:     * Programのentry point
19:     */
20:    int main(int argc, char** argv)
21:    {
22:        return alps::parapack::start(argc, argv);
23:    }

In the above example, it needs to be changed will be the red part characters.

Fortran source code

The main contents of the Fortran source code is the calculation logic. However, there is always a need to implement some Subroutine to use the ALPS Fortran.You call the ALPS function via the Subroutine provided by the ALPS Fortran when performing the loading of the parameters and saving the calculation results.

required Subroutine 

for the user program to control the function of ALPS, you will need some Subroutine in the Fortran source code.read on below for a description of each Subroutine,Implement appropriately,and is a link error if you omit them, you can not build. when implementing these Subroutine, keep in mind the following points:

  • All Subroutine will be passed “(2) :: caller integer” as argument.caller is a variable that is used internally to take ALPS function.Therefore, please do not rewrite the value of the caller. If the value of caller behavior has been changed is not guaranteed.

  • include the “alps / fortran / alps_fortran.h” In each Subroutine. This file will be required when calling the ALPS functions from Fortran code.

So, with regard to the Subroutine required, you will need the following three lines immediately below the signature of the Subroutine.

1:    subroutine alps_init(caller)
2:    implicit none
3:    include "alps/fortran/alps_fortran.h"
4:    integer :: caller(2)
5:    
6:    ! --- snip --- !

alps_init(caller)

  • Argument
TypeNameI/OMeaning
integercaller(2)inlocal variable
  • Explanation

This Subroutine will be called once before the calculation is performed.This is where the initialization process of the Program like as allocating arrays.

alps_init_observables(caller)

  • Argument
TypeNameI/OMeaning
integercaller(2)inlocal variable
  • Explanation

This Subroutine will be called only once after it has been a call is alps_init. This is where you initialize the alps :: ObservableSet.This Subroutine is called once in one input parameter. Incidentally, detail information of the alps :: ObservableSet, refer to the ALPS HP.

alps_run(caller)

  • Argument
TypeNameI/OMeaning
integercaller(2)inlocal variable
  • Explanation

This subroutine is implemented the logic calculation.until it returns a value greater than or equal to 1.0 by alps_progress,This Subroutine is called repeatedly from ALPS.Therefore, in this Subroutine is necessary to take the loop structure is not available. In addition,while running at thread-level-parallelism,this subroutine work on multi-threading.Therefore, when used in thread-level-parallelism is required to provide thread-safe implementation

alps_progress(prgrs, caller)

  • Argument
TypeNameI/OMeaning
real*8prgrsoutProgramの進捗状態(0.0 ≦ prgrs)
integercaller(2)inlocal variable
  • Explanation

This Subroutine will be called by the ALPS has been finished after alps_run, ALPS is returned to the progress situation of the Program.While the prgrs value less than 1.0, ALPS will call repeatedly alps_run. When prgrs value more than 1.0 are substituted, ALPS judges that a calculation was completed, and will finish the program.In addition,while running at thread-level-parallelism,this subroutine work on multi-threading.Therefore, when used in thread-level-parallelism is required to provide thread-safe implementation

alps_is_thermalized(thrmlz, caller)

  • Argument
TypeNameI/OMeaning
real*8thrmlzoutthermalize ending flag(0:Not Completed / 1:Completed )
integercaller(2)inlocal variable
  • Explanation

This Subroutine will be called by the ALPS has been finished after alps_run, returns the incomplete / complete thermalize.When a value of thrmlz is 0, Program judges the calculation is now in thermalize, and does not save a calculation result data.On the other hand,value is 1, Program judges that thermalize was completed, and the calculation result saving is started. In addition,while running at thread-level-parallelism,this subroutine work on multi-threading.Therefore, when used in thread-level-parallelism is required to provide thread-safe implementation

alps_finalize(caller)

  • Argument
TypeNameI/OMeaning
integercaller(2)inlocal variable
  • Explanation

This Subroutine will be called only once (after returning the value greater than or equal to 1.0 from alps_progress) after completing your calculation. This is where you end processing such as the release of allocated memory.

alps_save(caller)

  • Argument
TypeNameI/OMeaning
integercaller(2)inlocal variable
  • Explanation

This subroutine is called from ALPS has been finished after alps_run. Saves the restartrestart-file using the function of ALPS.In addition,while running at thread-level-parallelism,this subroutine work on multi-threading.Therefore, when used in thread-level-parallelism is required to provide thread-safe implementation.

alps_load(caller)

  • Argument
TypeNameI/OMeaning
integercaller(2)inlocal variable
  • Explanation

This Subroutine will be called once, when the Program is restart. Load the saved restart-file using the ALPS functions.

Subroutine provided ALPS Fortran

When you call the ALPS functions from the user program, call the Subroutine provided by the ALPS Fortran. These subroutine will require “(2) :: caller integer” as argument. caller is a local variable that is passed from the ALPS Fortran, you will need to pass the Subroutine provided as a variable passed in the argument to (2.2.3.1) Subroutine required.

alps_get_parameter(data, name, type, caller)

  • Argument
TypeNameI/OMeaning
-dataoutstore of the value
charactername(*)inparameter name to take out
integertypeindata type
integercaller(2)inlocal variable
  • Explanation

Specify the name, ane receive a parameter from ALPS. parameter name, type, number of elements is specified name, type, in each count.This Subroutine will be used to initialize the arrays and variables in the mainly alps_init. In addition, the possible value of the type is defined in the alps_fortran.h.

alps_parameter_defined(res, name, caller)

  • Argument
TypeNameI/OMeaning
integerresoutThe presence or absence of definition of parameter(1:absence / 0:definition)
charactername(*)inparameter name
integercaller(2)inlocal variable
  • Explanation

Returns whether the parameter is defined in the parameter file is specified by name. 1Italic text is assigned to the res if it is defined. 0Italic text is assigned if it is not.This Subroutine will be used to initialize the arrays and variables in the mainly alps_init.

alps_init_observable(count, type, name, caller)

  • Argument
TypeNameI/OMeaning
integercountinNumber of element of a stored calculation result
integertypeindata type
charactername(*)inThe name of Observable to store
integercaller(2)inlocal variable
  • Explanation

This Subroutine is used to register a name that is specified in the Observable to alps :: ObservableSet in alps_init_observable. Observable types are determined as follows by type and count.

typecountObservable
ALPS_INT1IntObservable
ALPS_INT1<in
ALPS_REAL1RealObservable
ALPS_REAL1<RealVectorObservable
ALPS_DOUBLE_PRECISION1RealObservable
ALPS_DOUBLE_PRECISION1<RealVectorObservable

alps_accumulate_observable(data, count, type, name, caller)

  • Argument
TypeNameI/OMeaning
-datainthe calculation results to store
integercountinNumber of element of a stored calculation result
integertypeindata type
charactername(*)inThe name of Observable to store
integercaller(2)inlocal variable
  • Explanation

Save the result data to Observable with the specified name. This Subroutine is used to store the results of a calculation in alps_run. count / name / type must match the ones specified in init_observable.

alps_dump(data, count, type, caller)

  • Argument

    TypeNameI/OMeaning
    -datainthe values to store
    integercountinNumber of elements of values to store
    integertypeindata type
    integercall(2)inlocal variable
  • Explanation

This Subroutine is used to save the restart-file in the alps_save. interruption data was saved using alps_dump will be used at restart.

alps_restore(data, count, type, caller)

  • Argument
TypeNameI/OMeaning
-dataoutstorage location of loaded values
integercountinNumber of element of value to load
integertypeindata type
integercaller(2)inlocal variable
  • Explanation

This Subroutine is used to load the restart-file in the alps_load to restart-file data is saved in the order in which they were saved in alps_dump. Therefore, when loading is alps_restore, remove the data in the same order as when it is saved.

editing configuration file

user program builds using CMake as well as ALPS. It is a sample of setting file(CMakeLists.txt) to build user program in CMake as follows.

1:    # CMakeList.txt
2:    # editing configuration file for CMake
3:    
4:    cmake_minimum_required(VERSION 2.8.0 FATAL_ERROR)
5:    
6:    #Project name setting
7:    project(**hello_sample**)
8:    
9:    # find ALPS Fortran setting
10:    find_package(ALPS REQUIRED NO_SYSTEM_ENVIRONMENT_PATH)
11:    message(STATUS "ALPS version: ${ALPS_VERSION}")
12:    include(${ALPS_USE_FILE})
13:    
14:    # Source code required to create and run file name
15:    add_executable(**hello main.C hello_impl.f**)
16:    # External library file required to generate execution
17:    target_link_libraries(**hello** ${ALPS_LIBRARIES} ${ALPS_FORTRAN_LIBRARIES})

In the above example, it needs to be changed will be the part of characters inside **…**.

Porting of existing program code

In this section, in case of the ising model program shown below,Describes the procedure that ALPS to work on the existing Fortran Program.

preparation porting 

In this section, we will use the file in the tutorial directory that is generated by extracting the alps_fortran.tar.gz.In preparation for the porting work, copy the following file to a working directory in the tutorial directory.

  • ising_original.f:original source code
  • template.f90:Template source cod of ALPS Fortran Program
  • main.C:entry point of Program
  • CMakeList.txt:Template of CMakeList.txt

All Subroutine which are necessary implementing ALPSProgram in template.f90 is defined.Therefore, when developing a new Program you can proceed with the development based on template.f90.

The rough structure of original code is as follows.

Processing contents
4-7Variable Declaration & Initialization
8-23Array element Initialization
24-47main loop
25-34calculation
36thermalize check
37-46saving calculation resutls
48-58results output

porting fortran code

The porting of Fortran code, we will assign to Subroutine, the processing being done in each block of ising_original.f. This section describes an example of tutorial/alps_ising.f90 as a sample of after-porting code.

Variable declaration

Each variable has been declared in the ising_original.f is at the porting is turned into ALPS module.In order to porting to ALPS because there is a need to Subroutine for each processing unit, and modify it to allow access to the variables from each Subroutine.

  • before porting

      4:    DIMENSION IS(20,20),IP(20),IM(20),P(-4:4),A(4)
      5:    C PARAMETERS
      6:          DATA TEMP/2.5/, L/10/, MCS/1000/, INT/1000/
      7:          DATA IX/1234567/, V0/.465661288D-9/
    
  • after porting

      1:    module ising_mod
      2:      implicit none
      3:      real, parameter :: V0 = .465661288D-9
      4:
      5:      integer, allocatable, dimension(:) :: IP, IM
      6:      integer, allocatable, dimension(:,:) :: IS
      7:      real*8, allocatable, dimension(:) :: P
      8:      integer :: K, MCS, INT, L, IX
      9:      real :: TEMP
      10:    end module ising_mod
      11:
    

IP, IM, IS, P array are initialized in alps_init, the size of the after transplantation does not specify here.In addition, original array A is for storing a result, this array is in the after-porting will use the mechanism of ALPS.Therefore, array A is not necessary for code after the porting.Also, the value of each variable after porting gotten from the parameter file.In addition, K is a variable variable after the porting to count the number of iterations. Thermalize check after porting is responsible for control and repeat with the value of K to do without a loop. In this section, so that is expected to run in parallel MPI, for thread-safe is not considered.

Initializing process

Initialization process of the original code may have to initialize each element of the array, at after-porting code, run in the initialization process is Subroutine alps_init.First,Initializes the array variables, using the alps_get_parameter, then initialize the array elements.Also, do not prepare the array for storing the results after porting, prepare the Observable for saving the results in alps_init_observableSubroutine.In addition, it is not necessary for alps_init and alps_init_observable to call it in after-porting code because it is called automatically by ALPS.Also, do not prepare an array for storing the results, prepare the Observable for saving the results in alps_init_observableSubroutine.

  • before porting

      8:    C TABLES
      9:          DO 10 I=-4,4
      10:          W=EXP(FLOAT(I)/TEMP)
      11:     10   P(I)=W/(W+1/W)
      12:          DO 11 I=1,L
      13:          IP(I)=I+1
      14:     11   IM(I)=I-1
      15:          IP(L)=1
      16:          IM(1)=L
      17:    C INITIAL CONFIGURATION
      18:          DO 20 I=1,L
      19:          DO 20 J=1,L
      20:     20   IS(I,J)=1
      21:    C ACCUMULATION DATA RESET
      22:          DO 21 I=1,4
      23:     21   A(I)=0.0
    
  • after porting(alps_init)

      13:    subroutine alps_init(caller)
      14:      use ising_mod
      15:      implicit none
      16:      include "alps/fortran/alps_fortran.h"
      17:      integer :: caller(2)
      18:      integer :: i, j
      19:      real*8 :: W
      20:
      21:      call alps_get_parameter(TEMP, "TEMPERATURE", ALPS_REAL, caller)
      22:      call alps_get_parameter(L, "L", ALPS_INT, caller)
      23:      call alps_get_parameter(MCS, "MCS", ALPS_INT, caller)
      24:      call alps_get_parameter(INT, "INT", ALPS_INT, caller)
      25:
      26:      allocate( IP(L) )
      27:      allocate( IM(L) )
      28:      allocate( P(-4:4) )
      29:      allocate( IS(L, L) )
      30:
      31:      K = 0
      32:      IX = 1234567
      33:
      34:      do i = -4, 4
      35:         W = exp(float(i)/TEMP)
      36:         P(i) = W / (W + 1/W)
      37:      end do
      38:
      39:      do i = 1, L
      40:         IP(i) = i + 1
      41:         IM(i) = i - 1
      42:      end do
      43:
      44:      do i = 1, L
      45:         do j = 1, L
      46:            IS(i, j) = 1
      47:         end do
      48:      end do
      49:
      50:      IP(L) = 1
      51:      IM(1) = L
      52:
      53:      return
      54:    end subroutine alps_init
    

Above code shows that it calls the alps_get_parameter in line 21 to 24, getting the contents of the parameter file through the ALPS.In addition, the processing of line 34-51 is the same as the original code.

  • after porting(alps_init_observables)

      92:    subroutine alps_init_observables(caller)
      93:      implicit none
      94:      include "alps/fortran/alps_fortran.h"
      95:      integer :: caller(2)
      96:
      97:      call alps_init_observable(1, ALPS_REAL, "Energy", caller)
      98:      call alps_init_observable(1, ALPS_REAL, "Magnetization", caller)
      99:
      100:      return
      101:    end subroutine alps_init_observables
    

Observable are available with the name “Magnetization” and “Energy” as a buffer for storing the calculation result after porting.In the original code, calculates the sum of squares with the sum for each Magnetization and Energy, but,these calculations is done automatically by Observable after porting.

calcuration and saving results

Although there has been in the do loop iteration (line 25 original-code)in the original code, and after porting, uses the alps_progressSubroutine alps_run without a do loop.

  • before porting

      24:    C SIMULATION
      25:          DO 30 K=1,MCS+INT
      26:          KIJ=0
      27:          DO 31 I=1,L
      28:          DO 31 J=1,L
      29:          M=IS(IP(I),J)+IS(I,IP(J))+IS(IM(I),J)+IS(I,IM(J))
      30:          KIJ=KIJ+1
      31:          IS(I,J)=-1
      32:          IX=IAND(IX*5*11,2147483647)
      33:          IF(P(M).GT.V0*IX) IS(I,J)=1
      34:     31   CONTINUE
      35:    C DATA
      36:          IF(K.LE.INT) GOTO 30
      37:          EN=0
      38:          MG=0
      39:          DO 40 I=1,L
      40:          DO 40 J=1,L
      41:          EN=EN+IS(I,J)*(IS(IP(I),J)+IS(I,IP(J)))
      42:     40   MG=MG+IS(I,J)
      43:          A(1)=A(1)+EN
      44:          A(2)=A(2)+EN**2
      45:          A(3)=A(3)+MG
      46:          A(4)=A(4)+MG**2
      47:     30   CONTINUE
    
  • after porting(alps_run)

      56:    ! subroutine alps_run
      57:    subroutine alps_run(caller)
      58:      use ising_mod
      59:      implicit none
      60:      include "alps/fortran/alps_fortran.h"
      61:      integer :: caller(2)
      62:      integer :: i, j, M
      63:      real*8 :: EN, MG
      64:
      65:      do i = 1, L
      66:         do j = 1, L
      67:            M = IS(IP(i), j) + IS(i, IP(j)) + IS(IM(i), j) + IS(i, IM(j))
      68:            IS(i, j) = -1
      69:
      70:            IX = IAND(IX * 5 * 11, 2147483647)
      71:            if(P(M).gt.V0*IX) IS(i, j) = 1
      72:         end do
      73:      end do
      74:
      75:      EN = 0.0D0
      76:      MG = 0.0D0
      77:      do i = 1, L
      78:         do j = 1, L
      79:            EN = EN + IS(i, j) * (IS(IP(i), j) + IS(i, IP(j)))
      80:            MG = MG + IS(i, j)
      81:         end do
      82:      end do
      83:
      84:      call alps_accumulate_observable(EN, 1, &
              ALPS_DOUBLE_PRECISION, "Energy", caller)
      85:      call alps_accumulate_observable(MG, 1, &
                                                                                                                                                                                                                                                                                                                                          ALPS_DOUBLE_PRECISION, "Magnetization", caller)
      86:      K = K + 1
      87:
      88:      return
      89:    end subroutine alps_run
    

Calculation process itself(Line 65 to 82) is the same as the original code, after porting will be called automatically alps_run repeatedly, the loop at line 25 of the Original Code is not writted.Instead, it counts the number of iterations in line 86.Also, save the results of the calculation using the ALPS function(line 84 and 85).In the original code (lines 43-46 the original code) are performed, such as calculating the integrated and square, but these are done automatically by alps_accumulate_observable.

  • after porting(alps_progress)

      103:    ! alps_progerss
      104:    subroutine alps_progress(prgrs, caller)
      105:      use ising_mod
      106:      implicit none
      107:      include "alps/fortran/alps_fortran.h"
      108:      integer :: caller(2)
      109:      real*8 :: prgrs
      110:
      111:      prgrs = K / (INT + MCS)
      112:
      113:    end subroutine alps_progress
    

after porting, Alps_progress done in the control of the iterative calculation.prgrs value is greater than or equal to 1 is alps_run will no longer be called.Therefore, it is implemented as prgrs value is greater than or equal to 1 to monitor the value of (K), the number of times when you are running counter provision.

thermalized check

In the original code, hermalized-check has been run within the main loop (line 36).However,after porting,run for subroutine alps_is_thermalized.

  • before porting

      36:          IF(K.LE.INT) GOTO 30
    
  • after porting(alps_is_thermalized):

      115:    ! alps_is_thermalized
      116:    subroutine alps_is_thermalized(thrmlz, caller)
      117:      use ising_mod
      118:      implicit none
      119:      include "alps/fortran/alps_fortran.h"
      120:      integer :: caller(2)
      121:      integer :: thrmlz
      122:
      123:      if(K >= INT) then
      124:         thrmlz = 1
      125:      else
      126:         thrmlz = 0
      127:      end if
      128:
      129:      return
      130:    end subroutine alps_is_thermalized
    

Similarly alps_progress, checks the thermalized from the value of (K) counter. are considered to have been completed thermalize and become value thrmlz=1.

output results

Post-processing and output of the results is done automatically when you use the ALPS.Therefore, the codes for output of calculation results and post-processing are not required.

  • before porting

      48:    C STATISTICS
      49:          DO 50 I=1,4
      50:     50   A(I)=A(I)/MCS
      51:          C=(A(2)-A(1)**2)/L**2/TEMP**2
      52:          X=(A(4)-A(3)**2)/L**2/TEMP
      53:          ENG=A(1)/L**2
      54:          AMG=A(3)/L**2
      55:          WRITE(6,100) TEMP,L,ENG,C,AMG,X
      56:     100  FORMAT(' TEMP=',F10.5,' SIZE=',I5,
      57:         * /' ENG =',F10.5,' C   =',F10.5,
      58:         * /' MAG =',F10.5,' X   =',F10.5)
    
  • after porting:code not available

Finalizing process

There is no end processing is not performed for allocate in the original code. However, after porting must be deallocate array that you allocate in alps_init.

  • before porting:code not available

  • after porting(alps_finalize)

      160:    ! alps_finalize
      161:    subroutine alps_finalize(caller)
      162:      use ising_mod
      163:      implicit none
      164:      include "alps/fortran/alps_fortran.h"
      165:      integer :: caller(2)
      166:
      167:      deallocate(IP)
      168:      deallocate(IM)
      169:      deallocate(P)
      170:      deallocate(IS)
      171:
      172:      return
      173:    end subroutine alps_finalize
    

restart function

Only to implement (alps_save / alps_load), you can add functionality to restart restart-file Program I / O function of when you use the ALPS.The original code does not have the ability to restart, describes an example implementation of I / O function of the restart-file according to the ALPS below.

  • before porting:code not available

  • after porting(alps_save)

      132:    ! alps_save
      133:    subroutine alps_save(caller)
      134:      use ising_mod
      135:      implicit none
      136:      include "alps/fortran/alps_fortran.h"
      137:      integer caller(2)
      138:
      139:      call alps_dump(K, 1, ALPS_INT, caller)
      140:      call alps_dump(IX, 1, ALPS_INT, caller)
      141:      call alps_dump(IS, L * L, ALPS_INT, caller)
      142:
      143:      return
      144:    end subroutine alps_save
    

alps_save writes in alps_dump the only variables that need to restart.Here, This section shows how to export counter (K) and data (IX, IS) calculating.

  • after porting(alps_load)

      146:    ! alps_load
      147:    subroutine alps_load(caller)
      148:      use ising_mod
      149:      implicit none
      150:      include "alps/fortran/alps_fortran.h"
      151:      integer :: caller(2)
      152:
      153:      call alps_restore(K, 1, ALPS_INT, caller)
      154:      call alps_restore(IX, 1, ALPS_INT, caller)
      155:      call alps_restore(IS, L * L, ALPS_INT, caller)
      156:
      157:      return
      158:    end subroutine alps_load
    

There are (alps_restore) must be loaded in the order alps_save exported in (alps_dump) In alps_load.However, when you restart the ALPSProgram, alps_init will be called before alps_load is called. However, when you restart the ALPSProgram, alps_init will be called before alps_load is called. In other words, the initialization of the memory allocation K,IX,and IS and other variables is done in alps_init, need to do initialization, etc. within the alps_load is not available.

About support of multi-thread

If you want to run with multi-thread the ALPSProgram, must be thread-safe implementation of the Fortran code.If tutorial.f90 described in this section, you can support multi-thread by thread-local variables to prepare in 2.4.2.

  • after porting(multi-thread)

      1:    module ising_mod
      2:      implicit none
      3:      real, parameter :: V0 = .465661288D-9
      4:
      5:      integer, allocatable, dimension(:) :: IP, IM
      6:      integer, allocatable, dimension(:,:) :: IS
      7:      real*8, allocatable, dimension(:) :: P
      8:      integer :: K, MCS, INT, L, IX
      9:      real :: TEMP
      10:    !$omp threadprivate (K, MCS, INT, TEMP, IP, IM, P, IS, IX, L)
      11:    end module ising_mod
      12:
    

About main.C 

main.C file is required to become entry point of the Program.But it is not necessary to change the contents of the main function. Configuration of main.C, change it if necessary. refer to 2.2.2.

About CMakeLists.txt

change the CMakeLists.txt (see text 2.3). The following is an example of CMakeLits.txt.

1:    cmake_minimum_required(VERSION 2.8.0 FATAL_ERROR)
2:    
3:    project(tutorial)
4:    
5:    find_package(ALPS REQUIRED NO_SYSTEM_ENVIRONMENT_PATH)
6:    message(STATUS "ALPS version: ${ALPS_VERSION}")
7:    include(${ALPS_USE_FILE})
8:    
9:    # Source code required to create and run file name
10:    add_executable(tutorial main.C tutorial.f90)
11:    target_link_libraries(tutorial ${ALPS_LIBRARIES} ${ALPS_FORTRAN_LIBRARIES})