Lewati ke konten
DispatchAtlas
Cari

Kontrak domain

dispatchatlas.core adalah batas paket internal. Ia menggunakan objek yang tidak dapat diubah dan hanya dari pustaka standar agar benchmark, solver, eksperimen, analisis, dan dokumentasi mengonsumsi satu kosakata penjadwalan bersama.

🗂️ Model penjadwalan

Masalah direpresentasikan dengan ProblemSpec, TaskSpec, ResourceSpec, Dependency, Objective, dan Constraint. Jadwal kandidat menggunakan Assignment, Schedule, ObjectiveValue, dan ScheduleResult.

Validasi bersifat eksplisit:

from dispatchatlas.core import (
    Duration,
    Objective,
    ObjectiveSense,
    ProblemId,
    ProblemSpec,
    ResourceAmount,
    ResourceId,
    ResourceRequirement,
    ResourceSpec,
    TaskId,
    TaskSpec,
    validate_problem,
)
 
cpu = ResourceId("cpu")
 
problem = ProblemSpec(
    id=ProblemId("smoke"),
    tasks=(
        TaskSpec(
            TaskId("task-a"),
            Duration(1.0),
            demands=(ResourceRequirement(cpu, ResourceAmount(1.0)),),
        ),
    ),
    resources=(ResourceSpec(cpu, ResourceAmount(1.0)),),
    objectives=(Objective("makespan", ObjectiveSense.MINIMIZE),),
)
 
validated = validate_problem(problem)

validate_problem mengembalikan sebuah ValidatedProblem dengan cap validasi dan laporan yang dapat dibaca mesin. validate_schedule memeriksa cakupan tugas, kapasitas sumber daya, batas waktu, dan dependensi.

🔗 Koalokasi multisumber-daya

Sebuah tugas dapat menuntut lebih dari satu sumber daya sekaligus. TaskSpec.demands adalah tuple dari ResourceRequirement, dan konstruktor jadwal mengoalokasikan tugas ke setiap sumber daya yang dituntutnya, menahannya bersama selama seluruh durasi tugas. Karena itu jadwal kandidat mencatat setiap penempatan sebagai Assignment.resource_ids — sebuah tuple, bukan satu sumber daya — dan validate_schedule memastikan dua tugas yang tumpang tindih dalam waktu tidak pernah berbagi sumber daya.

Graf konflik sumber daya adalah tuas penjadwalan: dua tugas yang himpunan tuntutannya berpotongan harus diserialkan, sementara dua yang himpunannya saling lepas berjalan secara konkuren.

from dispatchatlas.core import ResourceAmount, ResourceId, ResourceRequirement
 
# A task that co-allocates a compute node and an accelerator simultaneously.
demands = (
    ResourceRequirement(ResourceId("edge-0"), ResourceAmount(1.0)),
    ResourceRequirement(ResourceId("gpu-1"), ResourceAmount(1.0)),
)

Keluarga kontinum accelerator-coscheduling, distributed-transaction dan fpga-partitioning menggunakan tuas ini — yang pertama dengan penahanan komputasi-plus-akselerator tetap, yang kedua dengan himpunan kunci berkardinalitas variabel atas pecahan data. Yang dapat dijalankan examples/inspect_coallocation.py menjadwalkan keduanya dan menunjukkan tugas bersumber-daya lepas berjalan paralel sementara tugas yang berbagi sumber daya diserialkan.

🧩 Eksekusi moldable

Sebuah tugas dapat berjalan dalam salah satu dari beberapa mode. TaskSpec.modes adalah tuple dari TaskMode — masing-masing pasangan (demands, duration), di mana mode yang lebih lebar (yang menuntut lebih banyak sumber daya) berjalan lebih singkat, percepatan moldable. Ketika modes ditetapkan, tugas bersifat moldable: konstruktor jadwal memilih, per tugas, mode yang selesai paling awal mengingat sumber daya yang bebas, sehingga urutan jadwal memutuskan berapa banyak paralelisme yang diklaim tiap tugas. Tugas rigid membiarkan modes tidak ditetapkan (default) dan duration serta demands tingkat atasnya adalah satu-satunya modenya, yang dijadwalkan backend eksak sebagai referensi konservatif. validate_schedule memastikan setiap penempatan cocok dengan satu mode yang dideklarasikan, dan eksekusi moldable dan tak-presisi (mandatory_duration) saling eksklusif — sebuah tugas memilih paralelismenya atau membuang pekerjaan opsional, bukan keduanya.

from dispatchatlas.core import (
    Duration,
    ResourceAmount,
    ResourceId,
    ResourceRequirement,
    TaskMode,
)
 
