diff --git a/docs/source/builder/writing-kernels.md b/docs/source/builder/writing-kernels.md index aa38a192..90c45dbe 100644 --- a/docs/source/builder/writing-kernels.md +++ b/docs/source/builder/writing-kernels.md @@ -190,6 +190,11 @@ The following sections enumerate all supported options for `build.toml`. branch named `v`. - `backends` (required): a list of supported backends. Must be one or more of `cpu`, `cuda`, `metal`, `rocm`, or `xpu`. +- `upstream`: URL of the original upstream repository where the kernel + source code comes from. +- `source`: URL of the kernel-builder formatted source repository. This + repository must contain a `build.toml` and `flake.nix` so that it can be + pulled and built with the kernel builder. - `python-depends` (**experimental**): a list of additional Python dependencies that the kernel requires. The only supported dependencies are `einops` and `nvidia-cutlass-dsl`. diff --git a/docs/source/kernel-requirements.md b/docs/source/kernel-requirements.md index 64f9c621..f897af3b 100644 --- a/docs/source/kernel-requirements.md +++ b/docs/source/kernel-requirements.md @@ -71,6 +71,10 @@ metadata. Currently the following top-level keys are supported: - `version` (`int`, required): the kernel version number. - `license` (`str`, required): the kernel license in. Refer to the list of [supported license identifiers](https://huggingface.co/docs/hub/repositories-licenses). +- `upstream` (`str`, optional): URL of the original upstream repository + where the kernel source code comes from. +- `source` (`str`, optional): URL of the kernel-builder formatted source + repository (must contain `build.toml` and `flake.nix`). - `backend` (`dict`, required): information about the compute backend that this build variant supports. - `python-depends` (`list[str]`, optional): list of Python dependencies diff --git a/examples/kernels/cutlass-gemm-tvm-ffi/CARD.md b/examples/kernels/cutlass-gemm-tvm-ffi/CARD.md index c7c70715..7ab1bbaf 100644 --- a/examples/kernels/cutlass-gemm-tvm-ffi/CARD.md +++ b/examples/kernels/cutlass-gemm-tvm-ffi/CARD.md @@ -49,8 +49,14 @@ No benchmark available yet. {% endif %} {% if upstream %} -## Source code +## Upstream -Source code of this kernel originally comes from {{ upstream }} and it was repurposed for compatibility with `kernels`. +The original source code for this kernel comes from {{ upstream }}. +{% endif %} +{% if source %} + +## Source + +The kernel-builder formatted source for this kernel is available at {{ source }}. {% endif %} diff --git a/examples/kernels/cutlass-gemm/CARD.md b/examples/kernels/cutlass-gemm/CARD.md index c7c70715..7ab1bbaf 100644 --- a/examples/kernels/cutlass-gemm/CARD.md +++ b/examples/kernels/cutlass-gemm/CARD.md @@ -49,8 +49,14 @@ No benchmark available yet. {% endif %} {% if upstream %} -## Source code +## Upstream -Source code of this kernel originally comes from {{ upstream }} and it was repurposed for compatibility with `kernels`. +The original source code for this kernel comes from {{ upstream }}. +{% endif %} +{% if source %} + +## Source + +The kernel-builder formatted source for this kernel is available at {{ source }}. {% endif %} diff --git a/examples/kernels/extra-data/CARD.md b/examples/kernels/extra-data/CARD.md index c7c70715..7ab1bbaf 100644 --- a/examples/kernels/extra-data/CARD.md +++ b/examples/kernels/extra-data/CARD.md @@ -49,8 +49,14 @@ No benchmark available yet. {% endif %} {% if upstream %} -## Source code +## Upstream -Source code of this kernel originally comes from {{ upstream }} and it was repurposed for compatibility with `kernels`. +The original source code for this kernel comes from {{ upstream }}. +{% endif %} +{% if source %} + +## Source + +The kernel-builder formatted source for this kernel is available at {{ source }}. {% endif %} diff --git a/examples/kernels/relu-backprop-compile/CARD.md b/examples/kernels/relu-backprop-compile/CARD.md index c7c70715..7ab1bbaf 100644 --- a/examples/kernels/relu-backprop-compile/CARD.md +++ b/examples/kernels/relu-backprop-compile/CARD.md @@ -49,8 +49,14 @@ No benchmark available yet. {% endif %} {% if upstream %} -## Source code +## Upstream -Source code of this kernel originally comes from {{ upstream }} and it was repurposed for compatibility with `kernels`. +The original source code for this kernel comes from {{ upstream }}. +{% endif %} +{% if source %} + +## Source + +The kernel-builder formatted source for this kernel is available at {{ source }}. {% endif %} diff --git a/examples/kernels/relu-compiler-flags/CARD.md b/examples/kernels/relu-compiler-flags/CARD.md index c7c70715..7ab1bbaf 100644 --- a/examples/kernels/relu-compiler-flags/CARD.md +++ b/examples/kernels/relu-compiler-flags/CARD.md @@ -49,8 +49,14 @@ No benchmark available yet. {% endif %} {% if upstream %} -## Source code +## Upstream -Source code of this kernel originally comes from {{ upstream }} and it was repurposed for compatibility with `kernels`. +The original source code for this kernel comes from {{ upstream }}. +{% endif %} +{% if source %} + +## Source + +The kernel-builder formatted source for this kernel is available at {{ source }}. {% endif %} diff --git a/examples/kernels/relu-metal-cpp/CARD.md b/examples/kernels/relu-metal-cpp/CARD.md index c7c70715..7ab1bbaf 100644 --- a/examples/kernels/relu-metal-cpp/CARD.md +++ b/examples/kernels/relu-metal-cpp/CARD.md @@ -49,8 +49,14 @@ No benchmark available yet. {% endif %} {% if upstream %} -## Source code +## Upstream -Source code of this kernel originally comes from {{ upstream }} and it was repurposed for compatibility with `kernels`. +The original source code for this kernel comes from {{ upstream }}. +{% endif %} +{% if source %} + +## Source + +The kernel-builder formatted source for this kernel is available at {{ source }}. {% endif %} diff --git a/examples/kernels/relu-nki/CARD.md b/examples/kernels/relu-nki/CARD.md index c7c70715..7ab1bbaf 100644 --- a/examples/kernels/relu-nki/CARD.md +++ b/examples/kernels/relu-nki/CARD.md @@ -49,8 +49,14 @@ No benchmark available yet. {% endif %} {% if upstream %} -## Source code +## Upstream -Source code of this kernel originally comes from {{ upstream }} and it was repurposed for compatibility with `kernels`. +The original source code for this kernel comes from {{ upstream }}. +{% endif %} +{% if source %} + +## Source + +The kernel-builder formatted source for this kernel is available at {{ source }}. {% endif %} diff --git a/examples/kernels/relu-specific-torch/CARD.md b/examples/kernels/relu-specific-torch/CARD.md index c7c70715..7ab1bbaf 100644 --- a/examples/kernels/relu-specific-torch/CARD.md +++ b/examples/kernels/relu-specific-torch/CARD.md @@ -49,8 +49,14 @@ No benchmark available yet. {% endif %} {% if upstream %} -## Source code +## Upstream -Source code of this kernel originally comes from {{ upstream }} and it was repurposed for compatibility with `kernels`. +The original source code for this kernel comes from {{ upstream }}. +{% endif %} +{% if source %} + +## Source + +The kernel-builder formatted source for this kernel is available at {{ source }}. {% endif %} diff --git a/examples/kernels/relu-torch-bounds/CARD.md b/examples/kernels/relu-torch-bounds/CARD.md index c7c70715..7ab1bbaf 100644 --- a/examples/kernels/relu-torch-bounds/CARD.md +++ b/examples/kernels/relu-torch-bounds/CARD.md @@ -49,8 +49,14 @@ No benchmark available yet. {% endif %} {% if upstream %} -## Source code +## Upstream -Source code of this kernel originally comes from {{ upstream }} and it was repurposed for compatibility with `kernels`. +The original source code for this kernel comes from {{ upstream }}. +{% endif %} +{% if source %} + +## Source + +The kernel-builder formatted source for this kernel is available at {{ source }}. {% endif %} diff --git a/examples/kernels/relu-tvm-ffi/CARD.md b/examples/kernels/relu-tvm-ffi/CARD.md index c7c70715..7ab1bbaf 100644 --- a/examples/kernels/relu-tvm-ffi/CARD.md +++ b/examples/kernels/relu-tvm-ffi/CARD.md @@ -49,8 +49,14 @@ No benchmark available yet. {% endif %} {% if upstream %} -## Source code +## Upstream -Source code of this kernel originally comes from {{ upstream }} and it was repurposed for compatibility with `kernels`. +The original source code for this kernel comes from {{ upstream }}. +{% endif %} +{% if source %} + +## Source + +The kernel-builder formatted source for this kernel is available at {{ source }}. {% endif %} diff --git a/examples/kernels/relu/CARD.md b/examples/kernels/relu/CARD.md index c7c70715..92ecc33d 100644 --- a/examples/kernels/relu/CARD.md +++ b/examples/kernels/relu/CARD.md @@ -49,8 +49,13 @@ No benchmark available yet. {% endif %} {% if upstream %} -## Source code +## Upstream -Source code of this kernel originally comes from {{ upstream }} and it was repurposed for compatibility with `kernels`. +The original source code for this kernel comes from {{ upstream }}. {% endif %} +{% if source %} +## Source + +The kernel-builder formatted source for this kernel is available at {{ source }}. +{% endif %} diff --git a/examples/kernels/silu-and-mul-bad-registration/CARD.md b/examples/kernels/silu-and-mul-bad-registration/CARD.md index c7c70715..7ab1bbaf 100644 --- a/examples/kernels/silu-and-mul-bad-registration/CARD.md +++ b/examples/kernels/silu-and-mul-bad-registration/CARD.md @@ -49,8 +49,14 @@ No benchmark available yet. {% endif %} {% if upstream %} -## Source code +## Upstream -Source code of this kernel originally comes from {{ upstream }} and it was repurposed for compatibility with `kernels`. +The original source code for this kernel comes from {{ upstream }}. +{% endif %} +{% if source %} + +## Source + +The kernel-builder formatted source for this kernel is available at {{ source }}. {% endif %} diff --git a/examples/kernels/silu-and-mul/CARD.md b/examples/kernels/silu-and-mul/CARD.md index c7c70715..7ab1bbaf 100644 --- a/examples/kernels/silu-and-mul/CARD.md +++ b/examples/kernels/silu-and-mul/CARD.md @@ -49,8 +49,14 @@ No benchmark available yet. {% endif %} {% if upstream %} -## Source code +## Upstream -Source code of this kernel originally comes from {{ upstream }} and it was repurposed for compatibility with `kernels`. +The original source code for this kernel comes from {{ upstream }}. +{% endif %} +{% if source %} + +## Source + +The kernel-builder formatted source for this kernel is available at {{ source }}. {% endif %} diff --git a/kernel-builder/src/card.rs b/kernel-builder/src/card.rs index b0047a5c..3580e469 100644 --- a/kernel-builder/src/card.rs +++ b/kernel-builder/src/card.rs @@ -135,7 +135,8 @@ fn render_card(build: &Build, kernel_dir: &Path) -> Result { functions => functions, layers => layers, has_benchmark => has_benchmark, - upstream => build.general.upstream.as_ref().map(|u| u.to_string()), + upstream => build.general.upstream.as_ref().map(|u| u.as_url().to_string()), + source => build.general.source.as_ref().map(|u| u.as_url().to_string()), license => build.general.license.to_lowercase(), }) .wrap_err("Cannot render card template") diff --git a/kernel-builder/src/init/templates/CARD.md b/kernel-builder/src/init/templates/CARD.md index 5ded435c..f0c4376a 100644 --- a/kernel-builder/src/init/templates/CARD.md +++ b/kernel-builder/src/init/templates/CARD.md @@ -49,8 +49,14 @@ No benchmark available yet. {% endif %} {% if upstream %} -## Source code +## Upstream -Source code of this kernel originally comes from {{ upstream }} and it was repurposed for compatibility with `kernels`. +The original source code for this kernel comes from {{ upstream }}. +{% endif %} +{% if source %} + +## Source + +The kernel-builder formatted source for this kernel is available at {{ source }}. {% endif %} {% endraw %} diff --git a/kernel-builder/src/pyproject/common.rs b/kernel-builder/src/pyproject/common.rs index 74a46235..fda995ee 100644 --- a/kernel-builder/src/pyproject/common.rs +++ b/kernel-builder/src/pyproject/common.rs @@ -44,6 +44,7 @@ pub fn write_metadata( version: general.version, license: general.license.clone(), upstream: general.upstream.clone(), + source: general.source.clone(), python_depends, backend: BackendInfo { archs: None, diff --git a/kernels-data/bindings/python/kernels_data.pyi b/kernels-data/bindings/python/kernels_data.pyi index 3aef9502..ba001898 100644 --- a/kernels-data/bindings/python/kernels_data.pyi +++ b/kernels-data/bindings/python/kernels_data.pyi @@ -123,6 +123,8 @@ class Metadata: @property def upstream(self) -> Optional[str]: ... @property + def source(self) -> Optional[str]: ... + @property def python_depends(self) -> list[str]: ... @property def backend(self) -> BackendInfo: ... diff --git a/kernels-data/bindings/python/src/lib.rs b/kernels-data/bindings/python/src/lib.rs index e5475d27..fdd04eb0 100644 --- a/kernels-data/bindings/python/src/lib.rs +++ b/kernels-data/bindings/python/src/lib.rs @@ -195,6 +195,7 @@ struct PyMetadata { version: usize, license: String, upstream: Option, + source: Option, python_depends: Vec, backend: PyBackendInfo, } @@ -206,7 +207,8 @@ impl From for PyMetadata { name: PyKernelName { inner: m.name }, version: m.version, license: m.license, - upstream: m.upstream.map(|u| u.to_string()), + upstream: m.upstream.map(|u| u.as_url().to_string()), + source: m.source.map(|u| u.as_url().to_string()), python_depends: m.python_depends, backend: m.backend.into(), } @@ -257,6 +259,11 @@ impl PyMetadata { self.upstream.as_deref() } + #[getter] + fn source(&self) -> Option<&str> { + self.source.as_deref() + } + #[getter] fn python_depends(&self) -> &[String] { &self.python_depends @@ -269,12 +276,13 @@ impl PyMetadata { fn __repr__(&self) -> String { format!( - "Metadata(id={}, name={:?}, version={:?}, license={:?}, upstream={:?}, python_depends={:?}, backend={})", + "Metadata(id={}, name={:?}, version={:?}, license={:?}, upstream={:?}, source={:?}, python_depends={:?}, backend={})", self.id, self.name, self.version, self.license, self.upstream, + self.source, self.python_depends, self.backend.__repr__() ) diff --git a/kernels-data/bindings/python/tests/test_kernels_data.py b/kernels-data/bindings/python/tests/test_kernels_data.py index 2d49cc0b..29bb52fe 100644 --- a/kernels-data/bindings/python/tests/test_kernels_data.py +++ b/kernels-data/bindings/python/tests/test_kernels_data.py @@ -95,6 +95,7 @@ def test_metadata_load_full(tmp_path): "name": "my-kernel", "license": "Apache-2.0", "upstream": "https://github.com/example/kernel", + "source": "https://github.com/example/kernel-builder", "python-depends": ["torch"], "backend": {"type": "cuda", "archs": ["9.0", "10.0"]}, } @@ -106,6 +107,7 @@ def test_metadata_load_full(tmp_path): assert m.version == 1 assert m.license == "Apache-2.0" assert m.upstream == "https://github.com/example/kernel" + assert m.source == "https://github.com/example/kernel-builder" assert m.python_depends == ["torch"] assert m.backend.backend_type == Backend.CUDA assert m.backend.archs == ["9.0", "10.0"] @@ -129,6 +131,7 @@ def test_metadata_load_minimal(tmp_path): assert m.version == 1 assert m.license == "Apache-2.0" assert m.upstream is None + assert m.source is None assert m.python_depends == [] assert m.backend.backend_type == Backend.CPU diff --git a/kernels-data/src/config/git_url.rs b/kernels-data/src/config/git_url.rs new file mode 100644 index 00000000..84163c91 --- /dev/null +++ b/kernels-data/src/config/git_url.rs @@ -0,0 +1,138 @@ +use std::fmt; + +use serde::{Deserialize, Deserializer, Serialize, Serializer, de}; +use url::Url; + +const GIT_SCHEMES: &[&str] = &[ + "https", + "http", + "git", + "ssh", + "git+ssh", + "git+https", + "git+http", +]; + +/// A validated git repository URL. +/// +/// Accepts standard git URLs (`https://`, `ssh://`, etc.) and SCP-like +/// syntax (`git@github.com:org/repo.git`). +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct GitUrl { + url: Url, + original: String, +} + +impl GitUrl { + pub fn parse(s: &str) -> Result { + // Standard URL. + if let Ok(url) = Url::parse(s) { + if !GIT_SCHEMES.contains(&url.scheme()) { + return Err(format!( + "unsupported scheme `{}` in git URL `{s}`, expected one of: {}", + url.scheme(), + GIT_SCHEMES.join(", ") + )); + } + return Ok(Self { + url, + original: s.to_string(), + }); + } + + // SCP-like syntax: git@github.com:org/repo.git + if let Some((host, path)) = s.split_once(':') + && !host.is_empty() + && !path.is_empty() + && !path.starts_with('/') + { + let normalized = format!("ssh://{host}/{path}"); + if let Ok(url) = Url::parse(&normalized) { + return Ok(Self { + url, + original: s.to_string(), + }); + } + } + + Err(format!("invalid git URL `{s}`")) + } + + pub fn as_url(&self) -> &Url { + &self.url + } +} + +impl fmt::Display for GitUrl { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(&self.original) + } +} + +impl<'de> Deserialize<'de> for GitUrl { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + GitUrl::parse(&s).map_err(de::Error::custom) + } +} + +impl Serialize for GitUrl { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_str(&self.original) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_valid_urls() { + let valid = [ + "https://github.com/org/repo", + "https://github.com/org/repo.git", + "http://github.com/org/repo.git", + "git://github.com/org/repo.git", + "ssh://git@github.com/org/repo.git", + "git+ssh://git@github.com/org/repo.git", + "git+https://github.com/org/repo.git", + "git@github.com:org/repo.git", + "git@github.com:drbh/yamoe.git", + "user@gitlab.com:group/project.git", + ]; + for s in valid { + assert!(GitUrl::parse(s).is_ok(), "expected valid: {s}"); + } + } + + #[test] + fn test_scp_normalization() { + let git_url = GitUrl::parse("git@github.com:drbh/yamoe.git").unwrap(); + assert_eq!( + git_url.as_url().as_str(), + "ssh://git@github.com/drbh/yamoe.git" + ); + assert_eq!(git_url.to_string(), "git@github.com:drbh/yamoe.git"); + } + + #[test] + fn test_scp_roundtrip() { + let git_url = GitUrl::parse("git@github.com:org/repo.git").unwrap(); + let json = serde_json::to_string(&git_url).unwrap(); + let deserialized: GitUrl = serde_json::from_str(&json).unwrap(); + assert_eq!(deserialized.to_string(), "git@github.com:org/repo.git"); + } + + #[test] + fn test_invalid_urls() { + assert!(GitUrl::parse("ftp://example.com/repo.git").is_err()); + assert!(GitUrl::parse("file:///home/user/repo").is_err()); + assert!(GitUrl::parse("not a url").is_err()); + } +} diff --git a/kernels-data/src/config/mod.rs b/kernels-data/src/config/mod.rs index 2aa497d3..6c0f5c64 100644 --- a/kernels-data/src/config/mod.rs +++ b/kernels-data/src/config/mod.rs @@ -10,6 +10,9 @@ pub use deps::{Dependency, PythonDependency}; mod compat; pub use compat::BuildCompat; +mod git_url; +pub use git_url::GitUrl; + mod name; pub use name::KernelName; @@ -71,8 +74,11 @@ pub struct General { /// Hugging Face Hub license identifier. pub license: String, - /// Source repository or reference for the kernel code. - pub upstream: Option, + /// Original upstream repository for the kernel code. + pub upstream: Option, + + /// Kernel-builder formatted source repository (must contain build.toml and flake.nix). + pub source: Option, pub backends: Vec, pub hub: Option, diff --git a/kernels-data/src/config/v1.rs b/kernels-data/src/config/v1.rs index 523d283b..639c53d9 100644 --- a/kernels-data/src/config/v1.rs +++ b/kernels-data/src/config/v1.rs @@ -108,6 +108,7 @@ impl TryFrom for super::Build { version: None, license: None, upstream: None, + source: None, backends, hub: None, neuron: None, diff --git a/kernels-data/src/config/v2.rs b/kernels-data/src/config/v2.rs index 866ab6fe..b02ee754 100644 --- a/kernels-data/src/config/v2.rs +++ b/kernels-data/src/config/v2.rs @@ -173,6 +173,7 @@ impl General { version: None, license: None, upstream: None, + source: None, backends, cuda, hub: general.hub.map(Into::into), diff --git a/kernels-data/src/config/v3.rs b/kernels-data/src/config/v3.rs index f12a3dac..3583e6f3 100644 --- a/kernels-data/src/config/v3.rs +++ b/kernels-data/src/config/v3.rs @@ -3,7 +3,7 @@ use std::path::PathBuf; use serde::{Deserialize, Serialize}; -use super::{Dependency, KernelName}; +use super::{Dependency, GitUrl, KernelName}; use crate::{config::ConfigError, version::Version}; #[derive(Debug, Deserialize, Serialize)] @@ -38,7 +38,7 @@ pub struct General { pub license: Option, - pub upstream: Option, + pub upstream: Option, pub backends: Vec, @@ -195,6 +195,7 @@ impl TryFrom for super::General { version: general.version.unwrap_or(1), license, upstream: general.upstream, + source: None, backends: general.backends.into_iter().map(Into::into).collect(), cuda: general.cuda.map(Into::into), hub: general.hub.map(Into::into), diff --git a/kernels-data/src/config/v4.rs b/kernels-data/src/config/v4.rs index 14386b35..c10a105a 100644 --- a/kernels-data/src/config/v4.rs +++ b/kernels-data/src/config/v4.rs @@ -3,7 +3,7 @@ use std::path::PathBuf; use serde::{Deserialize, Serialize}; -use super::{Dependency, KernelName}; +use super::{Dependency, GitUrl, KernelName}; use crate::version::Version; #[derive(Debug, Deserialize, Serialize)] @@ -35,7 +35,9 @@ pub struct General { pub license: String, - pub upstream: Option, + pub upstream: Option, + + pub source: Option, pub backends: Vec, @@ -182,6 +184,7 @@ impl From for super::General { version: general.version, license: general.license, upstream: general.upstream, + source: general.source, backends: general.backends.into_iter().map(Into::into).collect(), cuda: general.cuda.map(Into::into), hub: general.hub.map(Into::into), @@ -376,6 +379,7 @@ impl From for General { version: general.version, license: general.license, upstream: general.upstream, + source: general.source, backends: general.backends.into_iter().map(Into::into).collect(), cuda: general.cuda.map(Into::into), hub: general.hub.map(Into::into), diff --git a/kernels-data/src/metadata.rs b/kernels-data/src/metadata.rs index 34d3d1cd..1fd22545 100644 --- a/kernels-data/src/metadata.rs +++ b/kernels-data/src/metadata.rs @@ -3,7 +3,7 @@ use std::str::FromStr; use eyre::Result; use serde::{Deserialize, Serialize}; -use crate::config::{Backend, KernelName}; +use crate::config::{Backend, GitUrl, KernelName}; #[derive(Debug, Deserialize, Serialize)] #[serde(rename_all = "kebab-case")] @@ -23,7 +23,9 @@ pub struct Metadata { pub version: usize, pub license: String, #[serde(skip_serializing_if = "Option::is_none")] - pub upstream: Option, + pub upstream: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub source: Option, pub python_depends: Vec, pub backend: BackendInfo, } diff --git a/kernels/src/kernels/utils.py b/kernels/src/kernels/utils.py index 5a046014..921de9df 100644 --- a/kernels/src/kernels/utils.py +++ b/kernels/src/kernels/utils.py @@ -114,7 +114,8 @@ class LoadedKernel: - `name` (`str`): the name of the kernel. - `version` (`int`): the version of the kernel. - `license` (`str`): the license of the kernel. - - `upstream` (`str | None`): the upstream repository of the kernel. + - `upstream` (`str | None`): the original upstream repository of the kernel. + - `source` (`str | None`): the kernel-builder formatted source repository. - `python_depends` (`list[str]`): required Python dependencies. - `backend`: information about the kernel's backend. """