Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
254 changes: 254 additions & 0 deletions src/CUDARequirement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@

import {
Dictionary,
expandUrl,
loadField,
LoaderInstances,
LoadingOptions,
Saveable,
ValidationException,
prefixUrl,
save,
saveRelativeUri
} from './util/Internal'
import { v4 as uuidv4 } from 'uuid'
import * as Internal from './util/Internal'


/**
* Auto-generated class implementation for http://commonwl.org/cwltool#CUDARequirement
*
* Require support for NVIDA CUDA (GPU hardware acceleration).
*
*/
export class CUDARequirement extends Saveable implements Internal.CUDARequirementProperties {
extensionFields?: Internal.Dictionary<any>

/**
* cwltool:CUDARequirement
*/
class_: string

/**
* CUDA hardware capability required to run the software, in X.Y
* format.
*
* * If this is a single value, it defines only the minimum
* compute capability. GPUs with higher capability are also
* accepted.
*
* * If it is an array value, then only select GPUs with compute
* capabilities that explicitly appear in the array.
*
*/
cudaComputeCapability: string | Array<string>

/**
* Maximum number of GPU devices to request. If not specified,
* same as `cudaDeviceCountMin`.
*
*/
cudaDeviceCountMax?: undefined | number | string

/**
* Minimum number of GPU devices to request. If not specified,
* same as `cudaDeviceCountMax`. If neither are specified,
* default 1.
*
*/
cudaDeviceCountMin?: undefined | number | string

/**
* Minimum CUDA version to run the software, in X.Y format. This
* corresponds to a CUDA SDK release. When running directly on
* the host (not in a container) the host must have a compatible
* CUDA SDK (matching the exact version, or, starting with CUDA
* 11.3, matching major version). When run in a container, the
* container image should provide the CUDA runtime, and the host
* driver is injected into the container. In this case, because
* CUDA drivers are backwards compatible, it is possible to
* use an older SDK with a newer driver across major versions.
*
* See https://docs.nvidia.com/deploy/cuda-compatibility/ for
* details.
*
*/
cudaVersionMin: string


constructor ({loadingOptions, extensionFields, class_ = 'CUDARequirement', cudaComputeCapability, cudaDeviceCountMax, cudaDeviceCountMin, cudaVersionMin} : {loadingOptions?: LoadingOptions} & Internal.CUDARequirementProperties) {
super(loadingOptions)
this.extensionFields = extensionFields ?? {}
this.class_ = class_
this.cudaComputeCapability = cudaComputeCapability
this.cudaDeviceCountMax = cudaDeviceCountMax
this.cudaDeviceCountMin = cudaDeviceCountMin
this.cudaVersionMin = cudaVersionMin
}

/**
* Used to construct instances of {@link CUDARequirement }.
*
* @param __doc Document fragment to load this record object from.
* @param baseuri Base URI to generate child document IDs against.
* @param loadingOptions Context for loading URIs and populating objects.
* @param docRoot ID at this position in the document (if available)
* @returns An instance of {@link CUDARequirement }
* @throws {@link ValidationException} If the document fragment is not a
* {@link Dictionary} or validation of fields fails.
*/
static override async fromDoc (__doc: any, baseuri: string, loadingOptions: LoadingOptions,
docRoot?: string): Promise<Saveable> {
const _doc = Object.assign({}, __doc)
const __errors: ValidationException[] = []

let class_
try {
class_ = await loadField(_doc.class, LoaderInstances.uristrtypeFalseTrueNoneNone,
baseuri, loadingOptions)
} catch (e) {
if (e instanceof ValidationException) {
__errors.push(
new ValidationException('the `class` field is not valid because: ', [e])
)
} else {
throw e
}
}

let cudaComputeCapability
try {
cudaComputeCapability = await loadField(_doc.cudaComputeCapability, LoaderInstances.unionOfstrtypeOrarrayOfstrtype,
baseuri, loadingOptions)
} catch (e) {
if (e instanceof ValidationException) {
__errors.push(
new ValidationException('the `cudaComputeCapability` field is not valid because: ', [e])
)
} else {
throw e
}
}

let cudaDeviceCountMax
if ('cudaDeviceCountMax' in _doc) {
try {
cudaDeviceCountMax = await loadField(_doc.cudaDeviceCountMax, LoaderInstances.unionOfundefinedtypeOrinttypeOrExpressionLoader,
baseuri, loadingOptions)
} catch (e) {
if (e instanceof ValidationException) {
__errors.push(
new ValidationException('the `cudaDeviceCountMax` field is not valid because: ', [e])
)
} else {
throw e
}
}
}

let cudaDeviceCountMin
if ('cudaDeviceCountMin' in _doc) {
try {
cudaDeviceCountMin = await loadField(_doc.cudaDeviceCountMin, LoaderInstances.unionOfundefinedtypeOrinttypeOrExpressionLoader,
baseuri, loadingOptions)
} catch (e) {
if (e instanceof ValidationException) {
__errors.push(
new ValidationException('the `cudaDeviceCountMin` field is not valid because: ', [e])
)
} else {
throw e
}
}
}

let cudaVersionMin
try {
cudaVersionMin = await loadField(_doc.cudaVersionMin, LoaderInstances.strtype,
baseuri, loadingOptions)
} catch (e) {
if (e instanceof ValidationException) {
__errors.push(
new ValidationException('the `cudaVersionMin` field is not valid because: ', [e])
)
} else {
throw e
}
}

const extensionFields: Dictionary<any> = {}
for (const [key, value] of Object.entries(_doc)) {
if (!CUDARequirement.attr.has(key)) {
if ((key as string).includes(':')) {
const ex = expandUrl(key, '', loadingOptions, false, false)
extensionFields[ex] = value
} else {
__errors.push(
new ValidationException(`invalid field ${key as string}, \
expected one of: \`class\`,\`cudaComputeCapability\`,\`cudaDeviceCountMax\`,\`cudaDeviceCountMin\`,\`cudaVersionMin\``)
)
break
}
}
}

if (__errors.length > 0) {
throw new ValidationException("Trying 'CUDARequirement'", __errors)
}

const schema = new CUDARequirement({
extensionFields: extensionFields,
loadingOptions: loadingOptions,
class_: class_,
cudaComputeCapability: cudaComputeCapability,
cudaDeviceCountMax: cudaDeviceCountMax,
cudaDeviceCountMin: cudaDeviceCountMin,
cudaVersionMin: cudaVersionMin
})
return schema
}

save (top: boolean = false, baseUrl: string = '', relativeUris: boolean = true)
: Dictionary<any> {
const r: Dictionary<any> = {}
for (const ef in this.extensionFields) {
r[prefixUrl(ef, this.loadingOptions.vocab)] = this.extensionFields.ef
}

if (this.class_ != null) {
const u = saveRelativeUri(this.class_, baseUrl, false,
relativeUris, undefined)
if (u != null) {
r.class = u
}
}

if (this.cudaComputeCapability != null) {
r.cudaComputeCapability = save(this.cudaComputeCapability, false, baseUrl, relativeUris)
}

if (this.cudaDeviceCountMax != null) {
r.cudaDeviceCountMax = save(this.cudaDeviceCountMax, false, baseUrl, relativeUris)
}

if (this.cudaDeviceCountMin != null) {
r.cudaDeviceCountMin = save(this.cudaDeviceCountMin, false, baseUrl, relativeUris)
}

if (this.cudaVersionMin != null) {
r.cudaVersionMin = save(this.cudaVersionMin, false, baseUrl, relativeUris)
}

if (top) {
if (this.loadingOptions.namespaces != null) {
r.$namespaces = this.loadingOptions.namespaces
}
if (this.loadingOptions.schemas != null) {
r.$schemas = this.loadingOptions.schemas
}
}
return r
}

static attr: Set<string> = new Set(['class','cudaComputeCapability','cudaDeviceCountMax','cudaDeviceCountMin','cudaVersionMin'])
}
65 changes: 65 additions & 0 deletions src/CUDARequirementProperties.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@

