ood_core 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,1002 @@
1
+ #!/usr/bin/ruby
2
+
3
+ #########################################################################
4
+ #
5
+ # The Contents of this file are made available subject to the terms of
6
+ # the Sun Industry Standards Source License Version 1.2
7
+ #
8
+ # Sun Microsystems Inc., March, 2006
9
+ #
10
+ #
11
+ # Sun Industry Standards Source License Version 1.2
12
+ # =================================================
13
+ # The contents of this file are subject to the Sun Industry Standards
14
+ # Source License Version 1.2 (the "License"); You may not use this file
15
+ # except in compliance with the License. You may obtain a copy of the
16
+ # License at http://gridengine.sunsource.net/Gridengine_SISSL_license.html
17
+ #
18
+ # Software provided under this License is provided on an "AS IS" basis,
19
+ # WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
20
+ # WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
21
+ # MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
22
+ # See the License for the specific provisions governing your rights and
23
+ # obligations concerning the Software.
24
+ #
25
+ # The Initial Developer of the Original Code is: Sun Microsystems, Inc.
26
+ #
27
+ # Copyright: 2006 by Sun Microsystems, Inc.
28
+ #
29
+ # All Rights Reserved.
30
+ #
31
+ #########################################################################
32
+ #
33
+ #
34
+ # Ruby 1.9 version of DRMAA wrapper
35
+ #
36
+ #
37
+ #
38
+
39
+ require 'fiddle/import'
40
+ require 'ffi'
41
+ require 'pp'
42
+
43
+ module FFI_DRMAA
44
+ extend FFI::Library
45
+
46
+ ffi_lib defined?(self.libdrmaa_path) ? self.libdrmaa_path : 'libdrmaa.so'
47
+
48
+ #TODO / Missing:
49
+ #
50
+ # drmaa_delete_job_template
51
+ # drmaa_strerror
52
+
53
+ attach_function 'drmaa_version', [ :pointer , :pointer , :string , :ulong ], :int
54
+ attach_function 'drmaa_init', [:string, :string, :ulong], :int
55
+ attach_function 'drmaa_allocate_job_template', [:pointer, :string, :ulong], :int
56
+ attach_function 'drmaa_get_attribute', [:pointer, :string, :pointer, :ulong, :string, :ulong], :int
57
+ attach_function 'drmaa_get_attribute_names', [:pointer, :string, :ulong], :int
58
+ attach_function 'drmaa_get_vector_attribute', [:pointer, :string, :pointer, :string, :ulong], :int
59
+ attach_function 'drmaa_get_vector_attribute_names', [:pointer, :string, :ulong], :int
60
+
61
+ attach_function 'drmaa_run_job', [:string, :ulong, :pointer, :string, :ulong], :int
62
+ attach_function 'drmaa_set_attribute', [:pointer, :string, :string, :string, :ulong], :int
63
+ attach_function 'drmaa_set_vector_attribute', [:pointer, :string, :pointer, :string, :ulong], :int
64
+ attach_function 'drmaa_get_contact', [:string, :ulong, :string, :ulong], :int
65
+ attach_function 'drmaa_get_DRM_system', [:string, :ulong, :string, :ulong], :int
66
+ attach_function 'drmaa_get_DRMAA_implementation', [:string, :ulong, :string, :ulong], :int
67
+ attach_function 'drmaa_wait', [:buffer_in,:string,:ulong,:pointer,:long,:pointer,:string,:ulong], :int
68
+ attach_function 'drmaa_wifexited', [:pointer,:int,:string,:ulong], :int
69
+ attach_function 'drmaa_wexitstatus', [:pointer,:int,:string,:ulong], :int
70
+ attach_function 'drmaa_wifsignaled', [:pointer,:int,:string,:ulong], :int
71
+ attach_function 'drmaa_wtermsig', [:string,:ulong,:int,:string,:ulong], :int
72
+ attach_function 'drmaa_wifaborted', [:pointer,:int,:string,:ulong], :int
73
+ attach_function 'drmaa_wcoredump', [:pointer,:int,:string,:ulong], :int
74
+ attach_function 'drmaa_exit', [:string, :ulong], :int
75
+ attach_function 'drmaa_run_bulk_jobs', [:pointer,:pointer,:int,:int,:int,:string,:ulong], :int
76
+ attach_function 'drmaa_get_next_job_id', [ :pointer , :string , :ulong ], :int
77
+ attach_function 'drmaa_release_job_ids', [ :pointer ], :void
78
+ attach_function 'drmaa_get_next_attr_name', [ :pointer , :string, :ulong], :int
79
+ attach_function 'drmaa_release_attr_names', [ :pointer ], :void
80
+ attach_function 'drmaa_get_next_attr_value',[ :pointer, :string, :ulong], :int
81
+ attach_function 'drmaa_release_attr_values',[ :pointer ], :void
82
+ attach_function 'drmaa_control', [:string,:int,:string,:ulong], :int
83
+ attach_function 'drmaa_job_ps', [ :string, :pointer , :string, :ulong], :int
84
+
85
+ attach_function 'drmaa_synchronize', [:pointer,:long,:int,:string,:ulong], :int
86
+
87
+ end
88
+
89
+ module DRMAA
90
+ class DRMAAException < StandardError ; end
91
+ class DRMAAInternalError < DRMAAException ; end
92
+ class DRMAACommunicationError < DRMAAException ; end
93
+ class DRMAAAuthenticationError < DRMAAException ; end
94
+ class DRMAAInvalidArgumentError < DRMAAException ; end
95
+ class DRMAANoActiveSessionError < DRMAAException ; end
96
+ class DRMAANoMemoryError < DRMAAException ; end
97
+ class DRMAAInvalidContactError < DRMAAException ; end
98
+ class DRMAADefaultContactError < DRMAAException ; end
99
+ class DRMAASessionInitError < DRMAAException ; end
100
+ class DRMAAAlreadyActiveSessionError < DRMAAException ; end
101
+ class DRMAASessionExitError < DRMAAException ; end
102
+ class DRMAAInvalidAttributeFormatError < DRMAAException ; end
103
+ class DRMAAInvalidAttributeValueError < DRMAAException ; end
104
+ class DRMAAConflictingAttributeValuesError < DRMAAException ; end
105
+ class DRMAATryLater < DRMAAException ; end
106
+ class DRMAADeniedError < DRMAAException ; end
107
+ class DRMAAInvalidJobError < DRMAAException ; end
108
+ class DRMAAResumeInconsistent < DRMAAException ; end
109
+ class DRMAASuspendInconsistent < DRMAAException ; end
110
+ class DRMAAHoldInconsistent < DRMAAException ; end
111
+ class DRMAAReleaseInconsistent < DRMAAException ; end
112
+ class DRMAATimeoutExit < DRMAAException ; end
113
+
114
+ class DRMAANoDefaultContactSelected < DRMAAException ; end
115
+ class DRMAANoMoreElements < DRMAAException ; end
116
+
117
+ # drmaa_job_ps() constants
118
+ STATE_UNDETERMINED = 0x00
119
+ STATE_QUEUED_ACTIVE = 0x10
120
+ STATE_SYSTEM_ON_HOLD = 0x11
121
+ STATE_USER_ON_HOLD = 0x12
122
+ STATE_USER_SYSTEM_ON_HOLD = 0x13
123
+ STATE_RUNNING = 0x20
124
+ STATE_SYSTEM_SUSPENDED = 0x21
125
+ STATE_USER_SUSPENDED = 0x22
126
+ STATE_USER_SYSTEM_SUSPENDED = 0x23
127
+ STATE_DONE = 0x30
128
+ STATE_FAILED = 0x40
129
+
130
+ # drmaa_control() constants
131
+ ACTION_SUSPEND = 0
132
+ ACTION_RESUME = 1
133
+ ACTION_HOLD = 2
134
+ ACTION_RELEASE = 3
135
+ ACTION_TERMINATE = 4
136
+
137
+ # placeholders for job input/output/error path and working dir
138
+ PLACEHOLDER_INCR = "$drmaa_incr_ph$"
139
+ PLACEHOLDER_HD = "$drmaa_hd_ph$"
140
+ PLACEHOLDER_WD = "$drmaa_wd_ph$"
141
+
142
+ private
143
+ ANY_JOB = "DRMAA_JOB_IDS_SESSION_ANY"
144
+ ALL_JOBS = "DRMAA_JOB_IDS_SESSION_ALL"
145
+
146
+ # need errno mapping due to errno's changed from DRMAA 0.95 to 1.0 ... sigh!
147
+ ERRNO_MAP_095 = [ [ "DRMAA_ERRNO_SUCCESS", 0 ],
148
+ [ "DRMAA_ERRNO_INTERNAL_ERROR", 1 ],
149
+ [ "DRMAA_ERRNO_DRM_COMMUNICATION_FAILURE", 2 ],
150
+ [ "DRMAA_ERRNO_AUTH_FAILURE", 3 ],
151
+ [ "DRMAA_ERRNO_INVALID_ARGUMENT", 4 ],
152
+ [ "DRMAA_ERRNO_NO_ACTIVE_SESSION", 5 ],
153
+ [ "DRMAA_ERRNO_NO_MEMORY", 6 ],
154
+
155
+ [ "DRMAA_ERRNO_INVALID_CONTACT_STRING", 7 ],
156
+ [ "DRMAA_ERRNO_DEFAULT_CONTACT_STRING_ERROR" , 8 ],
157
+ [ "DRMAA_ERRNO_DRMS_INIT_FAILED", 9 ],
158
+ [ "DRMAA_ERRNO_ALREADY_ACTIVE_SESSION", 10 ],
159
+ [ "DRMAA_ERRNO_DRMS_EXIT_ERROR", 11 ],
160
+
161
+ [ "DRMAA_ERRNO_INVALID_ATTRIBUTE_FORMAT", 12 ],
162
+ [ "DRMAA_ERRNO_INVALID_ATTRIBUTE_VALUE", 13 ],
163
+ [ "DRMAA_ERRNO_CONFLICTING_ATTRIBUTE_VALUES", 14 ],
164
+
165
+ [ "DRMAA_ERRNO_TRY_LATER", 15 ],
166
+ [ "DRMAA_ERRNO_DENIED_BY_DRM", 16 ],
167
+
168
+ [ "DRMAA_ERRNO_INVALID_JOB", 17 ],
169
+ [ "DRMAA_ERRNO_RESUME_INCONSISTENT_STATE", 18 ],
170
+ [ "DRMAA_ERRNO_SUSPEND_INCONSISTENT_STATE", 19 ],
171
+ [ "DRMAA_ERRNO_HOLD_INCONSISTENT_STATE", 20 ],
172
+ [ "DRMAA_ERRNO_RELEASE_INCONSISTENT_STATE", 21 ],
173
+ [ "DRMAA_ERRNO_EXIT_TIMEOUT", 22 ],
174
+ [ "DRMAA_ERRNO_NO_RUSAGE", 23 ] ]
175
+
176
+ ERRNO_MAP_100 = [ [ "DRMAA_ERRNO_SUCCESS", 0 ],
177
+ [ "DRMAA_ERRNO_INTERNAL_ERROR", 1 ],
178
+ [ "DRMAA_ERRNO_DRM_COMMUNICATION_FAILURE", 2 ],
179
+ [ "DRMAA_ERRNO_AUTH_FAILURE", 3 ],
180
+ [ "DRMAA_ERRNO_INVALID_ARGUMENT", 4 ],
181
+ [ "DRMAA_ERRNO_NO_ACTIVE_SESSION", 5 ],
182
+ [ "DRMAA_ERRNO_NO_MEMORY", 6 ],
183
+
184
+ [ "DRMAA_ERRNO_INVALID_CONTACT_STRING", 7 ],
185
+ [ "DRMAA_ERRNO_DEFAULT_CONTACT_STRING_ERROR", 8 ],
186
+ [ "DRMAA_ERRNO_NO_DEFAULT_CONTACT_STRING_SELECTED", 9 ],
187
+ [ "DRMAA_ERRNO_DRMS_INIT_FAILED", 10 ],
188
+ [ "DRMAA_ERRNO_ALREADY_ACTIVE_SESSION", 11 ],
189
+ [ "DRMAA_ERRNO_DRMS_EXIT_ERROR", 12 ],
190
+
191
+ [ "DRMAA_ERRNO_INVALID_ATTRIBUTE_FORMAT", 13 ],
192
+ [ "DRMAA_ERRNO_INVALID_ATTRIBUTE_VALUE", 14 ],
193
+ [ "DRMAA_ERRNO_CONFLICTING_ATTRIBUTE_VALUES", 15 ],
194
+
195
+ [ "DRMAA_ERRNO_TRY_LATER", 16 ],
196
+ [ "DRMAA_ERRNO_DENIED_BY_DRM", 17 ],
197
+
198
+ [ "DRMAA_ERRNO_INVALID_JOB", 18 ],
199
+ [ "DRMAA_ERRNO_RESUME_INCONSISTENT_STATE", 19 ],
200
+ [ "DRMAA_ERRNO_SUSPEND_INCONSISTENT_STATE", 20 ],
201
+ [ "DRMAA_ERRNO_HOLD_INCONSISTENT_STATE", 21 ],
202
+ [ "DRMAA_ERRNO_RELEASE_INCONSISTENT_STATE", 22 ],
203
+ [ "DRMAA_ERRNO_EXIT_TIMEOUT", 23 ],
204
+ [ "DRMAA_ERRNO_NO_RUSAGE", 24 ],
205
+ [ "DRMAA_ERRNO_NO_MORE_ELEMENTS", 25 ]]
206
+
207
+ def DRMAA.errno2str(drmaa_errno)
208
+ # stack = caller
209
+ # puts stack
210
+ if DRMAA.version < 1.0
211
+ s = ERRNO_MAP_095.find{ |pair| pair[1] == drmaa_errno }[0]
212
+ else
213
+ s = ERRNO_MAP_100.find{ |pair| pair[1] == drmaa_errno }[0]
214
+ end
215
+ s = "DRMAA_ERRNO_INTERNAL_ERROR" if s.nil?
216
+ puts "errno2str(" + drmaa_errno.to_s + ") = " + s
217
+ return s
218
+ end
219
+
220
+ def DRMAA.str2errno(str)
221
+ if DRMAA.version < 1.0
222
+ errno = ERRNO_MAP_095.find{ |pair| pair[0] == str }[1]
223
+ else
224
+ errno = ERRNO_MAP_100.find{ |pair| pair[0] == str }[1]
225
+ end
226
+ errno = 1 if errno.nil? # internal error
227
+ # puts "str2errno(" + str + ") = " + errno.to_s
228
+ return errno
229
+ end
230
+
231
+ # 101 character buffer constant (length is arbitrary)
232
+ ErrSize = 161
233
+ WaitSize = 15
234
+ EC = " " * ErrSize
235
+
236
+ public
237
+ # returns string specifying the DRM system
238
+ # int drmaa_get_drm_system(char *, size_t , char *, size_t)
239
+ def DRMAA.drm_system
240
+ drm = " " * 20
241
+ err = " " * ErrSize
242
+ r = FFI_DRMAA.drmaa_get_DRM_system(drm, 20, err, ErrSize)
243
+ r1 = [drm, 20, err, ErrSize]
244
+ DRMAA.throw(r, r1[2])
245
+ drm.delete! "\000"
246
+ drm.strip!
247
+ return r1[0]
248
+ end
249
+
250
+ # returns string specifying contact information
251
+ # int drmaa_get_contact(char *, size_t, char *, size_t)
252
+ def DRMAA.contact
253
+ contact = " " * ErrSize
254
+ err = " " * ErrSize
255
+ r,r1 = FFI_DRMAA.drmaa_get_contact(contact, ErrSize, err, ErrSize)
256
+ r1 = [contact, ErrSize, err, ErrSize]
257
+ contact.delete! "\000"
258
+ contact.strip!
259
+ DRMAA.throw(r, r1[2])
260
+ return r1[0]
261
+ end
262
+
263
+ # returns string specifying DRMAA implementation
264
+ # int drmaa_get_DRMAA_implementation(char *, size_t , char *, size_t)
265
+ def DRMAA.drmaa_implementation
266
+ err = " " * ErrSize
267
+ impl = " " * 30
268
+ r = FFI_DRMAA.drmaa_get_DRMAA_implementation(impl, 30, err, ErrSize)
269
+ r1 = [impl, 30, err, ErrSize]
270
+ DRMAA.throw(r, r1[2])
271
+ impl.delete! "\000"
272
+ impl.strip!
273
+ return r1[0]
274
+ end
275
+
276
+ # returns DRMAA version (e.g. 1.0 or 0.95)
277
+ # int drmaa_version(unsigned int *, unsigned int *, char *, size_t )
278
+ def DRMAA.version
279
+ err= " " * ErrSize
280
+ major = FFI::MemoryPointer.new(:int, 1)
281
+ minor = FFI::MemoryPointer.new(:int, 1)
282
+ r = FFI_DRMAA.drmaa_version major,minor, err, ErrSize
283
+ r1 = [major.read_int,minor.read_int, err, ErrSize]
284
+ DRMAA.throw(r, r1[2])
285
+ @version = r1[0] + (Float(r1[1])/100)
286
+ end
287
+
288
+ private
289
+ # const char *drmaa_strerror(int drmaa_errno)
290
+ def DRMAA.strerror(errno)
291
+ r = @drmaa_strerror.call(drmaa_errno)
292
+ return r.to_s
293
+ end
294
+
295
+ # int drmaa_job_ps( const char *, int *, char *, size_t )
296
+ def DRMAA.job_ps(job)
297
+ err = " " * ErrSize
298
+ state = FFI::MemoryPointer.new(:int,4)
299
+ r = FFI_DRMAA.drmaa_job_ps(job, state, err, ErrSize)
300
+ r1 = [job, state.read_int, err, ErrSize]
301
+ DRMAA.throw(r, r1[2])
302
+ return r1[1]
303
+ end
304
+
305
+ # int drmaa_control(const char *, int , char *, size_t )
306
+ def DRMAA.control(job, action)
307
+ err = ' ' * ErrSize
308
+ r = FFI_DRMAA.drmaa_control(job, action, err, ErrSize)
309
+ r1 = [job, action, err, ErrSize]
310
+ DRMAA.throw(r, r1[2])
311
+ end
312
+
313
+
314
+ # int drmaa_init(const char *, char *, size_t)
315
+ def DRMAA.init(contact)
316
+ err=" " * ErrSize
317
+ r = FFI_DRMAA.drmaa_init contact, err, ErrSize-1
318
+ r1 = [contact,err,ErrSize-1]
319
+ contact.delete! "\000"
320
+ contact.strip!
321
+ DRMAA.throw(r, r1[1])
322
+ end
323
+
324
+ # int drmaa_exit(char *, size_t)
325
+ def DRMAA.exit
326
+ err=" " * ErrSize
327
+ r = FFI_DRMAA.drmaa_exit err, ErrSize-1
328
+ r1 = [err,ErrSize-1]
329
+ DRMAA.throw(r, r1[0])
330
+ end
331
+
332
+ # int drmaa_allocate_job_template(drmaa_job_template_t **, char *, size_t)
333
+ def DRMAA.allocate_job_template
334
+ err=" " * ErrSize
335
+ jt = FFI::MemoryPointer.new :pointer
336
+ r = FFI_DRMAA.drmaa_allocate_job_template jt, err, ErrSize
337
+ r1 = [jt,err,ErrSize]
338
+
339
+ DRMAA.throw(r, r1[1])
340
+ return jt
341
+ end
342
+
343
+ # int drmaa_delete_job_template(drmaa_job_template_t *, char *, size_t)
344
+ def DRMAA.delete_job_template(jt)
345
+ err = EC
346
+ r,r1 = @drmaa_delete_job_template.call(jt.ptr, err, ErrSize)
347
+ DRMAA.throw(r, r1[1])
348
+ end
349
+
350
+ # int drmaa_get_vector_attribute_names(drmaa_attr_names_t **, char *, size_t)
351
+ def DRMAA.vector_attributes()
352
+ err=""
353
+ (0..100).each { |x| err << " "}
354
+ jt = FFI::MemoryPointer.new :pointer
355
+ r = FFI_DRMAA.drmaa_get_vector_attribute_names jt, err, ErrSize
356
+ r1 = [jt,err,ErrSize]
357
+ DRMAA.throw(r, r1[1])
358
+ return DRMAA.get_attr_names(jt)
359
+ end
360
+
361
+ # int drmaa_get_attribute_names(drmaa_attr_names_t **, char *, size_t)
362
+ def DRMAA.attributes()
363
+ err=""
364
+ (0..100).each { |x| err << " "}
365
+ jt = FFI::MemoryPointer.new :pointer
366
+ r = FFI_DRMAA.get_attribute_names jt, err, ErrSize
367
+ r1 = [jt,err,ErrSize]
368
+ DRMAA.throw(r, r1[1])
369
+ return DRMAA.get_attr_names(jt)
370
+ end
371
+
372
+ def DRMAA.get_all(ids, nxt, rls)
373
+ if DRMAA.version < 1.0
374
+ errno_expect = DRMAA.str2errno("DRMAA_ERRNO_INVALID_ATTRIBUTE_VALUE")
375
+ else
376
+ errno_expect = DRMAA.str2errno("DRMAA_ERRNO_NO_MORE_ELEMENTS")
377
+ end
378
+ # STDERR.puts "get_all(1)"
379
+ values = Array.new
380
+ ret = 0
381
+ while ret != errno_expect do
382
+ # STDERR.puts "get_all(2) " + DRMAA.errno2str(ret)
383
+ err=" " * ErrSize
384
+ jobid=" " * ErrSize
385
+ r = FFI_DRMAA.send(nxt,ids.get_pointer(0), jobid, ErrSize)
386
+ jobid = jobid.unpack('Z*')[0]
387
+ # unpack null-terminated string , return first value
388
+ r1 = [ids.get_pointer(0),jobid,ErrSize]
389
+
390
+ if r != errno_expect
391
+ DRMAA.throw(r, "unexpected error")
392
+ values.push(r1[1])
393
+ # puts "get_all(3) " + DRMAA.errno2str(r)
394
+ end
395
+ ret = r
396
+ end
397
+ # puts "get_all(4)"
398
+ FFI_DRMAA.send(rls,ids.get_pointer(0))
399
+ return values
400
+ end
401
+
402
+ # int drmaa_get_next_job_id(drmaa_job_ids_t*, char *, size_t )
403
+ # void drmaa_release_job_ids(drmaa_job_ids_t*)
404
+ def DRMAA.get_job_ids(ids)
405
+ return DRMAA.get_all(ids, :drmaa_get_next_job_id, :drmaa_release_job_ids)
406
+ end
407
+
408
+
409
+ # int drmaa_get_next_attr_name(drmaa_attr_names_t*, char *, size_t )
410
+ # void drmaa_release_attr_names(drmaa_attr_names_t*)
411
+ def DRMAA.get_attr_names(names)
412
+ return DRMAA.get_all(names, :drmaa_get_next_attr_name, :drmaa_release_attr_names)
413
+ end
414
+
415
+ # int drmaa_get_next_attr_value(drmaa_attr_values_t*, char *, size_t )
416
+ # void drmaa_release_attr_values(drmaa_attr_values_t*)
417
+ def DRMAA.get_attr_values(ids)
418
+ return DRMAA.get_all(ids, :drmaa_get_next_attr_value, :drmaa_release_attr_values)
419
+ end
420
+
421
+ # int drmaa_wifexited(int *, int, char *, size_t)
422
+ def DRMAA.wifexited(stat)
423
+ return DRMAA.wif(stat, :drmaa_wifexited)
424
+ end
425
+
426
+ # int drmaa_wifsignaled(int *, int, char *, size_t)
427
+ def DRMAA.wifsignaled(stat)
428
+ return DRMAA.wif(stat, :drmaa_wifsignaled)
429
+ end
430
+
431
+ # int drmaa_wifaborted(int *, int , char *, size_t)
432
+ def DRMAA.wifaborted(stat)
433
+ return DRMAA.wif(stat, :drmaa_wifaborted)
434
+ end
435
+
436
+ # int drmaa_wcoredump(int *, int , char *, size_t)
437
+ def DRMAA.wcoredump(stat)
438
+ return DRMAA.wif(stat, :drmaa_wcoredump)
439
+ end
440
+
441
+ def DRMAA.wif(stat, method)
442
+ err = " " * ErrSize
443
+ intp = FFI::MemoryPointer.new(:int,4)
444
+ r = FFI_DRMAA.send(method, intp, stat, err, ErrSize)
445
+ r1 = [intp, stat, err, ErrSize]
446
+ DRMAA.throw(r, r1[2])
447
+ boo = r1[0].read_int
448
+ if boo == 0
449
+ return false
450
+ else
451
+ return true
452
+ end
453
+ end
454
+
455
+ # int drmaa_wexitstatus(int *, int, char *, size_t)
456
+ def DRMAA.wexitstatus(stat)
457
+ err = " " * ErrSize
458
+ ret = FFI::MemoryPointer.new(:int,4)
459
+ r = FFI_DRMAA.drmaa_wexitstatus(ret, stat, err, ErrSize)
460
+ r1 = [ret, stat, err, ErrSize]
461
+ DRMAA.throw(r, r1[2])
462
+ return r1[0].read_int
463
+ end
464
+
465
+ # int drmaa_wtermsig(char *signal, size_t signal_len, int stat, char *error_diagnosis, size_t error_diag_len);
466
+ def DRMAA.wtermsig(stat)
467
+ err = " " * ErrSize
468
+ signal = " " * ErrSize
469
+ r = FFI_DRMAA.drmaa_wtermsig(signal, ErrSize, stat, err, ErrSize)
470
+ r1 = [signal, ErrSize, stat, err, ErrSize]
471
+ DRMAA.throw(r, r1[3])
472
+ return r1[0]
473
+ end
474
+
475
+ # int drmaa_wait(const char *, char *, size_t , int *, signed long ,
476
+ # drmaa_attr_values_t **, char *, size_t );
477
+ def DRMAA.wait(jobid, timeout)
478
+ errno_timeout = DRMAA.str2errno("DRMAA_ERRNO_EXIT_TIMEOUT")
479
+ errno_no_rusage = DRMAA.str2errno("DRMAA_ERRNO_NO_RUSAGE")
480
+ err = " " * ErrSize
481
+ waited = " " * WaitSize
482
+ stat = FFI::MemoryPointer.new(:int,4)
483
+ usage = FFI::MemoryPointer.new :pointer, 1
484
+
485
+ r = FFI_DRMAA.drmaa_wait jobid, waited, WaitSize, stat, timeout, usage, err, ErrSize
486
+ r1 = [jobid, waited, WaitSize, stat, timeout, usage, err, ErrSize]
487
+ # getting null's at end of string
488
+ waited.delete! "\000"
489
+ waited.strip!
490
+
491
+ return nil if r == errno_timeout
492
+ if r != errno_no_rusage
493
+ DRMAA.throw(r, r1[6])
494
+ return JobInfo.new(r1[1], r1[3], usage)
495
+ else
496
+ return JobInfo.new(r1[1], r1[3])
497
+ end
498
+ end
499
+
500
+ # int drmaa_run_bulk_jobs(drmaa_job_ids_t **, const drmaa_job_template_t *jt,
501
+ # int, int, int, char *, size_t)
502
+ def DRMAA.run_bulk_jobs(jt, first, last, incr)
503
+ err = " " * ErrSize
504
+ #strptrs = []
505
+ #numJobs = (last - first + 1) / incr
506
+ #numJobs.times {|i| strptrs << FFI::MemoryPointer.from_string(i) }
507
+ #strptrs << nil
508
+ #ids = FFI::MemoryPointer.new(:pointer,strptrs.length)
509
+ #strptrs.each_with_index do |p,i|
510
+ # ids[i].put_pointer(0, p)
511
+ #end
512
+ ids = FFI::MemoryPointer.new :pointer
513
+ r = FFI_DRMAA.drmaa_run_bulk_jobs(ids, jt.get_pointer(0), first, last, incr, err, ErrSize)
514
+ r1 = [ids, jt, first, last, incr, err, ErrSize]
515
+ DRMAA.throw(r, r1[5])
516
+ return DRMAA.get_job_ids(ids)
517
+ end
518
+
519
+ # int drmaa_run_job(char *, size_t, const drmaa_job_template_t *, char *, size_t)
520
+ def DRMAA.run_job(jt)
521
+ err=" " * ErrSize
522
+ jobid=" " * ErrSize
523
+ r = FFI_DRMAA.drmaa_run_job jobid, ErrSize, jt.get_pointer(0), err, ErrSize
524
+ r1 = [jobid,ErrSize,jt.get_pointer(0), err, ErrSize]
525
+ jobid.delete! "\000"
526
+ jobid.strip!
527
+
528
+ DRMAA.throw(r, r1[3])
529
+ return r1[0]
530
+ end
531
+
532
+ # int drmaa_set_attribute(drmaa_job_template_t *, const char *, const char *, char *, size_t)
533
+ def DRMAA.set_attribute(jt, name, value)
534
+ err=" " * ErrSize
535
+ r = FFI_DRMAA.drmaa_set_attribute jt.get_pointer(0), name, value, err, ErrSize
536
+ r1 = [jt.get_pointer(0),name,value,err,ErrSize]
537
+ DRMAA.throw(r, r1[3])
538
+ end
539
+
540
+ # int drmaa_set_vector_attribute(drmaa_job_template_t *, const char *,
541
+ # const char *value[], char *, size_t)
542
+ def DRMAA.set_vector_attribute(jt, name, ary)
543
+ err=" " * ErrSize
544
+ ary.flatten!
545
+
546
+ strptrs = []
547
+ ary.each { |x| strptrs << FFI::MemoryPointer.from_string(x) }
548
+ strptrs << nil
549
+
550
+ argv = FFI::MemoryPointer.new(:pointer,strptrs.length)
551
+ strptrs.each_with_index do |p,i|
552
+ argv[i].put_pointer(0, p)
553
+ end
554
+
555
+ r = FFI_DRMAA.drmaa_set_vector_attribute jt.get_pointer(0), name, argv, err, ErrSize
556
+ r1 = [jt.get_pointer(0),name, argv, err, ErrSize]
557
+ DRMAA.throw(r, r1[3])
558
+ end
559
+
560
+ # int drmaa_get_attribute(drmaa_job_template_t *, const char *, char *,
561
+ # size_t , char *, size_t)
562
+ def DRMAA.get_attribute(jt, name)
563
+ err = " " * ErrSize
564
+ value = " " * ErrSize
565
+ r = FFI_DRMAA.drmaa_get_attribute jt.get_pointer(0), name, value, ErrSize, err, ErrSize
566
+ value = value.unpack('Z*')[0]
567
+ # unpack null-terminated string , return first value
568
+ r1 = [jt.get_pointer(0), name, value, ErrSize, err, ErrSize]
569
+ DRMAA.throw(r, r1[3])
570
+ return r1[2]
571
+ end
572
+
573
+ # int drmaa_get_vector_attribute(drmaa_job_template_t *, const char *,
574
+ # drmaa_attr_values_t **, char *, size_t )
575
+ def DRMAA.get_vector_attribute(jt, name)
576
+ err=" " * ErrSize
577
+ attr = FFI::MemoryPointer.new :pointer
578
+ r = FFI_DRMAA.drmaa_get_vector_attribute jt.get_pointer(0), name, attr, err, ErrSize
579
+ r1 = [jt.get_pointer(0), name, attr, err, ErrSize]
580
+ DRMAA.throw(r, r1[3])
581
+
582
+ # Original author had a method called "drmaa_get_vector_attribute" that did the same thing as this
583
+ return DRMAA.get_attr_values(attr)
584
+ end
585
+
586
+ # int drmaa_synchronize(const char *job_ids[], signed long timeout, int dispose, char *, size_t)
587
+ def DRMAA.synchronize(jobs, timeout, dispose)
588
+ err = " " * ErrSize
589
+ if dispose == false
590
+ disp = 0
591
+ else
592
+ disp = 1
593
+ end
594
+ errno_timeout = DRMAA.str2errno("DRMAA_ERRNO_EXIT_TIMEOUT")
595
+ jobs.flatten!
596
+ strptrs = []
597
+ jobs.each { |x| strptrs << FFI::MemoryPointer.from_string(x) }
598
+ strptrs << nil
599
+ job_ids = FFI::MemoryPointer.new(:pointer,strptrs.length)
600
+ strptrs.each_with_index do |p,i|
601
+ job_ids[i].put_pointer(0, p)
602
+ end
603
+ r = FFI_DRMAA.drmaa_synchronize job_ids, timeout, disp, err, ErrSize
604
+ r1 = [job_ids, timeout, disp, err, ErrSize]
605
+ if r == errno_timeout
606
+ return false
607
+ else
608
+ DRMAA.throw(r, r1[3])
609
+ return true
610
+ end
611
+ end
612
+
613
+ def DRMAA.throw(r, diag)
614
+ return if r == 0
615
+ s_errno = DRMAA.errno2str(r)
616
+ case s_errno
617
+ when "DRMAA_ERRNO_INTERNAL_ERROR"
618
+ raise DRMAAInternalError, diag
619
+ when "DRMAA_ERRNO_DRM_COMMUNICATION_FAILURE"
620
+ raise DRMAACommunicationError, diag
621
+ when "DRMAA_ERRNO_AUTH_FAILURE"
622
+ raise DRMAAAuthenticationError, diag
623
+ when "DRMAA_ERRNO_INVALID_ARGUMENT"
624
+ raise DRMAAInvalidArgumentError, diag
625
+ when "DRMAA_ERRNO_NO_ACTIVE_SESSION"
626
+ raise DRMAANoActiveSessionError, diag
627
+ when "DRMAA_ERRNO_NO_MEMORY"
628
+ raise DRMAANoMemoryError, diag
629
+ when "DRMAA_ERRNO_INVALID_CONTACT_STRING"
630
+ raise DRMAAInvalidContactError, diag
631
+ when "DRMAA_ERRNO_DEFAULT_CONTACT_STRING_ERROR"
632
+ raise DRMAADefaultContactError, diag
633
+ when "DRMAA_ERRNO_NO_DEFAULT_CONTACT_STRING_SELECTED"
634
+ raise DRMAANoDefaultContactSelected, diag
635
+ when "DRMAA_ERRNO_DRMS_INIT_FAILED"
636
+ raise DRMAASessionInitError, diag
637
+ when "DRMAA_ERRNO_ALREADY_ACTIVE_SESSION"
638
+ raise DRMAAAlreadyActiveSessionError, diag
639
+ when "DRMAA_ERRNO_DRMS_EXIT_ERROR"
640
+ raise DRMAASessionExitError, diag
641
+ when "DRMAA_ERRNO_INVALID_ATTRIBUTE_FORMAT"
642
+ raise DRMAAInvalidAttributeFormatError, diag
643
+ when "DRMAA_ERRNO_INVALID_ATTRIBUTE_VALUE"
644
+ raise DRMAAInvalidAttributeValueError, diag
645
+ when "DRMAA_ERRNO_CONFLICTING_ATTRIBUTE_VALUES"
646
+ raise DRMAAConflictingAttributeValuesError, diag
647
+ when "DRMAA_ERRNO_TRY_LATER"
648
+ raise DRMAATryLater, diag
649
+ when "DRMAA_ERRNO_DENIED_BY_DRM"
650
+ raise DRMAADeniedError, diag
651
+ when "DRMAA_ERRNO_INVALID_JOB"
652
+ raise DRMAAInvalidJobError, diag
653
+ when "DRMAA_ERRNO_RESUME_INCONSISTENT_STATE"
654
+ raise DRMAAResumeInconsistent, diag
655
+ when "DRMAA_ERRNO_SUSPEND_INCONSISTENT_STATE"
656
+ raise DRMAASuspendInconsistent, diag
657
+ when "DRMAA_ERRNO_HOLD_INCONSISTENT_STATE"
658
+ raise DRMAAHoldInconsistent, diag
659
+ when "DRMAA_ERRNO_RELEASE_INCONSISTENT_STATE"
660
+ raise DRMAAReleaseInconsistent, diag
661
+ when "DRMAA_ERRNO_EXIT_TIMEOUT"
662
+ raise DRMAATimeoutExit, diag
663
+ when "DRMAA_ERRNO_NO_RUSAGE"
664
+ raise DRMAANoRusage, diag
665
+ when "DRMAA_ERRNO_NO_MORE_ELEMENTS"
666
+ raise DRMAANoMoreElements, diag
667
+ end
668
+ end
669
+
670
+ public
671
+ # const char *drmaa_strerror(int drmaa_errno)
672
+ # DRMAA job info as returned by drmaa_wait()
673
+ class JobInfo
674
+ attr_reader :job
675
+ def initialize(job, stat, rusage = nil)
676
+ @job = job
677
+ @stat = stat.read_int
678
+ @rusage = Hash.new
679
+
680
+ if ! rusage.nil?
681
+ DRMAA.get_attr_values(rusage).each { |u|
682
+ nv = u.scan(/[^=][^=]*/)
683
+ @rusage[nv[0]] = nv[1]
684
+ }
685
+ end
686
+ end
687
+ def wifaborted?
688
+ DRMAA.wifaborted(@stat)
689
+ end
690
+ # true if job finished and exit status available
691
+ def wifexited?
692
+ DRMAA.wifexited(@stat)
693
+ end
694
+ # true if job was signaled and termination signal available
695
+ def wifsignaled?
696
+ DRMAA.wifsignaled(@stat)
697
+ end
698
+ # true if job core dumped
699
+ def wcoredump?
700
+ DRMAA.wcoredump(@stat)
701
+ end
702
+ # returns job exit status
703
+ def wexitstatus
704
+ DRMAA.wexitstatus(@stat)
705
+ end
706
+ # returns termination signal as string
707
+ def wtermsig
708
+ DRMAA.wtermsig(@stat)
709
+ end
710
+ # returns resource utilization as string array ('name=value')
711
+ def rusage
712
+ return @rusage
713
+ end
714
+ end
715
+
716
+ # DRMAA Session
717
+ class Session
718
+ attr_accessor :retry
719
+
720
+ # initialize DRMAA session
721
+ def initialize(contact = "")
722
+ DRMAA.init(contact)
723
+ ObjectSpace.define_finalizer(self, self.method(:finalize).to_proc)
724
+ @retry = 0
725
+ end
726
+
727
+ # close DRMAA session
728
+ def finalize(id)
729
+ # STDERR.puts "... exiting DRMAA"
730
+ DRMAA.exit
731
+ end
732
+
733
+ # non-zero retry interval causes DRMAA::DRMAATryLater be handled transparently
734
+ def retry_until
735
+ if @retry == 0
736
+ job = yield
737
+ else
738
+ begin
739
+ job = yield
740
+ rescue DRMAA::DRMAATryLater
741
+ STDERR.puts "... sleeping"
742
+ sleep @retry
743
+ retry
744
+ end
745
+ end
746
+ return job
747
+ end
748
+
749
+ # submits job described by JobTemplate 't' and returns job id as string
750
+ def run(t)
751
+ retry_until { DRMAA.run_job(t.ptr) }
752
+ end
753
+
754
+ # submits bulk job described by JobTemplate 't'
755
+ # and returns an array of job id strings
756
+ def run_bulk(t, first, last, incr = 1)
757
+ retry_until { DRMAA.run_bulk_jobs(t.ptr, first, last, incr) }
758
+ end
759
+
760
+ # wait for any job of this session and return JobInfo
761
+ def wait_any(timeout = -1)
762
+ DRMAA.wait(ANY_JOB, timeout)
763
+ end
764
+
765
+ # wait for job and return JobInfo
766
+ def wait(job, timeout = -1)
767
+ DRMAA.wait(job, timeout)
768
+ end
769
+
770
+ # run block with JobInfo to finish for each waited session job
771
+ # or return JobInfo array if no block was passed
772
+ def wait_each(timeout = -1)
773
+ if ! block_given?
774
+ ary = Array.new
775
+ end
776
+ while true
777
+ begin
778
+ info = DRMAA.wait(ANY_JOB, timeout)
779
+ rescue DRMAAInvalidJobError
780
+ break
781
+ end
782
+ if block_given?
783
+ yield info
784
+ else
785
+ ary << info
786
+ end
787
+ end
788
+ if ! block_given?
789
+ return ary
790
+ end
791
+ end
792
+
793
+ # synchronize with all session jobs and dispose any job finish information
794
+ # returns false in case of a timeout
795
+ def sync_all!(timeout = -1)
796
+ DRMAA.synchronize([ ALL_JOBS ], timeout, true)
797
+ end
798
+
799
+ # synchronize with all session jobs
800
+ # returns false in case of a timeout
801
+ def sync_all(timeout = -1, dispose = false)
802
+ DRMAA.synchronize([ ALL_JOBS ], timeout, dispose)
803
+ end
804
+
805
+ # synchronize with specified session jobs and dispose any job finish information
806
+ # returns false in case of a timeout
807
+ def sync!(jobs, timeout = -1)
808
+ DRMAA.synchronize(jobs, timeout, true)
809
+ end
810
+
811
+ # synchronize with specified session jobs
812
+ # returns false in case of a timeout
813
+ def sync(jobs, timeout = -1)
814
+ DRMAA.synchronize(jobs, timeout, false)
815
+ end
816
+
817
+ # suspend specified job or all session jobs
818
+ def suspend(job = ALL_JOBS)
819
+ DRMAA.control(job, DRMAA::ACTION_SUSPEND)
820
+ end
821
+
822
+ # resume specified job or all session jobs
823
+ def resume(job = ALL_JOBS)
824
+ DRMAA.control(job, DRMAA::ACTION_RESUME)
825
+ end
826
+
827
+ # put specified job or all session jobs in hold state
828
+ def hold(job = ALL_JOBS)
829
+ DRMAA.control(job, DRMAA::ACTION_HOLD)
830
+ end
831
+
832
+ # release hold state for specified job or all session jobs
833
+ def release(job = ALL_JOBS)
834
+ DRMAA.control(job, DRMAA::ACTION_RELEASE)
835
+ end
836
+
837
+ # terminate specified job or all session jobs
838
+ def terminate(job = ALL_JOBS)
839
+ DRMAA.control(job, DRMAA::ACTION_TERMINATE)
840
+ end
841
+
842
+ # get job state
843
+ def job_ps(job)
844
+ DRMAA.job_ps(job)
845
+ end
846
+ end
847
+
848
+ # DRMAA job template as required by drmaa_run_job() and drmaa_run_bulk_jobs()
849
+ class JobTemplate
850
+ attr_reader :ptr
851
+ def initialize
852
+ @ptr = DRMAA.allocate_job_template
853
+ ObjectSpace.define_finalizer(self, self.method(:finalize).to_proc)
854
+ end
855
+ def finalize(id)
856
+ # STDERR.puts "... releasing job template"
857
+ DRMAA.delete_job_template(@ptr)
858
+ end
859
+ def set(name, value)
860
+ DRMAA.set_attribute(@ptr, name, value)
861
+ end
862
+ def get(name)
863
+ DRMAA.get_attribute(@ptr, name)
864
+ end
865
+ def vset(name, values)
866
+ DRMAA.set_vector_attribute(@ptr, name, values)
867
+ end
868
+ def vget(name)
869
+ DRMAA.get_vector_attribute(@ptr, name)
870
+ end
871
+
872
+ # path of the command to be started as a job
873
+ def command=(cmd)
874
+ set("drmaa_remote_command", cmd)
875
+ end
876
+ def command()
877
+ return get("drmaa_remote_command")
878
+ end
879
+
880
+ # DRMAA job category
881
+ def category=(cat)
882
+ set("drmaa_job_category", cat)
883
+ end
884
+ def category()
885
+ return set("drmaa_job_category")
886
+ end
887
+
888
+ # an opaque string that is interpreted by the DRM
889
+ # refer to DRM documentation for what can be specified here
890
+ def native=(nat)
891
+ set("drmaa_native_specification", nat)
892
+ end
893
+ def native()
894
+ return get("drmaa_native_specification")
895
+ end
896
+
897
+ # jobs stdin path (format "[<hostname>]:<file_path>")
898
+ def stdin=(host_path)
899
+ set("drmaa_input_path", host_path)
900
+ end
901
+ def stdin()
902
+ get("drmaa_input_path")
903
+ end
904
+
905
+ # jobs stdout path (format "[<hostname>]:<file_path>")
906
+ def stdout=(host_path)
907
+ set("drmaa_output_path", host_path)
908
+ end
909
+ def stdout()
910
+ return get("drmaa_output_path")
911
+ end
912
+
913
+ # jobs stderr path (format "[<hostname>]:<file_path>")
914
+ def stderr=(host_path)
915
+ set("drmaa_error_path", host_path)
916
+ end
917
+ def stderr()
918
+ return get("drmaa_error_path")
919
+ end
920
+
921
+ # specifies which files need to be transfered
922
+ def transfer=(transfer)
923
+ set("drmaa_transfer_files", transfer)
924
+ end
925
+
926
+ # job name
927
+ def name=(name)
928
+ set("drmaa_job_name", name)
929
+ end
930
+ def name
931
+ return get("drmaa_job_name")
932
+ end
933
+
934
+ # jobs working directory
935
+ def wd=(path)
936
+ set("drmaa_wd", path)
937
+ end
938
+ def wd
939
+ return get("drmaa_wd")
940
+ end
941
+
942
+ # set jobs start time (format ""[[[[CC]YY/]MM/]DD] hh:mm[:ss] [{-|+}UU:uu])")
943
+ def start_time=(time)
944
+ set("drmaa_start_time", time)
945
+ end
946
+
947
+ # jobs can be submitted in hold state and released later-on
948
+ def hold=(hold)
949
+ if hold
950
+ set("drmaa_js_state", "drmaa_hold")
951
+ else
952
+ set("drmaa_js_state", "drmaa_active")
953
+ end
954
+ end
955
+ def hold?
956
+ if get("drmaa_js_state") == "drmaa_hold"
957
+ true else false end
958
+ end
959
+
960
+ def block_mail=(block)
961
+ if block
962
+ set("drmaa_block_email", "1")
963
+ else
964
+ set("drmaa_block_email", "0")
965
+ end
966
+ end
967
+
968
+ # join jobs stdout/stderr
969
+ def join=(join)
970
+ if join
971
+ set("drmaa_join_files", "y")
972
+ else
973
+ set("drmaa_join_files", "n")
974
+ end
975
+ end
976
+ def join?()
977
+ if get("drmaa_join_files") == "y"
978
+ return true
979
+ else
980
+ return false
981
+ end
982
+ end
983
+
984
+ # job arguments
985
+ def arg=(argv)
986
+ vset("drmaa_v_argv", argv)
987
+ end
988
+ def arg()
989
+ return vget("drmaa_v_argv")
990
+ end
991
+
992
+ # job environment
993
+ def env=(env)
994
+ vset("drmaa_v_env", env)
995
+ end
996
+
997
+ # mail receipants
998
+ def mail=(mail)
999
+ vset("drmaa_v_email", mail)
1000
+ end
1001
+ end
1002
+ end