# Two ways to run one job: wide-and-fast on two workers, or narrow-and-slow on one.
modes = (
    TaskMode(
        demands=(
            ResourceRequirement(ResourceId("worker-0"), ResourceAmount(1.0)),
            ResourceRequirement(ResourceId("worker-1"), ResourceAmount(1.0)),
        ),
        duration=Duration(1.0),
    ),
    TaskMode(
        demands=(ResourceRequirement(ResourceId("worker-0"), ResourceAmount(1.0)),),
        duration=Duration(1.8),
    ),
)

Keluarga kontinum elastic-serverless-autoscale menggunakan tuas ini: setiap invokasi fungsi dapat berskala ke satu, dua, atau empat pekerja yang diambil dari kolam burst bersama yang kecil, sehingga urutan jadwal memutuskan invokasi mana yang mengklaim mode lebar-dan-cepat yang langka dan mana yang berjalan sempit — sebuah kompromi antara latensi dan biaya sumber daya.

🛰️ Kojadwal gang

Tugas-tugas yang berbagi TaskSpec.gang_id membentuk sebuah gang yang pekerja-pekerjanya harus semua mulai pada saat yang sama pada sumber daya berbeda — sebuah komulai semua-atau-tidak-sama-sekali, sebagaimana pekerjaan pelatihan-terdistribusi atau MPI yang sinkron memerlukan para pekerjanya berjalan bersama. Konstruktor serial menempatkan satu gang penuh secara atomik pada saat paling awal ketika sumber daya setiap pekerja bebas, bahkan ketika satu pekerja bisa saja mulai lebih awal sendirian; validate_schedule menolak gang yang pekerjanya tidak komulai (schedule.feasibility.gang_cosched). Pekerja gang bersifat rigid (bukan moldable), karena gang komulai pada lebar tetap; tugas independen membiarkan gang_id tidak ditetapkan.

from dispatchatlas.core import (
    Duration,
    ResourceAmount,
    ResourceId,
    ResourceRequirement,
    TaskId,
    TaskSpec,
)
 
# Two workers of one training job that must launch together on distinct accelerators.
gang = "train-job-0"
workers = tuple(
    TaskSpec(
        id=TaskId(f"worker-{index}"),
        duration=Duration(2.0),
        demands=(ResourceRequirement(ResourceId(f"acc-{index}"), ResourceAmount(1.0)),),
        gang_id=gang,
    )
    for index in range(2)
)

Keluarga kontinum distributed-training-gang menggunakan tuas ini: gang dua hingga empat pekerja menggunakan kembali kolam akselerator bersama dan pekerjaan tiba dari waktu ke waktu, sehingga sebuah pekerjaan tidak dapat dimulai sampai cukup akselerator bebas secara bersamaan dan urutan jadwal memutuskan pekerjaan mana yang lebih dulu memperoleh himpunan pekerja penuhnya.

⚖️ Pembagian adil multipenyewa

Tugas membawa TaskSpec.tenant_id opsional yang melabeli penyewa pemiliknya untuk akuntansi pembagian adil multipenyewa. Tujuan dominant-resource-share (ObjectiveKind.DOMINANT_RESOURCE_SHARE, menurut keadilan sumber daya dominan dari Ghodsi dkk.) menilai seberapa merata bagian dominan para penyewa diseimbangkan: bagian dominan tiap penyewa adalah fraksi terbesar, lintas sumber daya, dari kapasitas-waktu total sebuah sumber daya yang ditempati tugasnya, dan tujuannya adalah sebaran antara penyewa yang paling banyak dan paling sedikit dilayani — 0.0 untuk jadwal berbagian-dominan-setara (adil), lebih tinggi ketika satu penyewa memonopoli sumber daya dominannya. Tujuan ini bersifat minimasi dan mengembalikan DEFERRED pada instans tanpa penyewa. tenant_id ortogonal terhadap eksekusi gang, moldable, dan tak-presisi — tugas seorang penyewa bisa salah satu di antaranya; tugas tanpa penyewa membiarkan tenant_id tidak ditetapkan.

Tuasnya adalah penempatan, bukan urutan jadwal: okupansi sumber daya total seorang penyewa ditetapkan oleh bebannya, jadi pada sumber daya mana tugasnya mendarat itulah yang menyeimbangkan atau membiaskan bagian dominan. Yang dapat dijalankan examples/multi_tenant_fairshare_study.py menilai penempatan adil (tersebar) versus penempatan memonopoli atas penyewa berat dan penyewa ringan pada kolam tiga node, menjadikan tuasnya eksplisit.

