def main(): parser = argparse.ArgumentParser() parser.add_argument("--backend", default="webgpu,webgl,webassembly,fallback") parser.add_argument("--encoding") parser.add_argument('--out', '-o', default='output_chainer', help='Directory to output the graph descriptor') _, _, _, graph = generate_graph() args = parser.parse_args() os.makedirs(args.out, exist_ok=True) any_backend_failed = False last_backend_exception = None for backend in args.backend.split(","): try: graph_exec_data = generate_descriptor( backend, graph, constant_encoder_name=args.encoding) graph_exec_data.save(args.out) except Exception as ex: any_backend_failed = True last_backend_exception = ex console.error( f"Failed generating descriptor for backend {backend}: {str(ex)}\n" ) if any_backend_failed: raise last_backend_exception
def main(): sys.setrecursionlimit(10000) # workaround for deep copying large graph parser = argparse.ArgumentParser() parser.add_argument("--model", default="resnet50", choices=["vgg16", "resnet50"]) parser.add_argument("--backend", default="webgpu,webassembly,fallback") parser.add_argument("--encoding") parser.add_argument('--out', '-o', default='output_chainer', help='Directory to output the graph descriptor') args = parser.parse_args() os.makedirs(args.out, exist_ok=True) sample_image = np.zeros((224, 224, 3), dtype=np.uint8) # PIL.Image.open("") if args.model == "vgg16": link = chainer.links.model.vision.vgg.VGG16Layers() prepared_image = chainer.links.model.vision.vgg.prepare( sample_image) # BGR, CHW elif args.model == "resnet50": link = chainer.links.model.vision.resnet.ResNet50Layers() prepared_image = chainer.links.model.vision.resnet.prepare( sample_image) else: raise NotImplementedError nn_input = chainer.Variable(np.array([prepared_image], dtype=np.float32)) if chainer.__version__ >= "2.": with chainer.using_config('train', False): nn_output = link(nn_input, layers=['prob'])['prob'] else: nn_output = link(nn_input, layers=['prob'], test=True)['prob'] graph = ChainerConverter().convert([nn_input], [nn_output]) # type: Graph any_backend_failed = False last_backend_exception = None for backend in args.backend.split(","): try: graph_exec_data = generate_descriptor( backend, graph, constant_encoder_name=args.encoding) graph_exec_data.save(args.out) except Exception as ex: any_backend_failed = True last_backend_exception = ex console.error( f"Failed generating descriptor for backend {backend}: {str(ex)}\n" ) if any_backend_failed: raise last_backend_exception
def validate_kernel_source(descriptor: GraphDescriptor): # FIXME: WebGPU supports multi shader languages, but this test supposes the language as METAL. source = descriptor.concat_kernel_sources() if os.name != 'posix': # os.name in mac is 'posix', and xcrun command is only in mac console.warning( "[WebGPUDescriptorGenerator] 'xcrun' command is not found. validation of generated source code in webgpu backend is " "skipped.") return with tmp.TemporaryDirectory() as tmpdir: source_path = path.join(tmpdir, "kernel.metal") lib_path = path.join(tmpdir, "kernel.air") with open(source_path, "w+") as f: f.write(source) try: result = subprocess.run([ "xcrun", "-sdk", "macosx", "metal", source_path, "-o", lib_path ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) if result.returncode == 0: if result.stderr == b"": console.debug( "[WebGPUDescriptorGenerator] Generated kernel source is valid." ) else: console.warning( "[WebGPUDescriptorGenerator] In validating kernel source, warnings are generated." ) console.stderr(result.stderr.decode("utf-8")) else: console.error( "[WebGPUDescriptorGenerator] Generated kernel source is invalid." ) console.stderr(result.stderr.decode("utf-8")) exit(result.returncode) except FileNotFoundError: console.warning( "[WebGPUDescriptorGenerator] 'xcrun' command is not found. validation of generated source code in webgpu backend is " "skipped.") return
def main(): sys.setrecursionlimit(10000) # workaround for deep copying large graph parser = argparse.ArgumentParser() # default is Caffenet of Caffe example parser.add_argument("caffemodel") parser.add_argument("--backend", default="webgpu,webassembly,fallback", help="comma-separated list of backends") parser.add_argument("--input_name", help="blob name for input (mandatory)") parser.add_argument("--input_shape", help="shape of blobs for inputs (example: '(1,3,224,224)')") parser.add_argument("--input_npy", help="npy file containing sample inputs") parser.add_argument("--output_names", required=True, help="comma-separated blob name for output (mandatory)") parser.add_argument("--out", help="output directory (default: <model>/webdnn_graph_descriptor)") parser.add_argument("--encoding", help="name of weight encoder") args = parser.parse_args() # multiple blob input can be easily implemented, but command-line arguments becomes complicated. input_blob, input_filled = parse_input_blob(args) output_names = args.output_names.split(",") console.stderr("[convert_caffe] Loading caffe model... (usually takes several minutes)") link = chainer.links.caffe.CaffeFunction(args.caffemodel) console.stderr("[convert_caffe] Generating feedforward graph") if chainer.__version__ >= "2.": chainer.using_config("train", False) output_blobs = list( link(inputs={args.input_name: input_blob}, outputs=output_names)) # list of Variable else: output_blobs = list( link(inputs={args.input_name: input_blob}, outputs=output_names, train=False)) # list of Variable chainer_cg = chainer.computational_graph.build_computational_graph(output_blobs) converter = ChainerConverter() graph = converter.convert(chainer_cg, [input_blob], output_blobs) # type: Graph if args.out: output_dir = args.out else: output_dir = path.join(path.dirname(args.caffemodel), "webdnn_graph_descriptor") os.makedirs(output_dir, exist_ok=True) if input_filled: # save output of Caffe Network (not required for inference) output_arrays = {output_name: output_blob.data for output_name, output_blob in zip(output_names, output_blobs)} np.savez(path.join(output_dir, "example_output.npz"), **output_arrays) console.stderr("[convert_caffe] Generating descriptors") any_backend_failed = False for backend in args.backend.split(","): try: graph_exec_data = generate_descriptor(backend, graph, constant_encoder_name=args.encoding) graph_exec_data.save(output_dir) except Exception as ex: any_backend_failed = True console.error(f"[convert_caffe] Failed generating descriptor for backend {backend}: {str(ex)}") if any_backend_failed: sys.exit(1)
def main(): sys.setrecursionlimit(10000) # workaround for deep copying large graph parser = argparse.ArgumentParser() parser.add_argument("kerasmodel") parser.add_argument("--backend", default="webgpu,webassembly,fallback", help="comma-separated list of backends") parser.add_argument("--input_shape", required=True, help="shape of blobs for inputs (example: '(1,3,224,224)')") # parser.add_argument("--input_data_format", choices=["channels_first", "channels_last"]) parser.add_argument("--out", help="output directory (default: <model>/webdnn_graph_descriptor)") parser.add_argument("--encoding", help="name of weight encoder") parser.add_argument("--visualize_ir", action="store_true") parser.add_argument("--plugin", action="append", help="plugin python files which are imported before transpiling") args = parser.parse_args() console.stderr(f"[{path.basename(__file__)}] Generating feedforward graph") class_list = [] if args.plugin: for plugin_path in args.plugin: class_list += _load_plugin(plugin_path) if len(class_list) > 0: # custom_objects is a dictionary for load_model to load user-defined custom layers custom_objects = {} for k, v in class_list: custom_objects[k] = v input_shape, _ = Shape.parse(args.input_shape) input_shapes = [input_shape] model = keras.models.load_model(args.kerasmodel, custom_objects=custom_objects) model.build() converter = KerasConverter() graph = converter.convert(model) for graph_input, input_shape in zip(graph.inputs, input_shapes): for p1, p2 in zip(graph_input.shape, input_shape): if not Placeholder.check_resolved(p1) and Placeholder.check_resolved(p2): p1.value = Placeholder.force_int(p2) elif Placeholder.check_resolved(p1) and not Placeholder.check_resolved(p2): raise ValueError(f'Shape mismatch: {p1} != {p2}') elif Placeholder.check_resolved(p1) and Placeholder.check_resolved(p2): assert p1 == p2, f'Shape mismatch: {p1} != {p2}' if args.out: output_dir = args.out else: output_dir = path.join(path.dirname(args.kerasmodel), "webdnn_graph_descriptor") os.makedirs(output_dir, exist_ok=True) if args.visualize_ir: ir_dot_path = path.join(output_dir, "ir.dot") with open(ir_dot_path, "w") as f: f.write(dump_dot(graph)) console.stderr(f"IR graph can be visualized with graphviz command: 'dot {ir_dot_path} -T png -o output.png'") console.stderr(f"[{path.basename(__file__)}] Generating graph descriptor") any_backend_failed = False backends = args.backend.split(",") for i, backend in enumerate(backends): console.stderr(f"[{path.basename(__file__)}] Backend: {console.colorize(backend, console.Color.Cyan)}") try: graph_exec_data = generate_descriptor(backend, graph, constant_encoder_name=args.encoding) graph_exec_data.save(output_dir) except Exception as ex: if flags.DEBUG: raise ex any_backend_failed = True console.error(f"[{path.basename(__file__)}] Failed generating descriptor for {backend} backend") console.stderr(traceback.format_exc()) continue if any_backend_failed: exit(1)
def main(): sys.setrecursionlimit(10000) # workaround for deep copying large graph parser = argparse.ArgumentParser() parser.add_argument("--backend", default="webgpu,webassembly") parser.add_argument("--encoding", default="eightbit") parser.add_argument('--out', '-o', default='webdnn/image-caption-model', help='Directory to output the graph descriptor') parser.add_argument('--sentence', '-s', required=True, type=str, help='sentence dataset file path') parser.add_argument('--model', '-m', required=True, type=str, help='input model file path') parser.add_argument("--example_image", help="example image for comparing output") parser.add_argument("--visualize_ir", action="store_true") args = parser.parse_args() os.makedirs(args.out, exist_ok=True) out_dir_graph1 = os.path.join(args.out, "image-feature") out_dir_graph2 = os.path.join(args.out, "caption-generation") hidden_num = 512 with open(args.sentence, 'rb') as f: sentence_dataset = pickle.load(f) word_ids = sentence_dataset['word_ids'] word_num = len(word_ids) id_to_word = [""] * word_num for k, v in word_ids.items(): id_to_word[v] = k with open(os.path.join(args.out, "word_data.json"), "w") as f: json.dump( { "id_to_word": id_to_word, "bos_id": word_ids["<S>"], "eos_id": word_ids["</S>"], "word_num": word_num, "hidden_num": hidden_num }, f) caption_net = ImageCaption(word_num=word_num, feature_num=2048, hidden_num=hidden_num) chainer.serializers.load_hdf5(args.model, caption_net) graph1 = generate_graph_model1(caption_net) graph2 = generate_graph_model2(caption_net, hidden_num=hidden_num) if args.example_image: example_io = generate_example_io(caption_net, word_ids, args.example_image) with open(os.path.join(args.out, "example_io.json"), "w") as f: json.dump(example_io, f) if args.visualize_ir: ir_dot_path = os.path.join(args.out, "ir.dot") with open(ir_dot_path, "w") as f: f.write(dump_dot(graph2)) console.stderr( f"IR graph can be visualized with graphviz command: 'dot {ir_dot_path} -T png -o output.png'" ) any_backend_failed = False last_backend_exception = None for backend in args.backend.split(","): try: graph_exec_data = generate_descriptor( backend, graph1, constant_encoder_name=args.encoding) graph_exec_data.save(out_dir_graph1) graph_exec_data = generate_descriptor( backend, graph2, constant_encoder_name=args.encoding) graph_exec_data.save(out_dir_graph2) except Exception as ex: any_backend_failed = True last_backend_exception = ex console.error( f"Failed generating descriptor for backend {backend}: {str(ex)}\n" ) if any_backend_failed: raise last_backend_exception