import * as Internal from './util/Internal'


/**
* Auto-generated interface for http://commonwl.org/cwltool#CUDARequirement
*
* Require support for NVIDA CUDA (GPU hardware acceleration).
*
*/
export interface CUDARequirementProperties extends Internal.ProcessRequirementProperties {

extensionFields?: Internal.Dictionary<any>

/**
* cwltool:CUDARequirement
*/
class_?: string

/**
* CUDA hardware capability required to run the software, in X.Y
* format.
*
* * If this is a single value, it defines only the minimum
* compute capability. GPUs with higher capability are also
* accepted.
*
* * If it is an array value, then only select GPUs with compute
* capabilities that explicitly appear in the array.
*
*/
cudaComputeCapability: string | Array<string>

/**
* Maximum number of GPU devices to request. If not specified,
* same as `cudaDeviceCountMin`.
*
*/
cudaDeviceCountMax?: undefined | number | string

/**
* Minimum number of GPU devices to request. If not specified,
* same as `cudaDeviceCountMax`. If neither are specified,
* default 1.
*
*/
cudaDeviceCountMin?: undefined | number | string

/**
* Minimum CUDA version to run the software, in X.Y format. This
* corresponds to a CUDA SDK release. When running directly on
* the host (not in a container) the host must have a compatible
* CUDA SDK (matching the exact version, or, starting with CUDA
* 11.3, matching major version). When run in a container, the
* container image should provide the CUDA runtime, and the host
* driver is injected into the container. In this case, because
* CUDA drivers are backwards compatible, it is possible to
* use an older SDK with a newer driver across major versions.
*
* See https://docs.nvidia.com/deploy/cuda-compatibility/ for
* details.
*
*/
cudaVersionMin: string
}
19 changes: 0 additions & 19 deletions src/CWLVersion.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,4 @@