⏱️ Tenggat keras dan lunak

Sebuah tugas dapat membawa tenggat penyelesaian TaskSpec.deadline, dan TaskSpec.deadline_kind mengklasifikasikan bagaimana sebuah kelewatan dinilai. Default ConstraintKind.HARD menjadikan tenggat yang terlewat sebagai pelanggaran kelayakan: validate_schedule memunculkan masalah pemblokir schedule.feasibility.deadline dan jadwal dilaporkan tak-layak. ConstraintKind.SOFT menjadikan kelewatan yang sama hanya penalti keterlambatan — jadwal tetap layak sementara kelebihannya terakumulasi ke tujuan lateness (ObjectiveKind.LATENESS), sehingga tugas waktu-nyata-lunak dipenalti karena keterlambatan tanpa membuat jadwal tak-layak. Jenis ini tidak berefek ketika deadline tidak ditetapkan.

Dua pembacaan tenggat bersifat independen: tenggat keras membatasi wilayah layak sementara tenggat lunak membentuk permukaan tujuan, dan sebuah tugas dapat memakai salah satunya. Yang dapat dijalankan examples/infeasibility_study.py menelusuri kasus tenggat keras dari ujung ke ujung — sebuah instans terlalu-terkendala dilaporkan tak-layak, dan urutan paling-tak-layak ketika tidak ada jadwal layak yang eksis.

💰 Model biaya

Penjadwalan yang sadar-biaya dideskripsikan oleh CostModel, sebuah artefak tak dapat diubah yang terpisah, tertaut ke sebuah masalah lewat pengenalnya. Menjaga lapisan biaya di luar ProblemSpec membuat sebuah masalah dan data biayanya dapat diversikan dan diserialkan secara independen. Sebuah model biaya membundel lima kontrak opsional:

  • ExecutionTimeMatrix — waktu pemrosesan mesin-tak-terkait (p_ij) untuk keluarga R||Cmax. Matriks ini jarang: pasangan (task, machine) yang absen berarti tugas tidak bisa berjalan di sana, dan menanyakannya memunculkan kesalahan alih-alih default ke nol.
  • CompatibilityMask — himpunan kelayakan tugas-ke-mesin eksplisit, dijaga terpisah dari matriks eksekusi agar kelayakan dan waktu yang ditabulasi dapat berbeda.
  • SetupMatrix — waktu persiapan bergantung-urutan, dikunci oleh transisi tugas-ke-tugas atau tipe-ke-tipe pada sebuah mesin.
  • LoadModel — kurva eksekusi bergantung-beban yang memetakan tingkat beban ke pengali durasi melalui interpolasi linear-bertahap atau tangga antara titik patah yang naik ketat.
  • CommunicationModel — penalti komunikasi antar-sumber-daya pada graf jarang; komunikasi sesama-mesin gratis dan pasangan antar-mesin yang tak terdaftar mundur ke penalti default yang dideklarasikan.
from dispatchatlas.core import (
    CostModel,
    ProblemId,
    ResourceId,
    TaskId,
    execution_matrix_from_iterable,
)
 
cost_model = CostModel(
    problem_id=ProblemId("smoke"),
    execution_matrix=execution_matrix_from_iterable(
        [(TaskId("task-a"), ResourceId("cpu"), 1.0)]
    ),
)

🎯 Tujuan dan reduksi

Keluarga tujuan dinamai dalam OBJECTIVE_FAMILY, yang mencatat sense dan satuan kanonik tiap tujuan: makespan, energi, biaya, karbon, latensi, keterlambatan, keadilan, bagian sumber daya dominan (sebaran antara bagian sumber daya dominan penyewa yang paling banyak dan paling sedikit dilayani — pembagian adil multipenyewa), keandalan, keamanan, ketangguhan, persiapan, imbalan tak-presisi (komputasi opsional yang diselesaikan melampaui bagian wajib tugas yang dapat-dieksekusi-sebagian), dan komposit berbobot. Sebuah hasil terukur dibawa oleh VectorObjectiveValue, yang menyimpan satu atau lebih entri ObjectiveValue (terurut menurut nama) plus sebuah ObjectiveReduction eksplisit dan label pengungkapan. Reduksi jumlah-berbobot dan Chebyshev menskalarisasi vektor; reduksi yang tak-menskalarisasi (NONE, LEXICOGRAPHIC) memunculkan kesalahan pada scalarize() agar pemanggil menangani pengurutan secara eksplisit.

Laporan kelayakan

