func getStringValue(jt *C.drmaa_job_template_t, name string) (string, *Error) { if jt == nil { ce := makeError("No job template", errorId[C.DRMAA_ERRNO_INVALID_JOB]) return "", &ce } diag := C.makeString(stringSize) defer C.free(unsafe.Pointer(diag)) n := C.CString(name) defer C.free(unsafe.Pointer(n)) v := C.makeString(stringSize) defer C.free(unsafe.Pointer(v)) errNumber := C.drmaa_get_attribute(jt, n, v, stringSize, diag, stringSize) if errNumber != C.DRMAA_ERRNO_SUCCESS { ce := makeError(C.GoString(diag), errorId[errNumber]) return "", &ce } return C.GoString(v), nil }
// Get contact string. func GetContact() (string, *Error) { diag := C.makeString(stringSize) defer C.free(unsafe.Pointer(diag)) contact := C.makeString(stringSize) defer C.free(unsafe.Pointer(contact)) errNumber := C.drmaa_get_contact(contact, stringSize, diag, stringSize) if errNumber != C.DRMAA_ERRNO_SUCCESS && diag != nil { ce := makeError(C.GoString(diag), errorId[errNumber]) return "", &ce } return C.GoString(contact), nil }
// Submits a job in a (initialized) session to the DRM. func (s *Session) RunJob(jt *JobTemplate) (string, *Error) { jobId := C.makeString(jobnameSize) defer C.free(unsafe.Pointer(jobId)) diag := C.makeString(stringSize) defer C.free(unsafe.Pointer(diag)) errNumber := C.drmaa_run_job(jobId, jobnameSize, jt.jt, diag, stringSize) if errNumber != C.DRMAA_ERRNO_SUCCESS && diag != nil { ce := makeError(C.GoString(diag), errorId[errNumber]) return "", &ce } return C.GoString(jobId), nil }
// Blocks the the programm until the given jobs left the system or // a specific timeout is reached. func (s *Session) Synchronize(jobIds []string, timeout int64, dispose bool) *Error { // TODO handle special string: DRMAA_ID_SESSION_ALL diag := C.makeString(stringSize) defer C.free(unsafe.Pointer(diag)) job_ids := C.makeStringArray(C.int(len(jobIds) + 1)) for i, jobid := range jobIds { C.setString(job_ids, C.CString(jobid), C.int(i)) } C.setString(job_ids, nil, C.int(len(jobIds))) var disp C.int if dispose { disp = C.int(1) } else { disp = C.int(0) } if errNumber := C.drmaa_synchronize(job_ids, C.long(timeout), disp, diag, stringSize); errNumber != C.DRMAA_ERRNO_SUCCESS { ce := makeError(C.GoString(diag), errorId[errNumber]) return &ce } return nil }
// Get the DRM system. func (s *Session) GetDrmSystem() (string, *Error) { diag := C.makeString(stringSize) defer C.free(unsafe.Pointer(diag)) drm := C.makeString(stringSize) defer C.free(unsafe.Pointer(drm)) errNumber := C.drmaa_get_DRM_system(drm, stringSize, diag, stringSize) if errNumber != C.DRMAA_ERRNO_SUCCESS && diag != nil { ce := makeError(C.GoString(diag), errorId[errNumber]) return "", &ce } return C.GoString(drm), nil }
// Disengages a session frmo the DRMAA library and cleans it up. func (s *Session) Exit() *Error { diag := C.makeString(stringSize) defer C.free(unsafe.Pointer(diag)) errNumber := C.drmaa_exit(diag, stringSize) if errNumber != C.DRMAA_ERRNO_SUCCESS && diag != nil { ce := makeError(C.GoString(diag), errorId[errNumber]) return &ce } return nil }
// Deletes (and frees memory) of an allocated job template. // Must be called in to prevent memory leaks. JobTemplates // are not handled in GO garbage collector. func (s *Session) DeleteJobTemplate(jt *JobTemplate) *Error { diag := C.makeString(stringSize) defer C.free(unsafe.Pointer(diag)) // de-allocate job template in memory errNumber := C.drmaa_delete_job_template(jt.jt, diag, stringSize) if errNumber != C.DRMAA_ERRNO_SUCCESS && diag != nil { ce := makeError(C.GoString(diag), errorId[errNumber]) return &ce } return nil }
// Submits a job as an array job. func (s *Session) RunBulkJobs(jt *JobTemplate, start, end, incr int) ([]string, *Error) { var ids *C.drmaa_job_ids_t jobId := C.makeString(jobnameSize) defer C.free(unsafe.Pointer(jobId)) diag := C.makeString(stringSize) defer C.free(unsafe.Pointer(diag)) errNumber := C.drmaa_run_bulk_jobs(&ids, jt.jt, C.int(start), C.int(end), C.int(incr), diag, stringSize) if errNumber != C.DRMAA_ERRNO_SUCCESS && diag != nil { ce := makeError(C.GoString(diag), errorId[errNumber]) return nil, &ce } // collect job ids var jobIds []string for C.drmaa_get_next_job_id(ids, jobId, C.DRMAA_JOBNAME_BUFFER) == C.DRMAA_ERRNO_SUCCESS { jobIds = append(jobIds, C.GoString(jobId)) } return jobIds, nil }
// Allocates a new job template. func (s *Session) AllocateJobTemplate() (jt JobTemplate, err *Error) { if s.initialized == false { // error, need a connection (active session) ce := makeError("No active session", NoActiveSession) return jt, &ce } diag := C.makeString(stringSize) defer C.free(unsafe.Pointer(diag)) //var jtp *C.drmaa_job_template_t errNumber := C.drmaa_allocate_job_template(&jt.jt, diag, stringSize) if errNumber != C.DRMAA_ERRNO_SUCCESS && diag != nil { ce := makeError(C.GoString(diag), errorId[errNumber]) return jt, &ce } return jt, nil }
// private JOB TEMPLATE helpers func setNameValue(jt *C.drmaa_job_template_t, name string, value string) *Error { diag := C.makeString(stringSize) defer C.free(unsafe.Pointer(diag)) n := C.CString(name) defer C.free(unsafe.Pointer(n)) v := C.CString(value) defer C.free(unsafe.Pointer(v)) errNumber := C.drmaa_set_attribute(jt, n, v, diag, stringSize) if errNumber != C.DRMAA_ERRNO_SUCCESS { ce := makeError(C.GoString(diag), errorId[errNumber]) return &ce } return nil }
// vector attributes func setVectorAttributes(jt *JobTemplate, name *C.char, args []string) *Error { diag := C.makeString(stringSize) defer C.free(unsafe.Pointer(diag)) //name := C.CString(C.DRMAA_V_ENV) //defer C.free(unsafe.Pointer(name)) values := C.makeStringArray(C.int(len(args) + 1)) defer C.freeStringArray(values, C.int(len(args)+1)) for i, a := range args { C.setString(values, C.CString(a), C.int(i)) } errNumber := C.drmaa_set_vector_attribute(jt.jt, name, values, diag, stringSize) if errNumber != C.DRMAA_ERRNO_SUCCESS && diag != nil { ce := makeError(C.GoString(diag), errorId[errNumber]) return &ce } return nil }
// Returns the state of a job. func (s *Session) JobPs(jobId string) (PsType, *Error) { outPs := C.int(0) diag := C.makeString(stringSize) defer C.free(unsafe.Pointer(diag)) if errNumber := C.drmaa_job_ps(C.CString(jobId), &outPs, diag, stringSize); errNumber != C.DRMAA_ERRNO_SUCCESS && diag != nil { ce := makeError(C.GoString(diag), errorId[errNumber]) return 0, &ce } var psType PsType switch outPs { case C.DRMAA_PS_UNDETERMINED: psType = PsUndetermined case C.DRMAA_PS_QUEUED_ACTIVE: psType = PsQueuedActive case C.DRMAA_PS_SYSTEM_ON_HOLD: psType = PsSystemOnHold case C.DRMAA_PS_USER_ON_HOLD: psType = PsUserOnHold case C.DRMAA_PS_USER_SYSTEM_ON_HOLD: psType = PsUserSystemOnHold case C.DRMAA_PS_RUNNING: psType = PsRunning case C.DRMAA_PS_SYSTEM_SUSPENDED: psType = PsSystemSuspended case C.DRMAA_PS_USER_SUSPENDED: psType = PsUserSuspended case C.DRMAA_PS_USER_SYSTEM_SUSPENDED: psType = PsUserSystemSuspended case C.DRMAA_PS_DONE: psType = PsDone case C.DRMAA_PS_FAILED: psType = PsFailed } return psType, nil }
// Initializes a DRMAA session. If contact string is "" // a new session is created otherwise an existing session // is connected. func (s *Session) Init(contactString string) *Error { diag := C.makeString(stringSize) defer C.free(unsafe.Pointer(diag)) var errNumber C.int if contactString == "" { errNumber = C.drmaa_init(nil, diag, stringSize) } else { csp := C.CString(contactString) defer C.free(unsafe.Pointer(csp)) errNumber = C.drmaa_init(csp, diag, stringSize) } if errNumber != C.DRMAA_ERRNO_SUCCESS && diag != nil { // convert ERROR string back s.initialized = false ce := makeError(C.GoString(diag), errorId[errNumber]) return &ce } else { s.initialized = true } return nil }
// Controls a job, i.e. terminates, suspends, resumes a job or sets // it in a the hold state or release it from the hold state. func (s *Session) Control(jobId string, action controlType) *Error { diag := C.makeString(stringSize) defer C.free(unsafe.Pointer(diag)) var ca C.int switch action { case Terminate: ca = C.DRMAA_CONTROL_TERMINATE case Suspend: ca = C.DRMAA_CONTROL_SUSPEND case Resume: ca = C.DRMAA_CONTROL_RESUME case Hold: ca = C.DRMAA_CONTROL_HOLD case Release: ca = C.DRMAA_CONTROL_RELEASE } if errNumber := C.drmaa_control(C.CString(jobId), ca, diag, stringSize); errNumber != C.DRMAA_ERRNO_SUCCESS { ce := makeError(C.GoString(diag), errorId[errNumber]) return &ce } return nil }
// Blocks until the job left the DRM system or a timeout is reached and // returns a JobInfo structure. func (s *Session) Wait(jobId string, timeout int64) (jobinfo JobInfo, err *Error) { diag := C.makeString(stringSize) defer C.free(unsafe.Pointer(diag)) job_id_out := C.makeString(jobnameSize) defer C.free(unsafe.Pointer(job_id_out)) // out cstat := C.int(0) var crusage *C.struct_drmaa_attr_values_t if errNumber := C.drmaa_wait(C.CString(jobId), job_id_out, jobnameSize, &cstat, C.long(timeout), &crusage, diag, stringSize); errNumber != C.DRMAA_ERRNO_SUCCESS { ce := makeError(C.GoString(diag), errorId[errNumber]) return jobinfo, &ce } // fill JobInfo struct exited := C.int(0) if errNumber := C.drmaa_wifexited(&exited, cstat, diag, stringSize); errNumber != C.DRMAA_ERRNO_SUCCESS { ce := makeError(C.GoString(diag), errorId[errNumber]) return jobinfo, &ce } if exited == 0 { jobinfo.hasExited = false } else { jobinfo.hasExited = true // set exit status exitstatus := C.int(0) if errNumber := C.drmaa_wifexited(&exitstatus, cstat, diag, stringSize); errNumber != C.DRMAA_ERRNO_SUCCESS { C.drmaa_release_attr_values(crusage) ce := makeError(C.GoString(diag), errorId[errNumber]) return jobinfo, &ce } jobinfo.exitStatus = int64(exitstatus) } signaled := C.int(0) if errNumber := C.drmaa_wifsignaled(&signaled, cstat, diag, stringSize); errNumber != C.DRMAA_ERRNO_SUCCESS { C.drmaa_release_attr_values(crusage) ce := makeError(C.GoString(diag), errorId[errNumber]) return jobinfo, &ce } if signaled == 0 { jobinfo.hasSignaled = false } else { jobinfo.hasSignaled = true termsig := C.makeString(stringSize) defer C.free(unsafe.Pointer(termsig)) if errNumber := C.drmaa_wtermsig(termsig, stringSize, cstat, diag, stringSize); errNumber != C.DRMAA_ERRNO_SUCCESS { C.drmaa_release_attr_values(crusage) ce := makeError(C.GoString(diag), errorId[errNumber]) return jobinfo, &ce } jobinfo.terminationSignal = C.GoString(termsig) } aborted := C.int(0) if errNumber := C.drmaa_wifsignaled(&aborted, cstat, diag, stringSize); errNumber != C.DRMAA_ERRNO_SUCCESS { C.drmaa_release_attr_values(crusage) ce := makeError(C.GoString(diag), errorId[errNumber]) return jobinfo, &ce } if aborted == 0 { jobinfo.hasAborted = false } else { jobinfo.hasAborted = true } coreDumped := C.int(0) if errNumber := C.drmaa_wcoredump(&coreDumped, cstat, diag, stringSize); errNumber != C.DRMAA_ERRNO_SUCCESS { C.drmaa_release_attr_values(crusage) ce := makeError(C.GoString(diag), errorId[errNumber]) return jobinfo, &ce } if coreDumped == 0 { jobinfo.hasCoreDump = false } else { jobinfo.hasCoreDump = true } jobinfo.jobId = C.GoString(job_id_out) // rusage usageLength := C.int(0) if errNumber := C.drmaa_get_num_attr_values(crusage, &usageLength); errNumber != C.DRMAA_ERRNO_SUCCESS { C.drmaa_release_attr_values(crusage) ce := makeError(C.GoString(diag), errorId[errNumber]) return jobinfo, &ce } usageArray := make([]string, 0) for i := 0; i < int(usageLength); i++ { usage := C.makeString(stringSize) defer C.free(unsafe.Pointer(usage)) if C.drmaa_get_next_attr_value(crusage, usage, stringSize) == C.DRMAA_ERRNO_SUCCESS { usageArray = append(usageArray, C.GoString(usage)) } } C.drmaa_release_attr_values(crusage) // make a map out of the array usageMap := make(map[string]string) for i := range usageArray { nameVal := strings.Split(usageArray[i], "=") usageMap[nameVal[0]] = nameVal[1] } jobinfo.resourceUsage = usageMap return jobinfo, nil }