backend

package
v0.0.0-...-1dd1f65 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 26, 2023 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package backend contains style-to-backend resolution.

Package backend contains service models for backend services.

Index

Examples

Constants

View Source
const (
	// CanRunStandalone states that the backend can produce ToStandalone targets.
	CanRunStandalone = 1 << iota
	// CanProduceObj states that the backend's recipes can ToObjRecipe targets.
	CanProduceObj
	// CanProduceExe states that the backend's recipes can produce ToExeRecipe targets.
	CanProduceExe
	// CanLiftLitmus states that the backend can consume LiftLitmus sources.
	CanLiftLitmus
)

Variables

View Source
var (
	// ErrBadSource occurs when the input of a LiftJob has a source set to an unknown value.
	ErrBadSource = errors.New("bad input source")
	// ErrBadTarget occurs when the output of a LiftJob has a target set to an unknown value.
	ErrBadTarget = errors.New("bad output target")
	// ErrUnsupportedFile occurs when we try to determine a LiftInput from a file that can't supply one.
	ErrUnsupportedFile = errors.New("file format not supported as a backend input source")
	// ErrInLitmusBlank occurs when the input file of a lifter job is checked and found to be blank.
	ErrInLitmusBlank = errors.New("input litmus file path blank")
	// ErrOutDirBlank occurs when the output directory of a lifter job is checked and found to be blank.
	ErrOutDirBlank = errors.New("output directory path blank")
)
View Source
var ErrNoMatch = errors.New("no matching backend found")

ErrNoMatch occurs when we can't find a backend that matches the given criteria.

View Source
var ErrNotSupported = errors.New("service doesn't support action")

ErrNotSupported is the error that backends should return if we try to do something they don't support.

Functions

This section is empty.

Types

type Backend

type Backend interface {
	// SingleLifter captures that some backends can lift test-cases into recipes (capability CanLiftLitmus).
	SingleLifter

	// ObsParser captures that any backends that can be run standalone or produce executables
	// (capability CanRunStandalone | CanProduceExe) must give an parser for interpreting their stdout as observations.
	ObsParser

	// Class gets the class of this backend.
	Class() Class
}

Backend contains the various interfaces that a backend can implement.

func ResolveAndInstantiate

func ResolveAndInstantiate(spec Spec, r Resolver) (Backend, error)

ResolveAndInstantiate uses a Resolver to resolve spec's class ID, then uses spec to instantiate the class.

type Capability

type Capability uint8

Capability is the enumeration of things that a backend claims to be able to do.

func (Capability) Satisfies

func (c Capability) Satisfies(c2 Capability) bool

Satisfies is true if this capability contains all capabilities in c2.

Example

ExampleCapability_Satisfies is a runnable example for Capability.Satisfies.

package main

import (
	"fmt"

	"github.com/c4-project/c4t/internal/model/service/backend"
)

func main() {
	c := backend.Capability(backend.CanLiftLitmus | backend.CanRunStandalone)
	fmt.Println(c.Satisfies(0))
	fmt.Println(c.Satisfies(backend.CanLiftLitmus))
	fmt.Println(c.Satisfies(backend.CanRunStandalone))
	fmt.Println(c.Satisfies(backend.CanProduceObj))
	fmt.Println(c.Satisfies(backend.CanLiftLitmus | backend.CanProduceObj))

}
Output:

true
true
true
false
false

func (Capability) String

func (c Capability) String() string

String gets a stringified form of the capability

Example

ExampleCapability_String is a runnable example for Capability.String.

package main

import (
	"fmt"

	"github.com/c4-project/c4t/internal/model/service/backend"
)

func main() {
	fmt.Println(backend.Capability(0))
	fmt.Println(backend.Capability(backend.CanLiftLitmus))
	fmt.Println(backend.Capability(backend.CanRunStandalone))
	fmt.Println(backend.Capability(backend.CanProduceObj))
	fmt.Println(backend.Capability(backend.CanLiftLitmus | backend.CanProduceObj))

}
Output:


lift-litmus
run-standalone
produce-obj
produce-obj+lift-litmus

type Class

