tiagomonteiro0715 commited on
Commit
fcfe221
·
1 Parent(s): 490d9fe

migrate to new huggingface/kernels builder schema

Browse files
build.toml CHANGED
@@ -1,10 +1,16 @@
 
 
 
1
  [general]
2
- name = "my_softmax_function"
 
 
 
3
  backends = ["cuda"]
4
 
5
  [general.cuda]
 
6
  minver = "12.8"
7
  python-depends = ["nvidia-cutlass-dsl"]
8
 
9
- [torch]
10
- src = []
 
1
+ # Hugging Face kernel manifest (new huggingface/kernels schema).
2
+ # Pure-Python kernel (CUTLASS Python DSL, JIT-compiled on the GPU at runtime):
3
+ # no compiled sources -> declared with [torch-noarch]. CUDA-only (CUTLASS is NVIDIA).
4
  [general]
5
+ name = "my-softmax-function"
6
+ version = 1
7
+ edition = 5
8
+ license = "Apache-2.0"
9
  backends = ["cuda"]
10
 
11
  [general.cuda]
12
+ # nvidia-cutlass-dsl 4.3.0 requires CUDA >= 12.8.
13
  minver = "12.8"
14
  python-depends = ["nvidia-cutlass-dsl"]
15
 
16
+ [torch-noarch]
 
build/torch-cuda/_kernel.py CHANGED
@@ -10,12 +10,11 @@ import math
10
  import torch
11
  from cutlass.cute.runtime import from_dlpack
12
 
 
13
  from .attention_v3 import solve
14
 
15
- _OP_NAME = "my_softmax_function::softmax_attention"
16
 
