forked from tinygrad/tinygrad
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aef4a496b1 | ||
|
|
7383ab9b80 |
@@ -269,7 +269,8 @@ if __name__ == "__main__":
|
||||
|
||||
# load in weights
|
||||
with WallTimeEvent(BenchEvent.LOAD_WEIGHTS):
|
||||
load_state_dict(model, torch_load(fetch('https://huggingface.co/CompVis/stable-diffusion-v-1-4-original/resolve/main/sd-v1-4.ckpt', 'sd-v1-4.ckpt'))['state_dict'], verbose=False, strict=False, realize=False)
|
||||
model_bin = fetch('https://huggingface.co/CompVis/stable-diffusion-v-1-4-original/resolve/main/sd-v1-4.ckpt', 'sd-v1-4.ckpt')
|
||||
load_state_dict(model, torch_load(model_bin)['state_dict'], verbose=False, strict=False, realize=False)
|
||||
|
||||
if args.fp16:
|
||||
for k,v in get_state_dict(model).items():
|
||||
|
||||
@@ -418,5 +418,32 @@ class TestPathTensor(unittest.TestCase):
|
||||
Tensor(pathlib.Path(test_file)).tolist()
|
||||
os.chmod(test_file, 0o644)
|
||||
assert Tensor(pathlib.Path(test_file)).tolist(), list(range(10))
|
||||
|
||||
class TestDiskTensorMovement(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.fn = pathlib.Path(temp("custom_disk_range"))
|
||||
self.fn.unlink(missing_ok=True)
|
||||
Tensor.arange(100, dtype=dtypes.uint8).to(f"disk:{str(self.fn)}").realize()
|
||||
|
||||
def test_simple_read(self):
|
||||
t = Tensor(self.fn)
|
||||
self.assertTrue(Tensor.all(t.to(None) == Tensor.arange(100, dtype=dtypes.uint8)).item())
|
||||
|
||||
def test_slice_read(self):
|
||||
t = Tensor(self.fn)
|
||||
self.assertListEqual(t[16:18].tolist(), [16,17])
|
||||
|
||||
# TODO: fix this! at least assert on it
|
||||
@unittest.expectedFailure
|
||||
def test_slice_read_cat(self):
|
||||
t = Tensor(self.fn)
|
||||
self.assertListEqual(Tensor.cat(t[16:18], t[20:22]).tolist(), [16,17,20,21])
|
||||
|
||||
# TODO: fix this! at least assert on it
|
||||
@unittest.expectedFailure
|
||||
def test_slice_sum(self):
|
||||
t = Tensor(self.fn)
|
||||
self.assertListEqual((t[16:18]+t[20:22]).tolist(), [16+20,17+21])
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
+13
-6
@@ -1,6 +1,6 @@
|
||||
import json, pathlib, zipfile, pickle, tarfile, struct, functools, io
|
||||
from collections import OrderedDict
|
||||
from typing import Any, Callable, BinaryIO, Iterable
|
||||
from typing import Any, Callable, BinaryIO, Iterable, cast
|
||||
from tinygrad.tensor import Tensor
|
||||
from tinygrad.dtype import dtypes
|
||||
from tinygrad.helpers import prod, argsort, DEBUG, Timing, CI, unwrap, GlobalCounters, tqdm, round_up, T, strides_for_shape
|
||||
@@ -237,11 +237,18 @@ def torch_load(t:Tensor) -> dict[str, Tensor]:
|
||||
|
||||
if passthrough_reset(zipfile.is_zipfile(fobj)): # NOTE: passthrough_reset required to support python < 3.14
|
||||
myzip = zipfile.ZipFile(fobj, 'r')
|
||||
base_name = myzip.namelist()[0].split('/', 1)[0]
|
||||
for n in myzip.namelist():
|
||||
if n.startswith(f'{base_name}/data/'):
|
||||
with myzip.open(n) as myfile:
|
||||
offsets[n.split("/")[-1]] = myfile._orig_compress_start # type: ignore
|
||||
base_name = None
|
||||
header_offsets = {}
|
||||
for zi in myzip.filelist:
|
||||
if base_name is None: base_name = zi.filename.split('/', 1)[0]
|
||||
if zi.filename.startswith(f'{base_name}/data/'): header_offsets[zi.filename.split("/")[-1]] = zi.header_offset
|
||||
# sadly there's no way to get the start of the file in the zip without reading the header
|
||||
# at least here we read them in parallel
|
||||
header_contents = [t[v+26:v+30].bitcast(dtypes.uint16).to('CPU') for v in header_offsets.values()]
|
||||
Tensor.realize(*header_contents)
|
||||
for (n,o),c in zip(header_offsets.items(), header_contents):
|
||||
# header_offset + sizeFileHeader + File name length + Extra field length : https://en.wikipedia.org/wiki/ZIP_(file_format)
|
||||
offsets[n] = o+30+sum(cast(list[int], c.tolist()))
|
||||
with myzip.open(f'{base_name}/data.pkl') as myfile:
|
||||
return TorchPickle(myfile).load()
|
||||
elif passthrough_reset(tarfile.is_tarfile(fobj)): # NOTE: passthrough_reset required to support python < 3.11
|
||||
|
||||
+3
-2
@@ -256,7 +256,7 @@ class Tensor(MathTrait):
|
||||
# create the schedule
|
||||
schedule, var_vals = create_schedule_with_vars(sink)
|
||||
schedule = memory_planner(schedule)
|
||||
if DEBUG >= 1 and len(schedule) > 1: print(f"scheduled {len(schedule)} kernels in {(time.perf_counter()-st)*1000:.2f} ms")
|
||||
if (DEBUG >= 1 and len(schedule) > 1) or DEBUG >= 3: print(f"scheduled {len(schedule)} kernels in {(time.perf_counter()-st)*1000:.2f} ms")
|
||||
return schedule, var_vals
|
||||
|
||||
def schedule(self, *lst:Tensor) -> list[ScheduleItem]:
|
||||
@@ -267,7 +267,8 @@ class Tensor(MathTrait):
|
||||
|
||||
def realize(self, *lst:Tensor, do_update_stats=True) -> Tensor:
|
||||
"""Triggers the computation needed to create these Tensor(s)."""
|
||||
run_schedule(*self.schedule_with_vars(*lst), do_update_stats=do_update_stats)
|
||||
if len(to_realize:=[x for x in (self,)+lst if not x.uop.is_contiguous()]):
|
||||
run_schedule(*Tensor.schedule_with_vars(*to_realize), do_update_stats=do_update_stats)
|
||||
return self
|
||||
|
||||
def replace(self, x:Tensor, allow_shape_mismatch=False) -> Tensor:
|
||||
|
||||
+9
-5
@@ -389,7 +389,15 @@ class UOp(MathTrait, metaclass=UOpMetaClass):
|
||||
assert self.dtype.scalar() is dtypes.index, "Can only call get_valid on index dtype"
|
||||
return self.src[0] if self.op is Ops.WHERE and self.src[2].arg is Invalid else UOp.const(dtypes.bool, self.arg is not Invalid)
|
||||
def reduce(self, *src:UOp, **kwargs): return UOp(Ops.REDUCE, kwargs.pop('dtype', self.dtype), src=(self,)+src, **kwargs)
|
||||
def contiguous(self, *args, **kwargs): return UOp(Ops.CONTIGUOUS, dtype=self.dtype, src=(self,)+args, **kwargs)
|
||||
|
||||
def is_contiguous(self):
|
||||
# TODO: this is is_realized
|
||||
if self.op is Ops.RESHAPE: return self.src[0].is_contiguous()
|
||||
return self.op is Ops.BUFFER
|
||||
|
||||
def contiguous(self, *args, **kwargs):
|
||||
if self.is_contiguous(): return self
|
||||
return UOp(Ops.CONTIGUOUS, dtype=self.dtype, src=(self,)+args, **kwargs)
|
||||
def contiguous_backward(self): return self.alu(Ops.CONTIGUOUS_BACKWARD)
|
||||
def bufferize(self, *args, **kwargs): return UOp(Ops.BUFFERIZE, dtype=self.dtype, src=(self,)+args, **kwargs)
|
||||
def fuse(self): return self.alu(Ops.FUSE)
|
||||
@@ -497,10 +505,6 @@ class UOp(MathTrait, metaclass=UOpMetaClass):
|
||||
if ret.shape == self.shape and same_shape_noop: return self
|
||||
return ret
|
||||
|
||||
def is_contiguous(self):
|
||||
if self.op is Ops.RESHAPE: return self.src[0].is_contiguous()
|
||||
return self.op is Ops.BUFFER
|
||||
|
||||
# in these four, if the shape doesn't change we can return self
|
||||
def forced_reshape(self, arg:tuple[sint, ...]): return self._mop(Ops.RESHAPE, arg, same_shape_noop=False)
|
||||
def reshape(self, arg:tuple[sint, ...]): return self._mop(Ops.RESHAPE, arg, same_shape_noop=True)
|
||||
|
||||
Reference in New Issue
Block a user