type Class interface {
	// Metadata gets information about this type of backend.
	Metadata() Metadata

	// Instantiate instantiates a class, producing a backend.
	Instantiate(spec Spec) Backend

	// Probe probes the local system for specifications that can be used to produce backends of this class.
	// It takes a runner sr and context ctx, for any external programs, and a style ID style that the resolver will
	// resolve to one of these specifications.
	Probe(ctx context.Context, sr service.Runner, style id.ID) ([]NamedSpec, error)
}

Class contains information about a style of backend.

type Criteria

type Criteria struct {
	// IDGlob is a glob pattern for the identifier of the backend.
	IDGlob id.ID
	// StyleGlob is a glob pattern for the style of the backend.
	StyleGlob id.ID
	// Capability specifies which capabilities are needed on the backend.
	Capability Capability
}

Criteria contains the criteria for which a backend should be found.

The criteria is a conjunction of each present criterion in the struct.

func (Criteria) Find

func (c Criteria) Find(specs []NamedSpec, r Resolver) (*NamedSpec, error)

Find tries to find a matching backend in a list of specifications specs, given a resolver r.

Example

ExampleCriteria_String is a runnable example for Criteria.Find.

package main

import (
	"fmt"

	backend2 "github.com/c4-project/c4t/internal/serviceimpl/backend"

	"github.com/c4-project/c4t/internal/id"
	"github.com/c4-project/c4t/internal/model/service/backend"
)

func main() {
	specs := []backend.NamedSpec{
		{ID: id.FromString("herd"), Spec: backend.Spec{Style: id.FromString("herdtools.herd")}},
		{ID: id.FromString("litmus"), Spec: backend.Spec{Style: id.FromString("herdtools.litmus")}},
		{ID: id.FromString("litmus.dev"), Spec: backend.Spec{Style: id.FromString("herdtools.litmus")}},
		{ID: id.FromString("rmem"), Spec: backend.Spec{Style: id.FromString("rmem")}},
	}
	r := &backend2.Resolve

	m1, _ := backend.Criteria{}.Find(specs, r)
	fmt.Println("empty criteria:", m1.ID)
	m2, _ := backend.Criteria{IDGlob: id.FromString("litmus.*")}.Find(specs, r)
	fmt.Println("litmus criteria:", m2.ID)
	m3, _ := backend.Criteria{IDGlob: id.FromString("litmus.dev")}.Find(specs, r)
	fmt.Println("litmus.dev criteria:", m3.ID)
	m4, _ := backend.Criteria{StyleGlob: id.FromString("rmem.*")}.Find(specs, r)
	fmt.Println("rmem criteria:", m4.ID)
	m5, _ := backend.Criteria{Capability: backend.CanLiftLitmus + backend.CanProduceExe}.Find(specs, r)
	fmt.Println("litmus-to-exe criteria:", m5.ID)
	_, err := backend.Criteria{IDGlob: id.FromString("litmus"), StyleGlob: id.FromString("rmem")}.Find(specs, r)
	fmt.Println("unmatchable criteria:", err)
	_, err = backend.Criteria{IDGlob: id.FromString("litmus"), StyleGlob: id.FromString("*.rmem.*")}.Find(specs, r)
	fmt.Println("malformed criteria:", err)

}
Output:

empty criteria: herd
litmus criteria: litmus
litmus.dev criteria: litmus.dev
rmem criteria: rmem
litmus-to-exe criteria: litmus
unmatchable criteria: no matching backend found: id=litmus, style=rmem
malformed criteria: malformed glob expression: more than one '*' character

func (Criteria) Matches

func (c Criteria) Matches(s NamedSpec, r Resolver) (bool, error)

Matches tries to see if s matches this criteria given resolver r.

Example

ExampleCriteria_String is a runnable example for Criteria.Matches.

package main

import (
	"fmt"

	backend2 "github.com/c4-project/c4t/internal/serviceimpl/backend"

	"github.com/c4-project/c4t/internal/id"
	"github.com/c4-project/c4t/internal/model/service/backend"
)

