This is an automated email from the ASF dual-hosted git repository.
tqchen pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm.git
The following commit(s) were added to refs/heads/main by this push:
new 40ec46970f [WEB] Move ArtifactCache to Interface, Support Cache delete
and Batch Delete, Remove typo (#16525)
40ec46970f is described below
commit 40ec46970f7e1b94a0eec3b4da8868d1ec179d69
Author: Diego Cao <[email protected]>
AuthorDate: Mon Feb 19 14:02:58 2024 -0500
[WEB] Move ArtifactCache to Interface, Support Cache delete and Batch
Delete, Remove typo (#16525)
Parallel Download, Move ArtifactCache to Interface to support future
different cache types, fix README path typo, Support delete and batch delete
Co-authored-by: DavidGOrtega <[email protected]>
---
web/README.md | 2 +-
web/package-lock.json | 4 ++--
web/src/artifact_cache.ts | 19 ++++++++++++++++++
web/src/index.ts | 2 +-
web/src/runtime.ts | 51 ++++++++++++++++++++++++++++++++++++++++-------
5 files changed, 67 insertions(+), 11 deletions(-)
diff --git a/web/README.md b/web/README.md
index 64f507579e..9b3cda1fb7 100644
--- a/web/README.md
+++ b/web/README.md
@@ -94,4 +94,4 @@ Right now we use the SPIRV to generate shaders that can be
accepted by Chrome an
- Firefox should be close pending the support of Fence.
- Download vulkan SDK (1.1 or higher) that supports SPIRV 1.3
- Start the WebSocket RPC
-- run `python tests/node/webgpu_rpc_test.py`
+- run `python tests/python/webgpu_rpc_test.py`
diff --git a/web/package-lock.json b/web/package-lock.json
index 37bac4493f..74561324c9 100644
--- a/web/package-lock.json
+++ b/web/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "tvmjs",
- "version": "0.15.0-dev0",
+ "version": "0.16.0-dev0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "tvmjs",
- "version": "0.15.0-dev0",
+ "version": "0.16.0-dev0",
"license": "Apache-2.0",
"devDependencies": {
"@rollup/plugin-commonjs": "^20.0.0",
diff --git a/web/src/artifact_cache.ts b/web/src/artifact_cache.ts
new file mode 100644
index 0000000000..394cda83bc
--- /dev/null
+++ b/web/src/artifact_cache.ts
@@ -0,0 +1,19 @@
+/*
+ Common Interface for the artifact cache
+*/
+export interface ArtifactCacheTemplate {
+ /**
+ * fetch key url from cache
+ */
+ fetchWithCache(url: string);
+
+ /**
+ * check if cache has all keys in Cache
+ */
+ hasAllKeys(keys: string[]);
+
+ /**
+ * Delete url in cache if url exists
+ */
+ deleteInCache(url: string);
+}
diff --git a/web/src/index.ts b/web/src/index.ts
index fd27fce9fd..9099d8f373 100644
--- a/web/src/index.ts
+++ b/web/src/index.ts
@@ -22,7 +22,7 @@ export {
PackedFunc, Module, NDArray,
TVMArray, TVMObject, VirtualMachine,
InitProgressCallback, InitProgressReport,
- ArtifactCache, Instance, instantiate, hasNDArrayInCache
+ ArtifactCache, Instance, instantiate, hasNDArrayInCache, deleteNDArrayCache
} from "./runtime";
export { Disposable, LibraryProvider } from "./types";
export { RPCServer } from "./rpc_server";
diff --git a/web/src/runtime.ts b/web/src/runtime.ts
index cf2a6069e4..cf8d17e772 100644
--- a/web/src/runtime.ts
+++ b/web/src/runtime.ts
@@ -26,6 +26,7 @@ import { Memory, CachedCallStack } from "./memory";
import { assert, StringToUint8Array } from "./support";
import { Environment } from "./environment";
import { FunctionInfo, WebGPUContext } from "./webgpu";
+import { ArtifactCacheTemplate } from "./artifact_cache";
import * as compact from "./compact";
import * as ctypes from "./ctypes";
@@ -988,7 +989,7 @@ export type InitProgressCallback = (report:
InitProgressReport) => void;
/**
* Cache to store model related data.
*/
-export class ArtifactCache {
+export class ArtifactCache implements ArtifactCacheTemplate {
private scope: string;
private cache?: Cache;
@@ -1021,6 +1022,14 @@ export class ArtifactCache {
.then(cacheKeys => keys.every(key => cacheKeys.indexOf(key) !== -1))
.catch(err => false);
}
+
+ async deleteInCache(url: string) {
+ if (this.cache === undefined) {
+ this.cache = await caches.open(this.scope);
+ }
+ const result = await this.cache.delete(url);
+ return result;
+ }
}
/**
@@ -1454,7 +1463,7 @@ export class Instance implements Disposable {
}
/**
- * Fetch NDArray cache from url.
+ * Given cacheUrl, search up items to fetch based on
cacheUrl/ndarray-cache.json
*
* @param ndarrayCacheUrl The cache url.
* @param device The device to be fetched to.
@@ -1480,6 +1489,7 @@ export class Instance implements Disposable {
this.cacheMetadata = { ...this.cacheMetadata, ...(list["metadata"] as
Record<string, any>) };
}
+
/**
* Fetch list of NDArray into the NDArrayCache.
*
@@ -1492,7 +1502,7 @@ export class Instance implements Disposable {
ndarrayCacheUrl: string,
list: Array<NDArrayShardEntry>,
device: DLDevice,
- artifactCache: ArtifactCache
+ artifactCache: ArtifactCacheTemplate
) {
const perf = compact.getPerformance();
const tstart = perf.now();
@@ -1539,10 +1549,11 @@ export class Instance implements Disposable {
});
}
- for (let i = 0; i < list.length; ++i) {
+ const processShard = async (i: number) => {
reportCallback(i);
- fetchedBytes += list[i].nbytes;
- const dataUrl = new URL(list[i].dataPath, ndarrayCacheUrl).href;
+ const shard = list[i];
+ fetchedBytes += shard.nbytes;
+ const dataUrl = new URL(shard.dataPath, ndarrayCacheUrl).href;
let buffer;
try {
buffer = await (await
artifactCache.fetchWithCache(dataUrl)).arrayBuffer();
@@ -1550,7 +1561,7 @@ export class Instance implements Disposable {
this.env.logger("Error: Cannot fetch " + dataUrl + " err= " + err);
throw err;
}
- const shardRecords = list[i].records;
+ const shardRecords = shard.records;
for (let j = 0; j < shardRecords.length; ++j) {
const rec = shardRecords[j];
const cpu_arr = this.withNewScope(() => {
@@ -1581,6 +1592,7 @@ export class Instance implements Disposable {
}
timeElapsed = Math.ceil((perf.now() - tstart) / 1000);
}
+ await Promise.all(list.map((_, index) => processShard(index)));
reportCallback(list.length);
}
@@ -2456,3 +2468,28 @@ export async function hasNDArrayInCache(
list = list["records"] as Array<NDArrayShardEntry>;
return await artifactCache.hasAllKeys(list.map(key => new URL(key.dataPath,
ndarrayCacheUrl).href));
}
+
+/**
+ * Given cacheUrl, search up items to delete based on
cacheUrl/ndarray-cache.json
+ *
+ * @param cacheUrl
+ * @param cacheScope
+ */
+export async function deleteNDArrayCache(
+ cacheUrl: string,
+ cacheScope = "tvmjs"
+) {
+ const artifactCache = new ArtifactCache(cacheScope);
+ const jsonUrl = new URL("ndarray-cache.json", cacheUrl).href;
+ const result = await artifactCache.fetchWithCache(jsonUrl);
+ let list;
+ if (result instanceof Response){
+ list = await result.json();
+ }
+ const arrayentry = list["records"] as Array<NDArrayShardEntry>;
+ const processShard = async (i: number) => {
+ const dataUrl = new URL(arrayentry[i].dataPath, cacheUrl).href;
+ await artifactCache.deleteInCache(dataUrl);
+ }
+ await Promise.all(arrayentry.map((_, index) => processShard(index)));
+}