CONOPT
Loading...
Searching...
No Matches
mp_rosex.f90
Go to the documentation of this file.
1!> @file mp_rosex.f90
2!! @ingroup FORTOPENMP_EXAMPLES
3!!
4!! @copydoc rosex.f90
5
6#if defined(_WIN32) && !defined(_WIN64)
7#define dec_directives_win32
8#endif
9
10Module tlim
11 Integer :: Thread2d
12End module tlim
14!> Main program. A simple setup and call of CONOPT
15!!
16Program rosex
17
19 Use conopt
20 Use omp_lib
21 Use tlim
22 IMPLICIT NONE
23!
24! Declare the user callback routines as Integer, External:
25!
26 Integer, External :: ros_readmatrix ! Mandatory Matrix definition routine defined below
27 Integer, External :: ros_fdeval ! Function and Derivative evaluation routine
28 ! needed a nonlinear model.
29 Integer, External :: std_status ! Standard callback for displaying solution status
30 Integer, External :: ros_solution ! Special callback for displaying solution values that does not write the solution
31 Integer, External :: std_message ! Standard callback for managing messages
32 Integer, External :: std_errmsg ! Standard callback for managing error messages
33#ifdef dec_directives_win32
34!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Ros_ReadMatrix
35!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Ros_FDEval
36!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Std_Status
37!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Ros_Solution
38!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Std_Message
39!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Std_ErrMsg
40#endif
41!
42! Control vector
43!
44 INTEGER, Dimension(:), Pointer :: cntvect
45 INTEGER :: coi_error
46!
47! The model is an unconstrained problem in which the objective is the
48! sum of N identical copies of the Rosenbrock function placed after
49! each other:
50!
51! min sum(i, (1-x(2*i-1))**2+100*(x(2*i)-x(2*i-1)**2)**2)
52!
53! The number of Rosenborck functions
54!
55 Integer :: nr
56!
57! Thread Info
58!
59 Integer :: maxthread
60 real*8 time0, time1, time4
61!
62! Create and initialize a Control Vector
63!
64 call startup
65
66 coi_error = coi_create( cntvect )
67!
68! Tell CONOPT about the size of the model by populating the Control Vector:
69!
70 nr = 16000
71 coi_error = max( coi_error, coidef_numvar( cntvect, 2*nr ) ) ! # variables
72 coi_error = max( coi_error, coidef_numcon( cntvect, 1 ) ) ! # constraints
73 coi_error = max( coi_error, coidef_numnz( cntvect, 2*nr ) ) ! # nonzeros in the Jacobian
74 coi_error = max( coi_error, coidef_numnlnz( cntvect, 2*nr ) ) ! # of which are nonlinear
75 coi_error = max( coi_error, coidef_optdir( cntvect, -1 ) ) ! Minimize
76 coi_error = max( coi_error, coidef_objcon( cntvect, 1 ) ) ! Objective is constraint 1
77 coi_error = max( coi_error, coidef_optfile( cntvect, 'mp_rosex.opt' ) )
78!
79! Tell CONOPT about the callback routines:
80!
81 coi_error = max( coi_error, coidef_readmatrix( cntvect, ros_readmatrix ) )
82 coi_error = max( coi_error, coidef_fdeval( cntvect, ros_fdeval ) )
83 coi_error = max( coi_error, coidef_status( cntvect, std_status ) )
84 coi_error = max( coi_error, coidef_solution( cntvect, ros_solution ) )
85 coi_error = max( coi_error, coidef_message( cntvect, std_message ) )
86 coi_error = max( coi_error, coidef_errmsg( cntvect, std_errmsg ) )
87
88#if defined(CONOPT_LICENSE_INT_1) && defined(CONOPT_LICENSE_INT_2) && defined(CONOPT_LICENSE_INT_3) && defined(CONOPT_LICENSE_TEXT)
89 coi_error = max( coi_error, coidef_license( cntvect, conopt_license_int_1, conopt_license_int_2, conopt_license_int_3, conopt_license_text) )
90#endif
91
92 If ( coi_error .ne. 0 ) THEN
93 write(*,*)
94 write(*,*) '**** Fatal Error while loading CONOPT Callback routines.'
95 write(*,*)
96 call flog( "Skipping Solve due to setup errors", 1 )
97 ENDIF
98!
99! Start CONOPT with a single thread:
100!
101 thread2d = 1
102 time0 = omp_get_wtime()
103 coi_error = coi_solve( cntvect )
104 time1 = omp_get_wtime() - time0
105 If ( coi_error /= 0 ) then
106 call flog( "Solve 1: Errors encountered during solution", 1 )
107 elseif ( stacalls == 0 .or. solcalls == 0 ) then
108 call flog( "Solve 1: Status or Solution routine was not called", 1 )
109 elseif ( sstat /= 1 .or. mstat /= 2 ) then
110 call flog( "Solve 1: Solver and Model Status was not as expected (1,2)", 1 )
111 elseif ( abs( obj-0.0d0 ) > 0.000001d0 ) then
112 call flog( "Solve 1: Incorrect objective returned", 1 )
113 endif
114!
115 maxthread = omp_get_max_threads() ! Define ThreadC as the largest number of threads we can get
116 coi_error = max( coi_error, coidef_threadc( cntvect, maxthread ) )
117 coi_error = max( coi_error, coidef_threadf( cntvect, 1 ) ) ! Functions must run with one thread
118#if defined (complete)
119!
120! Start CONOPT -- Multi-thread mode with a single thread:
121!
122 thread2d = 1
123 coi_error = max( coi_error, coidef_threads( cntvect, 1 ) ) ! 1 means use 1 thread
124 time0 = omp_get_wtime()
125 coi_error = coi_solve( cntvect )
126 time1a = omp_get_wtime() - time0
127 If ( coi_error /= 0 ) then
128 call flog( "Solve 1a: Errors encountered during solution", 1 )
129 elseif ( stacalls == 0 .or. solcalls == 0 ) then
130 call flog( "Solve 1a: Status or Solution routine was not called", 1 )
131 elseif ( sstat /= 1 .or. mstat /= 2 ) then
132 call flog( "Solve 1a: Solver and Model Status was not as expected (1,2)", 1 )
133 elseif ( abs( obj-0.0d0 ) > 0.000001d0 ) then
134 call flog( "Solve 1a: Incorrect objective returned", 1 )
135 endif
136!
137! Start CONOPT -- Multi-thread mode with two threads:
138!
139 thread2d = 2
140 coi_error = max( coi_error, coidef_threads( cntvect, 2 ) ) ! 2 threads
141 time0 = omp_get_wtime()
142 coi_error = coi_solve( cntvect )
143 time2 = omp_get_wtime() - time0
144 If ( coi_error /= 0 ) then
145 call flog( "Solve 2: Errors encountered during solution", 1 )
146 elseif ( stacalls == 0 .or. solcalls == 0 ) then
147 call flog( "Solve 2: Status or Solution routine was not called", 1 )
148 elseif ( sstat /= 1 .or. mstat /= 2 ) then
149 call flog( "Solve 2: Solver and Model Status was not as expected (1,2)", 1 )
150 elseif ( abs( obj-0.0d0 ) > 0.000001d0 ) then
151 call flog( "Solve 2: Incorrect objective returned", 1 )
152 endif
153#endif
154 if ( maxthread >= 4 ) then
155!
156! Start CONOPT -- Multi-thread mode with four threads:
157!
158 thread2d = 4
159 coi_error = max( coi_error, coidef_threads( cntvect, 4 ) ) ! 4 threads
160 time0 = omp_get_wtime()
161 coi_error = coi_solve( cntvect )
162 time4 = omp_get_wtime() - time0
163 If ( coi_error /= 0 ) then
164 call flog( "Solve 4: Errors encountered during solution", 1 )
165 elseif ( stacalls == 0 .or. solcalls == 0 ) then
166 call flog( "Solve 4: Status or Solution routine was not called", 1 )
167 elseif ( sstat /= 1 .or. mstat /= 2 ) then
168 call flog( "Solve 4: Solver and Model Status was not as expected (1,2)", 1 )
169 elseif ( abs( obj-0.0d0 ) > 0.000001d0 ) then
170 call flog( "Solve 4: Incorrect objective returned", 1 )
171 endif
172 endif
173
174 if ( coi_free( cntvect ) /= 0 ) call flog( "Error while freeing control vector", 1 )
175
176 write(*,*)
177 write(*,"('Time for single thread ',f10.3)") time1
178#if defined (complete)
179 write(*,"('Time for single thread ',f10.3)") time1a
180 write(*,"('Time for dual threads ',f10.3)") time2
181#endif
182 if ( maxthread >= 4 ) then
183 write(*,"('Time for quad threads ',f10.3)") time4
184 endif
185 write(*,*)
186 write(*,*) 'End of Extended Rosenbrock Function example. Return code=',coi_error
187
188 call flog( "Successful Solve", 0 )
189
190End Program rosex
191!
192! ============================================================================
193! Define information about the model:
194!
195
196!> Define information about the model
197!!
198!! @include{doc} readMatrix_params.dox
199Integer Function ros_readmatrix( lower, curr, upper, vsta, type, rhs, esta, &
200 colsta, rowno, value, nlflag, n, m, nz, &
201 usrmem )
202#ifdef dec_directives_win32
203!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Ros_ReadMatrix
204#endif
205 IMPLICIT NONE
206 integer, intent (in) :: n ! number of variables
207 integer, intent (in) :: m ! number of constraints
208 integer, intent (in) :: nz ! number of nonzeros
209 real*8, intent (in out), dimension(n) :: lower ! vector of lower bounds
210 real*8, intent (in out), dimension(n) :: curr ! vector of initial values
211 real*8, intent (in out), dimension(n) :: upper ! vector of upper bounds
212 integer, intent (in out), dimension(n) :: vsta ! vector of initial variable status
213 ! (not defined here)
214 integer, intent (out), dimension(m) :: type ! vector of equation types
215 integer, intent (in out), dimension(m) :: esta ! vector of initial equation status
216 ! (not defined here)
217 real*8, intent (in out), dimension(m) :: rhs ! vector of right hand sides
218 integer, intent (in out), dimension(n+1) :: colsta ! vector with start of column indices
219 integer, intent (out), dimension(nz) :: rowno ! vector of row numbers
220 integer, intent (in out), dimension(nz) :: nlflag ! vector of nonlinearity flags
221 real*8, intent (in out), dimension(nz) :: value ! vector of matrix values
222 real*8 usrmem(*) ! optional user memory
223
224 Integer :: nr
225 Integer :: i
226
227 nr = n / 2
228!
229! Information about Variables:
230! Default: Lower = -Inf, Curr = 0, and Upper = +inf.
231! Default: the status information in Vsta is not used.
232!
233 DO i = 1, nr
234 curr(2*i-1) = -1.d0
235 curr(2*i ) = +1.d0
236 enddo
237!
238! Information about Constraints:
239! Default: Rhs = 0
240! Default: the status information in Esta and the function
241! value in FV are not used.
242! Default: Type: There is no default.
243! 0 = Equality,
244! 1 = Greater than or equal,
245! 2 = Less than or equal,
246! 3 = Non binding.
247!
248! Constraint 1 (Objective)
249! Rhs = 0.0 and type Non binding
250!
251 type(1) = 3
252!
253! Information about the Jacobian. We have to define Rowno, Value,
254! Nlflag and Colsta.
255!
256! Colsta = Start of column indices (No Defaults):
257! Rowno = Row indices
258! Value = Value of derivative (by default only linear
259! derivatives are used)
260! Nlflag = 0 for linear and 1 for nonlinear derivative
261! (not needed for completely linear models)
262!
263! Indices
264! x(1) x(2) x(3) x(4)
265! 1: 1 2 3 4 etc
266!
267! Nonlinearity Structure: L = 0 are linear and NL = 1 are nonlinear
268! x(1) x(2) x(3) x(4)
269! 1: NL NL NL NL etc
270!
271! Value (Linear only)
272!
273 DO i = 1, nr*2+1
274 colsta(i) = i
275 enddo
276 DO i = 1, nr*2
277 rowno(i) = 1
278 nlflag(i) = 1
279 enddo
280
281 ros_readmatrix = 0 ! Return value means OK
282
283end Function ros_readmatrix
284!
285!==========================================================================
286! Compute nonlinear terms and non-constant Jacobian elements
287!
288
289!> Compute nonlinear terms and non-constant Jacobian elements
290!!
291!! @include{doc} fdeval_params.dox
292Integer Function ros_fdeval( x, g, jac, rowno, jcnm, mode, ignerr, errcnt, &
293 n, nz, thread, usrmem )
294#ifdef dec_directives_win32
295!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Ros_FDEval
296#endif
297 Use tlim
298 IMPLICIT NONE
299 integer, intent (in) :: n ! number of variables
300 integer, intent (in) :: rowno ! number of the row to be evaluated
301 integer, intent (in) :: nz ! number of nonzeros in this row
302 real*8, intent (in), dimension(n) :: x ! vector of current solution values
303 real*8, intent (in out) :: g ! constraint value
304 real*8, intent (in out), dimension(n) :: jac ! vector of derivatives for current constraint
305 integer, intent (in), dimension(nz) :: jcnm ! list of variables that appear nonlinearly
306 ! in this row. Ffor information only.
307 integer, intent (in) :: mode ! evaluation mode: 1 = function value
308 ! 2 = derivatives, 3 = both
309 integer, intent (in) :: ignerr ! if 1 then errors can be ignored as long
310 ! as errcnt is incremented
311 integer, intent (in out) :: errcnt ! error counter to be incremented in case
312 ! of function evaluation errors.
313 integer, intent (in) :: thread
314 real*8 usrmem(*) ! optional user memory
315
316 Integer :: nr
317 Integer :: i
318
319 nr = n / 2
320!
321! Row 1: the objective function is nonlinear
322!
323 if ( rowno .eq. 1 ) then
324!
325! Mode = 1 or 3. Function value:
326!
327 if ( mode .eq. 1 .or. mode .eq. 3 ) then
328 g = 0.d0
329 do i = 1, nr
330 g = g + (x(2*i-1)-1.d0)**2 + 1.d2*(x(2*i)-x(2*i-1)**2)**2
331 enddo
332 endif
333!
334! Mode = 2 or 3: Derivative values:
335!
336 if ( mode .eq. 2 .or. mode .eq. 3 ) then
337!$OMP PARALLEL DEFAULT(Shared) IF( Thread2D > 1 ) NUM_THREADS(Thread2D)
338!$OMP DO SCHEDULE(Static)
339 do i = 1, nr
340 jac(2*i-1) = 2.d0*(x(2*i-1)-1.d0) - 4.d2*(x(2*i)-x(2*i-1)**2)*x(2*i-1)
341 jac(2*i ) = 2.d2*(x(2*i)-x(2*i-1)**2)
342 enddo
343!$OMP END DO
344!$OMP END PARALLEL
345 endif
346 endif
347 ros_fdeval = 0
348
349end Function ros_fdeval
350
351Integer Function ros_solution( XVAL, XMAR, XBAS, XSTA, YVAL, YMAR, YBAS, YSTA, N, M, USRMEM )
352#ifdef dec_directives_win32
353!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Ros_Solution
354#endif
355!
356! Simple implementation in which we write the solution values to
357! the 'Documentation file' on unit 10.
358!
359 Use proginfop
360 IMPLICIT NONE
361 INTEGER, Intent(IN) :: n, m
362 INTEGER, Intent(IN), Dimension(N) :: xbas, xsta
363 INTEGER, Intent(IN), Dimension(M) :: ybas, ysta
364 real*8, Intent(IN), Dimension(N) :: xval, xmar
365 real*8, Intent(IN), Dimension(M) :: yval, ymar
366 real*8, Intent(IN OUT) :: usrmem(*)
367
368
369 solcalls = solcalls + 1
370 ros_solution = 0
371
372END Function ros_solution
373
integer function std_status(modsta, solsta, iter, objval, usrmem)
Definition comdecl.f90:88
integer function std_message(smsg, dmsg, nmsg, llen, usrmem, msgv)
Definition comdecl.f90:205
integer function std_errmsg(rowno, colno, posno, msglen, usrmem, msg)
Definition comdecl.f90:248
integer(c_int) function coidef_message(cntvect, coi_message)
define callback routine for handling messages returned during the solution process.
Definition conopt.f90:1265
integer(c_int) function coidef_solution(cntvect, coi_solution)
define callback routine for returning the final solution values.
Definition conopt.f90:1238
integer(c_int) function coidef_status(cntvect, coi_status)
define callback routine for returning the completion status.
Definition conopt.f90:1212
integer(c_int) function coidef_readmatrix(cntvect, coi_readmatrix)
define callback routine for providing the matrix data to CONOPT.
Definition conopt.f90:1111
integer(c_int) function coidef_errmsg(cntvect, coi_errmsg)
define callback routine for returning error messages for row, column or Jacobian elements.
Definition conopt.f90:1291
integer(c_int) function coidef_fdeval(cntvect, coi_fdeval)
define callback routine for performing function and derivative evaluations.
Definition conopt.f90:1135
integer(c_int) function coidef_optfile(cntvect, optfile)
define callback routine for defining an options file.
Definition conopt.f90:928
integer(c_int) function coidef_license(cntvect, licint1, licint2, licint3, licstring)
define the License Information.
Definition conopt.f90:293
integer(c_int) function coidef_threadc(cntvect, threadc)
check for thread compatibility.
Definition conopt.f90:727
integer(c_int) function coidef_threadf(cntvect, threadf)
number of threads allowed for simultaneous FDEval calls.
Definition conopt.f90:658
integer(c_int) function coidef_threads(cntvect, threads)
number of threads allowed internally in CONOPT.
Definition conopt.f90:627
integer(c_int) function coidef_numvar(cntvect, numvar)
defines the number of variables in the model.
Definition conopt.f90:97
integer(c_int) function coidef_numcon(cntvect, numcon)
defines the number of constraints in the model.
Definition conopt.f90:121
integer(c_int) function coidef_numnlnz(cntvect, numnlnz)
defines the Number of Nonlinear Nonzeros.
Definition conopt.f90:167
integer(c_int) function coidef_optdir(cntvect, optdir)
defines the Optimization Direction.
Definition conopt.f90:213
integer(c_int) function coidef_numnz(cntvect, numnz)
defines the number of nonzero elements in the Jacobian.
Definition conopt.f90:144
integer(c_int) function coidef_objcon(cntvect, objcon)
defines the Objective Constraint.
Definition conopt.f90:239
integer(c_int) function coi_create(cntvect)
initializes CONOPT and creates the control vector.
Definition conopt.f90:1726
integer(c_int) function coi_free(cntvect)
frees the control vector.
Definition conopt.f90:1749
integer(c_int) function coi_solve(cntvect)
method for starting the solving process of CONOPT.
Definition conopt.f90:1625
integer function ros_solution(xval, xmar, xbas, xsta, yval, ymar, ybas, ysta, n, m, usrmem)
Definition mp_rosex.f90:297
subroutine flog(msg, code)
Definition comdeclp.f90:48
real *8 obj
Definition comdeclp.f90:19
subroutine startup
Definition comdeclp.f90:31
integer thread2d
Definition mp_rosex.f90:13
integer function ros_readmatrix(lower, curr, upper, vsta, type, rhs, esta, colsta, rowno, value, nlflag, n, m, nz, usrmem)
Define information about the model.
Definition roseq.f90:112
integer function ros_fdeval(x, g, jac, rowno, jcnm, mode, ignerr, errcnt, n, nz, thread, usrmem)
Compute nonlinear terms and non-constant Jacobian elements.
Definition roseq.f90:200
program rosex
Main program. A simple setup and call of CONOPT.
Definition rosex.f90:18