export enum CWLVersion {
DRAFT_2='draft-2',
DRAFT_3_DEV1='draft-3.dev1',
DRAFT_3_DEV2='draft-3.dev2',
DRAFT_3_DEV3='draft-3.dev3',
DRAFT_3_DEV4='draft-3.dev4',
DRAFT_3_DEV5='draft-3.dev5',
DRAFT_3='draft-3',
DRAFT_4_DEV1='draft-4.dev1',
DRAFT_4_DEV2='draft-4.dev2',
DRAFT_4_DEV3='draft-4.dev3',
V1_0_DEV4='v1.0.dev4',
V1_0='v1.0',
V1_1_0_DEV1='v1.1.0-dev1',
V1_1='v1.1',
V1_2_0_DEV1='v1.2.0-dev1',
V1_2_0_DEV2='v1.2.0-dev2',
V1_2_0_DEV3='v1.2.0-dev3',
V1_2_0_DEV4='v1.2.0-dev4',
V1_2_0_DEV5='v1.2.0-dev5',
V1_2='v1.2',
}
8 changes: 4 additions & 4 deletions src/CommandInputParameter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ export class CommandInputParameter extends Saveable implements Internal.CommandI
extensionFields?: Internal.Dictionary<any>

/**
* The unique identifier for this object.
* The unique identifier for this Parameter.
*/
id?: undefined | string
id: string

/**
* A short, human-readable label of this object.
Expand Down Expand Up @@ -192,7 +192,7 @@ export class CommandInputParameter extends Saveable implements Internal.CommandI
let id
if ('id' in _doc) {
try {
id = await loadField(_doc.id, LoaderInstances.uriunionOfundefinedtypeOrstrtypeTrueFalseNoneNone,
id = await loadField(_doc.id, LoaderInstances.uristrtypeTrueFalseNoneNone,
baseuri, loadingOptions)
} catch (e) {
if (e instanceof ValidationException) {
Expand All @@ -210,7 +210,7 @@ export class CommandInputParameter extends Saveable implements Internal.CommandI
if (docRoot != null) {
id = docRoot
} else {
id = "_" + uuidv4()
throw new ValidationException("Missing id")
}
} else {
baseuri = id as string
Expand Down
4 changes: 2 additions & 2 deletions src/CommandInputParameterProperties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ export interface CommandInputParameterProperties extends Internal.InputParameter
extensionFields?: Internal.Dictionary<any>

/**
* The unique identifier for this object.
* The unique identifier for this Parameter.
*/
id?: undefined | string
id: string