build_feasibility_report mengubah laporan validasi jadwal menjadi FeasibilityReport yang terlihat oleh peninjau: pelanggaran keras menjadi rekaman InfeasibleRow per baris, dan kendala lunak bernama yang dilanggar mengakumulasi entri SoftConstraintPenalty berbobot. Pelanggaran lunak tidak pernah membalik feasible ke False.

📐 Evaluasi tujuan, kendala, dan frontier

Lapisan tujuan-dan-kendala menghitung tiap tujuan bernama secara individual, sehingga tak satu pun dilipat ke dalam bundel generik. evaluate_objective menurunkan makespan, keterlambatan, keadilan beban (indeks Jain), dan — untuk instans berlabel penyewa — keadilan bagian-sumber-daya-dominan langsung dari jadwal, menurunkan biaya dari matriks waktu eksekusi terlampir dan waktu persiapan bergantung-urutan dari matriks persiapan terlampir, dan mereduksi komponen yang dihitung menjadi komposit berbobot. Tujuan yang memerlukan model yang tidak dibawa inti (energi, karbon, latensi, keandalan, keamanan, ketangguhan) mengembalikan sebuah ObjectiveEvaluation berstatus DEFERRED dengan alasan bernama alih-alih nilai yang dikarang. MultiObjectiveOutcome membawa nilai skalar, tujuan vektor, dan laporan kelayakan melalui perjalanan bolak-balik serialisasi deterministik.

Akuntansi kendala menambahkan kendala tingkat layanan (SLA) bernama sebagai kendala kelas-utama dengan jalur pelanggaran keras (sebuah ketaklayakan) dan jalur penalti lunak (penalti berbobot proporsional terhadap pelanggaran). Sebuah ConstraintViolationSummary mengagregasi pelanggaran keras, penalti lunak, hasil SLA, dan diagnostik perbaikan; ia melaporkan tak-layak baik atas pelanggaran aturan keras maupun pelanggaran SLA keras.

Pembantu Pareto mengekstrak front non-terdominasi dan melaporkan empat indikator kualitas bernama yang dipilih menurut Riquelme, Von Lücken & Barán (2015): hipervolume (indikator utama), IGD+ (indikator konvergensi yang lemah-Pareto-patuh), epsilon-indikator aditif, dan sebaran (indikator keragaman). Tiap indikator dapat dihitung secara individual. frontier_data membangun rekaman siap-frontier dengan bendera non-terdominasi untuk analisis dan rendering portal.

Ketangguhan dikuantifikasi sebagai tujuan terukur alih-alih label sikap: evaluate_robustness mengagregasi nilai satu tujuan atas himpunan perturbasi yang dideklarasikan secara eksplisit, baik sebagai nilai kasus-terburuk maupun sebagai nilai pada risiko bersyarat (CVaR) dari ekor terburuk. Baik himpunan perturbasi maupun agregasi dicatat pada hasil.

⚠️ Keterbatasan

Kernel inti mendefinisikan kontrak biaya, tujuan, dan kendala serta lapisan tujuan-dan-kendala yang mengevaluasinya; ia tidak mengoptimasi. Tujuan yang memerlukan model yang tidak dibawa inti (energi, karbon, latensi, keandalan, keamanan, dan ketangguhan) dilaporkan sebagai ditangguhkan dengan alasan bernama alih-alih diestimasi. LoadModel hanya mengevaluasi kurva yang dideklarasikannya sendiri, dan ObjectiveDefinition membawa metadata alih-alih sebuah evaluator.

🌱 Provenans dan benih

Artefak yang dihasilkan membawa rekaman Provenance, ArtifactHash, SourceReference, EnvironmentStamp, dan SeedLineage opsional. Aliran benih diturunkan dari koordinat stabil:

from dispatchatlas.core import derive_seed
 
seed = derive_seed(42, "benchmark.smoke", 0)

Benih akar, ruang nama, dan indeks yang sama selalu menghasilkan benih turunan yang sama.

📦 Serialisasi

Objek inti diserialkan melalui pemetaan kanonik yang kompatibel-JSON dan pembungkus ArtifactEnvelope. Pembungkus mengikat muatan ke hash konten dan menyalin hash itu kembali ke provenans.

🔌 Protokol

Paket luar bergantung pada protokol yang didefinisikan inti:

  • BenchmarkProvider
  • Solver
  • ExperimentRunner
  • ResultRepository
  • DisclosurePolicy
  • AnalysisExporter

Protokol-protokol ini menjaga impor paket terarah ke dalam sambil memungkinkan paket benchmark, solver, eksperimen, dan analisis konkret terkomposisi belakangan.