func main() {
	spec := backend.NamedSpec{
		ID:   id.FromString("litmus"),
		Spec: backend.Spec{Style: id.FromString("herdtools.litmus")},
	}

	r := &backend2.Resolve

	m1, _ := backend.Criteria{}.Matches(spec, r)
	fmt.Println("matches empty criteria:", m1)

	m2, _ := backend.Criteria{
		IDGlob:    id.FromString("litmus"),
		StyleGlob: id.FromString("herdtools.*"),
	}.Matches(spec, r)
	fmt.Println("matches first criteria:", m2)

	m3, _ := backend.Criteria{
		IDGlob:    id.FromString("litmus"),
		StyleGlob: id.FromString("herdtools.*.7"),
	}.Matches(spec, r)
	fmt.Println("matches second criteria:", m3)

	m4, _ := backend.Criteria{
		Capability: backend.CanLiftLitmus | backend.CanProduceExe,
	}.Matches(spec, r)
	fmt.Println("matches third criteria:", m4)

	m5, _ := backend.Criteria{
		Capability: backend.CanLiftLitmus | backend.CanProduceObj,
	}.Matches(spec, r)
	fmt.Println("matches fourth criteria:", m5)

	_, err := backend.Criteria{
		IDGlob:    id.FromString("litmus"),
		StyleGlob: id.FromString("*.herdtools.*"),
	}.Matches(spec, r)
	fmt.Println("error for malformed glob:", err)

}
Output:

matches empty criteria: true
matches first criteria: true
matches second criteria: false
matches third criteria: true
matches fourth criteria: false
error for malformed glob: malformed glob expression: more than one '*' character

func (Criteria) String

func (c Criteria) String() string

String outputs a string representation of a set of criteria.

Example

ExampleCriteria_String is a runnable example for Criteria.String.

package main

import (
	"fmt"

	"github.com/c4-project/c4t/internal/id"
	"github.com/c4-project/c4t/internal/model/service/backend"
)

func main() {
	fmt.Println(backend.Criteria{})
	fmt.Println(backend.Criteria{IDGlob: id.FromString("litmus")})
	fmt.Println(backend.Criteria{StyleGlob: id.FromString("herdtools.*")})
	fmt.Println(backend.Criteria{IDGlob: id.FromString("litmus"), StyleGlob: id.FromString("herdtools.*")})
	fmt.Println(backend.Criteria{IDGlob: id.FromString("litmus"), Capability: backend.CanProduceExe})

}
Output:

any
id=litmus
style=herdtools.*
id=litmus, style=herdtools.*
id=litmus, can=produce-exe

type Finder

type Finder interface {
	// FindBackend asks for a backend that matches the given criteria.
	FindBackend(c Criteria) (*NamedSpec, error)
}

Finder is the interface of things that can find backends for machines.

type LiftInput

type LiftInput struct {
	// Source specifies the kind of thing that the lifter should consume.
	Source Source

	// Litmus gives information about an input Litmus test, if any.
	Litmus *litmus.Litmus
}

LiftInput is a specification of the input of a lifting operation.

func InputFromFile

func InputFromFile(ctx context.Context, fpath string, s litmus.StatDumper) (in LiftInput, err error)

InputFromFile tries to divine what sort of lifting input fpath contains. It returns, on success, a determined input.

func LiftLitmusInput

func LiftLitmusInput(l *litmus.Litmus) LiftInput

LiftLitmusInput is shorthand for creating a LiftInput over the litmus test l.

func (LiftInput) Check

func (l LiftInput) Check() error

Check makes sure that this lift input has a valid source and the data required for it.

type LiftJob

type LiftJob struct {
	// Arch is the ID of the architecture for which a recipe should be prepared, if the recipe is architecture-specific.
	Arch id.ID

	// In is the input specification for this job.
	In LiftInput

	// Out is the output specification for this job.
	Out LiftOutput
}

LiftJob is a specification of how to lift a test into a compilable recipe.

func (LiftJob) Check

func (l LiftJob) Check() error

Check performs several in-flight checks on a lifter job.

type LiftOutput

type LiftOutput struct {
	// Dir specifies the output directory into which the lifter should put outputs.
	Dir string

	// Target specifies the kind of thing that the lifter should create.
	Target Target
}

LiftOutput is a specification of the output of a lifting operation.

func (LiftOutput) Check