/**
* A short, human-readable label of this object.
Expand Down
2 changes: 0 additions & 2 deletions src/CommandLineBindableProperties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import * as Internal from './util/Internal'
*/
export interface CommandLineBindableProperties {

extensionFields?: Internal.Dictionary<any>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would adding this back in resolve this ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried that, but then there are other validation issues: https://github.com/common-workflow-lab/cwl-ts-auto/actions/runs/20676696133/job/59365273384

The removal is legitimate, as the class is now abstract..

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

class is now abstract

Yes but the object constructor still expects the extension fields, such as https://github.com/common-workflow-lab/cwl-ts-auto/blob/regen_20260103/src/CommandLineBindable.ts#L88

So you either need to either remove the extension fields from those types of calls, OR update the constructor type to add in the extension fields type (which was previously just in the CommandLineBindable properties), like so

This constructor

  constructor ({loadingOptions, extensionFields, inputBinding} : {loadingOptions?: LoadingOptions} & Internal.CommandLineBindableProperties) {

to

  constructor ({loadingOptions, extensionFields, inputBinding} : {loadingOptions?: LoadingOptions} & Internal.Dictionary<any> & Internal.CommandLineBindableProperties) {

I tried that, but then there are other validation issues

Yep because id is now set to 'mandatory' in many of the fields, such as https://github.com/common-workflow-lab/cwl-ts-auto/pull/43/changes#diff-07abac72669befd367f8ae59ac50db4ca16d87201905fb78ab737201b14488a6R27 but none of the cwl tests have 'id' in their attributes? If this is intentional, we will need to update the script that generates the cwl schema to ensure that the 'id' attribute is removed from the required fields, which shouldn't be too difficult.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like some of the SALAD processing for maps isn't happening, either on the Typescript side or the JSON schema generation/testing side.

https://www.commonwl.org/v1.2/Workflow.html#map

For example, the id field for WorkflowStepInput (used by the in field of a workflow step) is rarely in the long form:

class: Workflow
inputs:
  message: string
steps:
  a_step:
    run: something.cwl
    in:
      - id: an_input
        source: message
# […]

but usually written in the short form:

class: Workflow
inputs:
  message: string
steps:
  a_step:
    run: something.cwl
    in:
      an_input: message
# […]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can manually remove the 'id' fields in these sections from the json schema, that's why we generate the cwl-raw file and then the curated schema from that as the typescript isn't a perfect representation of a CWL file.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can manually remove the 'id' fields in these sections from the json schema, that's why we generate the cwl-raw file and then the curated schema from that as the typescript isn't a perfect representation of a CWL file.

The JSON schema should be modified to support all variations of the map syntax. I guess that information isn't present in the TypeScript objects because the loader functions take care of the variations. So the post-processing from the TypeScript to JSON Schema is going to need additional information on where to encode the map varients.

That information is in the SALAD definition of CWL.

I see at least 3 options to move forward:

A. Record the information about the map field variations during the TypeScript code generation that produced this repository. Use that information in a post-processing step after the TypeScript objects to JSON Schema generation.

or

B. Create schema-salad-tool --codegen json-schema to directly output JSON schema, taking into account all the map field varients.

or

C. Create manual patches to apply to the generated JSON Schema, updating them as the CWL 1.2 schema continues to be refined, and manually porting them for the future CWL versions.

I feel like Option B is the most future-proofed and brings value to other SALAD users, but also the most work. In some ways it won't be as difficult as the other additions of new codegen targets as we have two examples of what JSON Schema for CWL would look like.

I can assist with all of these options, but I'm not available to do any of these options entirely myself.


/**
* Describes how to turn this object into command line arguments.
*/
Expand Down
Loading
Loading