17
-
18
- @torch.library.custom_op(_OP_NAME, mutates_args=())
19
  def softmax_attention(
20
  Q: torch.Tensor, # (M, d)
21
  K: torch.Tensor, # (N, d)
@@ -65,4 +64,5 @@ def attention(Q, K, V, scale=None):
65
  """Convenience entry point with a default 1/sqrt(d) scale."""
66
  if scale is None:
67
  scale = 1.0 / math.sqrt(Q.shape[-1])
68
- return torch.ops.my_softmax_function.softmax_attention(Q, K, V, scale)
 
 
10
  import torch
11
  from cutlass.cute.runtime import from_dlpack
12
 
13
+ from ._ops import add_op_namespace_prefix
14
  from .attention_v3 import solve
15
 
 
16
 
17
+ @torch.library.custom_op(add_op_namespace_prefix("softmax_attention"), mutates_args=())
 
18
  def softmax_attention(
19
  Q: torch.Tensor, # (M, d)
20
  K: torch.Tensor, # (N, d)
 
64
  """Convenience entry point with a default 1/sqrt(d) scale."""
65
  if scale is None:
66
  scale = 1.0 / math.sqrt(Q.shape[-1])
67
+ # Call the registered op directly (its namespace is build-unique).
68
+ return softmax_attention(Q, K, V, scale)
build/torch-cuda/_ops.py CHANGED
@@ -1,8 +1,38 @@
1
  import torch
2
- ops = torch.ops._my_softmax_function_2af76fc
3
 
4
- def add_op_namespace_prefix(op_name: str):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  """
6
  Prefix op by namespace.
7
  """
8
- return f"_my_softmax_function_2af76fc::{op_name}"
 
1
  import torch
 
2
 
3
+ def get_backend() -> str:
4
+ """Detect the backend by inspecting torch."""
5
+ import torch
6
+
7
+ if hasattr(torch, "neuron"):
8
+ # Needs to be sorted before specific Torch builds, since Neuron
9
+ # extension can be loaded into e.g. CUDA Torch builds.
10
+ return "neuron"
11
+ elif torch.version.cuda is not None:
12
+ return "cuda"
13
+ elif torch.version.hip is not None:
14
+ return "rocm"
15
+ elif torch.backends.mps.is_available():
16
+ return "metal"
17
+ elif hasattr(torch.version, "xpu") and torch.version.xpu is not None:
18
+ return "xpu"
19
+ else:
20
+ return "cpu"
21
+
22
+
23
+ def _find_ops_name() -> str:
24
+ kernel_name = "my_softmax_function"
25
+ unique_id = "490d9fe_dirty"
26
+ backend = get_backend()
27
+ return f"_{kernel_name}_{backend}_{unique_id}"
28
+
29
+
30
+ _OPS_NAME = _find_ops_name()
31
+
32
+ ops = getattr(torch.ops, _OPS_NAME)
33
+
34
+ def add_op_namespace_prefix(op_name: str) -> str:
35
  """
36
  Prefix op by namespace.
37
  """
38
+ return f"{_OPS_NAME}::{op_name}"
build/torch-cuda/metadata.json CHANGED
@@ -1,5 +1,32 @@
1
  {
 
 
 
 
2
  "python-depends": [
3
  "nvidia-cutlass-dsl"
4
- ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  }
 
1
  {
2
+ "name": "my-softmax-function",
3
+ "id": "_my_softmax_function_cuda_490d9fe_dirty",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
  "python-depends": [
7
  "nvidia-cutlass-dsl"
8
+ ],
9
+ "backend": {
10
+ "type": "cuda"
11
+ },
12
+ "digest": {
13
+ "algorithm": "sha256",
14
+ "files": {
15
+ "__init__.py": "ZpvyIhcU8bz4Xcc1WhVskt3WR3Yx9CCzS8+Jl1DOXGU=",
16
+ "_kernel.py": "xDfkK2UVoOoZY8Jn4VtzTxrzdo6MfXVm72qu2S+/jp8=",
17
+ "_ops.py": "ZkMq9OCa4I7SzsNvw++4/jnPxnmILtflnvy5frJ1Pgc=",
18
+ "attention_v3.py": "xWyf2XnBmPKuOe5D6h8/3S3QwQXpbYFZTYCRh49Fkso="
19
+ }
20
+ },
21
+ "provenance": {
22
+ "kernel-builder": {
23
+ "version": "0.17.0-dev0",
24
+ "sha": "d0610aa58db33b142c86b59598a2a1c730f52996",
25
+ "dirty": false
26
+ },
27
+ "kernel": {
28
+ "sha": "490d9fe259aa1f38cdfd8c9646791796518182ee",
29
+ "dirty": true
30
+ }
31
+ }
32
  }
build/torch-cuda/my_softmax_function/__init__.py DELETED
@@ -1,26 +0,0 @@
1
- import ctypes
2
- import sys
3
-
4
- import importlib
5
- from pathlib import Path
6
- from types import ModuleType
7
-
8
- def _import_from_path(file_path: Path) -> ModuleType:
9
- # We cannot use the module name as-is, after adding it to `sys.modules`,
10
- # it would also be used for other imports. So, we make a module name that
11
- # depends on the path for it to be unique using the hex-encoded hash of
12
- # the path.
13
- path_hash = "{:x}".format(ctypes.c_size_t(hash(file_path.absolute())).value)
14
- module_name = path_hash
15
- spec = importlib.util.spec_from_file_location(module_name, file_path)
16
- if spec is None:
17
- raise ImportError(f"Cannot load spec for {module_name} from {file_path}")
18
- module = importlib.util.module_from_spec(spec)
19
- if module is None:
20
- raise ImportError(f"Cannot load module {module_name} from spec")
21
- sys.modules[module_name] = module
22
- spec.loader.exec_module(module) # type: ignore
23
- return module
24
-
25
-
26
- globals().update(vars(_import_from_path(Path(__file__).parent.parent / "__init__.py")))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
flake.lock CHANGED
@@ -2,11 +2,11 @@
2
  "nodes": {
3
  "flake-compat": {
4
  "locked": {
5
- "lastModified": 1765121682,
6
- "narHash": "sha256-4VBOP18BFeiPkyhy9o4ssBNQEvfvv1kXkasAYd0+rrA=",
7
  "owner": "edolstra",
8
  "repo": "flake-compat",
9
- "rev": "65f23138d8d09a92e30f1e5c87611b23ef451bf3",
10
  "type": "github"
11
  },
12
  "original": {
@@ -37,35 +37,36 @@
37
  "inputs": {
38
  "flake-compat": "flake-compat",
39
  "flake-utils": "flake-utils",
40
- "nixpkgs": "nixpkgs"
 
41
  },
42
  "locked": {
43
- "lastModified": 1775482375,
44
- "narHash": "sha256-RUbxfJGs96jwnwSci3+8h08GB2/katOI67yZTCaV+aE=",
45
  "owner": "huggingface",
46
- "repo": "kernel-builder",
47
- "rev": "dffbce5a048648febb96bbed79f3811ab6d7a577",
48
  "type": "github"
49
  },
50
  "original": {
51
  "owner": "huggingface",
52
- "repo": "kernel-builder",
53
  "type": "github"
54
  }
55
  },
56
  "nixpkgs": {
57
  "locked": {
58
- "lastModified": 1766341660,
59
- "narHash": "sha256-4yG6vx7Dddk9/zh45Y2KM82OaRD4jO3HA9r98ORzysA=",
60
  "owner": "NixOS",
61
  "repo": "nixpkgs",
62
- "rev": "26861f5606e3e4d1400771b513cc63e5f70151a6",
63
  "type": "github"
64
  },
65
  "original": {
66
  "owner": "NixOS",
67
- "ref": "nixos-unstable-small",
68
  "repo": "nixpkgs",
 
69
  "type": "github"
70
  }
71
  },
@@ -74,6 +75,27 @@
74
  "kernel-builder": "kernel-builder"
75
  }
76
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  "systems": {
78
  "locked": {
79
  "lastModified": 1681028828,
 
2
  "nodes": {
3
  "flake-compat": {
4
  "locked": {
5
+ "lastModified": 1767039857,
6
+ "narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=",
7
  "owner": "edolstra",
8
  "repo": "flake-compat",
9
+ "rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab",
10
  "type": "github"
11
  },
12
  "original": {
 
37
  "inputs": {
38
  "flake-compat": "flake-compat",
39
  "flake-utils": "flake-utils",
40
+ "nixpkgs": "nixpkgs",
41
+ "rust-overlay": "rust-overlay"
42
  },
43
  "locked": {
44
+ "lastModified": 1785427612,
45
+ "narHash": "sha256-hUFEwQKDjVHw9v6xgC6Lx402TYfUA8zXEi8hDE/F4y0=",
46
  "owner": "huggingface",
47
+ "repo": "kernels",
48
+ "rev": "d0610aa58db33b142c86b59598a2a1c730f52996",
49
  "type": "github"
50
  },
51
  "original": {
52
  "owner": "huggingface",
53
+ "repo": "kernels",
54
  "type": "github"
55
  }
56
  },
57
  "nixpkgs": {
58
  "locked": {
59
+ "lastModified": 1783284758,
60
+ "narHash": "sha256-tiQ8/qi8I45OOaBBYlVbXoAVkeQzvvTQOv5I45rMw5o=",
61
  "owner": "NixOS",
62
  "repo": "nixpkgs",
63
+ "rev": "ec1a11210589d294f0ac99d3290a27e6c73dfa1d",
64
  "type": "github"
65
  },
66
  "original": {
67
  "owner": "NixOS",
 
68
  "repo": "nixpkgs",
69
+ "rev": "ec1a11210589d294f0ac99d3290a27e6c73dfa1d",
70
  "type": "github"
71
  }
72
  },
 
75
  "kernel-builder": "kernel-builder"
76
  }
77
  },
78
+ "rust-overlay": {
79
+ "inputs": {
80
+ "nixpkgs": [
81
+ "kernel-builder",
82
+ "nixpkgs"
83
+ ]
84
+ },
85
+ "locked": {
86
+ "lastModified": 1783320166,
87
+ "narHash": "sha256-l7C/OsjcnWDOk2K3ssj+SBduwL67LashjBqis9+t468=",
88
+ "owner": "oxalica",
89
+ "repo": "rust-overlay",
90
+ "rev": "20ee15370c9256669d66968b89ee20a4b0a4e673",
91
+ "type": "github"
92
+ },
93
+ "original": {
94
+ "owner": "oxalica",
95
+ "repo": "rust-overlay",
96
+ "type": "github"
97
+ }
98
+ },
99
  "systems": {
100
  "locked": {
101
  "lastModified": 1681028828,
flake.nix CHANGED
@@ -2,7 +2,9 @@
2
  description = "my_softmax_function — fused softmax-attention kernel";
3
 
4
  inputs = {
5
- kernel-builder.url = "github:huggingface/kernel-builder";
 
 
6
  };
7
 
8
  outputs =
@@ -10,7 +12,8 @@
10
  self,
11
  kernel-builder,
12
  }:
13
- kernel-builder.lib.genFlakeOutputs {
 
14
  inherit self;
15
  path = ./.;
16
  };
 
2
  description = "my_softmax_function — fused softmax-attention kernel";
3
 
4
  inputs = {
5
+ # New merged repo (kernel-builder folded into huggingface/kernels).
6
+ # Its metadata schema matches the current `kernels` loader library.
7
+ kernel-builder.url = "github:huggingface/kernels";
8
  };
9
 
10
  outputs =
 
12
  self,
13
  kernel-builder,
14
  }:
15
+ # genFlakeOutputs was renamed to genKernelFlakeOutputs in the new repo.
16
+ kernel-builder.lib.genKernelFlakeOutputs {
17
  inherit self;
18
  path = ./.;
19
  };
torch-ext/my_softmax_function/_kernel.py CHANGED
@@ -10,12 +10,11 @@ import math
10
  import torch
11
  from cutlass.cute.runtime import from_dlpack
12
 
 
13
  from .attention_v3 import solve
14
 
15
- _OP_NAME = "my_softmax_function::softmax_attention"
16
 
17
-
18
- @torch.library.custom_op(_OP_NAME, mutates_args=())
19
  def softmax_attention(
20
  Q: torch.Tensor, # (M, d)
21
  K: torch.Tensor, # (N, d)
@@ -65,4 +64,5 @@ def attention(Q, K, V, scale=None):
65
  """Convenience entry point with a default 1/sqrt(d) scale."""
66
  if scale is None:
67
  scale = 1.0 / math.sqrt(Q.shape[-1])
68
- return torch.ops.my_softmax_function.softmax_attention(Q, K, V, scale)
 
 
10
  import torch
11
  from cutlass.cute.runtime import from_dlpack
12
 
13
+ from ._ops import add_op_namespace_prefix
14
  from .attention_v3 import solve
15
 
 
16
 
17
+ @torch.library.custom_op(add_op_namespace_prefix("softmax_attention"), mutates_args=())
 
18
  def softmax_attention(
19
  Q: torch.Tensor, # (M, d)
20
  K: torch.Tensor, # (N, d)
 
64
  """Convenience entry point with a default 1/sqrt(d) scale."""
65
  if scale is None:
66
  scale = 1.0 / math.sqrt(Q.shape[-1])
67
+ # Call the registered op directly (its namespace is build-unique).
68
+ return softmax_attention(Q, K, V, scale)