func (l LiftOutput) Check() error

Check makes sure that this lift output has a valid target and the data required for it.

func (LiftOutput) Files

func (l LiftOutput) Files() ([]string, error)

Files reads s.OutDir as a directory and returns the names of its contents. This is useful for using a recipe job to feed a compiler job.

type Metadata

type Metadata struct {
	// Capabilities is the set of capability flags enabled on this backend.
	Capabilities Capability

	// LitmusArches is the list of Litmus architectures understood by this backend (capability CanLiftLitmus).
	LitmusArches []id.ID
}

Metadata contains metadata for a backend archetype.

type NamedSpec

type NamedSpec struct {
	// ID is the ID of the backend.
	ID id.ID `toml:"id"`

	Spec
}

NamedSpec wraps a Spec with its ID.

type ObsParser

type ObsParser interface {
	// ParseObs parses the observation in reader r into o according to the backend configuration in b.
	// The backend described by b must have been used to produce the testcase outputting r.
	ParseObs(ctx context.Context, r io.Reader, o *obs.Obs) error
}

ObsParser is the interface of things that can parse test outcomes.

type Prober

type Prober interface {
	// Probe uses sr to probe for backends.
	Probe(ctx context.Context, sr service.Runner) ([]NamedSpec, error)
}

Prober is the interface of types that support backend probing.

type Resolver

type Resolver interface {
	// Resolve tries to resolve the class ID cid into a backend class.
	Resolve(cid id.ID) (Class, error)

	// Probe uses sr to probe for backend specifications on this machine.
	Probe(ctx context.Context, sr service.Runner) ([]NamedSpec, error)
}

Resolver is the interface of things that can resolve backends.

type RunJob

type RunJob struct {
	// Recipe is a pointer to the recipe that was fed into the compile stage for this compilation; this is useful for
	// backends that don't compile, and instead peruse files from the compiler recipe.
	Recipe *recipe.Recipe

	// CompileResult is a pointer to the result of any compilation that was done for the running.
	// It may be nil if there was no compilation.
	CompileResult *compilation.CompileResult

	// Obs points to the observation record that should be filled out by the runner.
	Obs *obs.Obs
}

RunJob is the type of jobs being sent to a backend for running.

type Runner

type Runner interface {
	// RunBackend runs the backend run job j.
	RunBackend(ctx context.Context, j *RunJob) error
}

Runner is the interface that backends must implement to slot into the machine node runner.

type SingleLifter

type SingleLifter interface {
	// Lift performs the lifting described by j.
	// It returns a recipe describing the files (C files, header files, etc.) created and how to use them, or an error.
	// Any external service running should happen by sr.
	Lift(ctx context.Context, j LiftJob, sr service.Runner) (recipe.Recipe, error)
}

SingleLifter is an interface capturing the ability to lift single jobs into recipes.

type Source

type Source uint8

Source is the enumeration of possible input types to a lift job.

const (
	// LiftUnknown states that the lifting source is unknown.
	LiftUnknown Source = iota
	// LiftLitmus states that the backend takes Litmus tests.
	// The backend may further specify particular architectures it can handle.
	LiftLitmus
)

func (Source) String

func (i Source) String() string

type Spec

type Spec struct {
	// Style is the declared style of the backend.
	Style id.ID `toml:"style" json:"style"`

	// Run contains information on how to run the backend; if given, this overrides any default RunInfo for the backend.
	Run *service.RunInfo `toml:"run,omitempty" json:"run,omitempty"`
}

Spec tells the tester how to run a backend.

type Target

type Target uint8

Target is the enumeration of targets of a backend.

const (
	// ToDefault states that the lifting backend should perform its default lifting.
	ToDefault Target = iota
	// ToStandalone states that the backend should run in a standalone manner in the running phase, without compilation.
	// The backend can still produce files and include them in the recipe, but should not produce instructions.
	ToStandalone
	// ToObjRecipe states that the backend should produce a recipe that emits one or more object files.
	ToObjRecipe
	// ToExeRecipe states that the backend should produce a recipe that emits a compilable executable.
	ToExeRecipe
)

func (Target) String

func (i Target) String() string

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL