type Job { id: ID! # Database ID, unique jobId: String! # ID given to the job by the cluster scheduler userId: String! # Username projectId: String! # Project clusterId: String! # Name of the cluster this job was running on startTime: Time! # RFC3339 formated string duration: Int! # For running jobs, the time it has already run numNodes: Int! # Number of nodes this job was running on nodes: [String!]! # List of hostnames hasProfile: Boolean! # TODO: Could be removed? state: JobState! # State of the job tags: [JobTag!]! # List of tags this job has # Will be null for running jobs. loadAvg: Float memUsedMax: Float flopsAnyAvg: Float memBwAvg: Float netBwAvg: Float fileBwAvg: Float } # TODO: Extend by more possible states? enum JobState { running completed } type JobTag { id: ID! # Database ID, unique tagType: String! # Type tagName: String! # Name } type Cluster { clusterID: String! processorType: String! socketsPerNode: Int! coresPerSocket: Int! threadsPerCore: Int! flopRateScalar: Int! flopRateSimd: Int! memoryBandwidth: Int! metricConfig: [MetricConfig!]! filterRanges: FilterRanges! } type MetricConfig { name: String! unit: String! sampletime: Int! peak: Int! normal: Int! caution: Int! alert: Int! } type JobMetric { unit: String! scope: JobMetricScope! timestep: Int! series: [JobMetricSeries!]! } type JobMetricSeries { node_id: String! statistics: JobMetricStatistics data: [NullableFloat!]! } type JobMetricStatistics { avg: Float! min: Float! max: Float! } type JobMetricWithName { name: String! metric: JobMetric! } type MetricFootprints { name: String! footprints: [NullableFloat!]! } enum Aggregate { USER, PROJECT, CLUSTER } type Query { clusters: [Cluster!]! # List of all clusters tags: [JobTag!]! # List of all tags job(id: ID!): Job jobMetrics(id: ID!, metrics: [String!]): [JobMetricWithName!]! jobsFootprints(filter: [JobFilter!], metrics: [String!]!): [MetricFootprints]! jobs(filter: [JobFilter!], page: PageRequest, order: OrderByInput): JobResultList! jobsStatistics(filter: [JobFilter!], groupBy: Aggregate): [JobsStatistics!]! rooflineHeatmap(filter: [JobFilter!]!, rows: Int!, cols: Int!, minX: Float!, minY: Float!, maxX: Float!, maxY: Float!): [[Float!]!]! } type Mutation { createTag(type: String!, name: String!): JobTag! deleteTag(id: ID!): ID! addTagsToJob(job: ID!, tagIds: [ID!]!): [JobTag!]! removeTagsFromJob(job: ID!, tagIds: [ID!]!): [JobTag!]! updateConfiguration(name: String!, value: String!): String } type IntRangeOutput { from: Int! to: Int! } type TimeRangeOutput { from: Time! to: Time! } type FilterRanges { duration: IntRangeOutput! numNodes: IntRangeOutput! startTime: TimeRangeOutput! } input JobFilter { tags: [ID!] jobId: StringInput userId: StringInput projectId: StringInput clusterId: StringInput duration: IntRange numNodes: IntRange startTime: TimeRange isRunning: Boolean flopsAnyAvg: FloatRange memBwAvg: FloatRange loadAvg: FloatRange memUsedMax: FloatRange } input OrderByInput { field: String! order: SortDirectionEnum! = ASC } enum SortDirectionEnum { DESC ASC } input StringInput { eq: String contains: String startsWith: String endsWith: String } input IntRange { from: Int! to: Int! } input FloatRange { from: Float! to: Float! } input TimeRange { from: Time to: Time } type JobResultList { items: [Job!]! offset: Int limit: Int count: Int } type HistoPoint { count: Int! value: Int! } type JobsStatistics { id: ID! # If `groupBy` was used, ID of the user/project/cluster totalJobs: Int! # Number of jobs that matched shortJobs: Int! # Number of jobs with a duration of less than 2 minutes totalWalltime: Int! # Sum of the duration of all matched jobs in hours totalCoreHours: Int! # Sum of the core hours of all matched jobs histWalltime: [HistoPoint!]! # value: hour, count: number of jobs with a rounded duration of value histNumNodes: [HistoPoint!]! # value: number of nodes, count: number of jobs with that number of nodes } input PageRequest { itemsPerPage: Int! page: Int! } scalar Time scalar NullableFloat scalar JobMetricScope