From 9d5e827c2ebb6a10ca9f660b04e00d088e88eb53 Mon Sep 17 00:00:00 2001 From: Emma Smith Date: Mon, 23 Dec 2019 17:14:27 +0000 Subject: [PATCH] Tensor manipulation contract --- examples.yaml | 12 ++ tensor_manipulation/submit_contract.py | 79 +++++++++ .../tensor_manipulation_contract.etch | 158 ++++++++++++++++++ 3 files changed, 249 insertions(+) create mode 100644 tensor_manipulation/submit_contract.py create mode 100644 tensor_manipulation/tensor_manipulation_contract.etch diff --git a/examples.yaml b/examples.yaml index 9fe1a33..080db6f 100644 --- a/examples.yaml +++ b/examples.yaml @@ -21,4 +21,16 @@ setup_conditions: steps: - sleep: 5 - run_python_test: { "script": "ml_examples.01_smart_contract_model.submit_contract", "mode": "boston"} +... +--- +test_description: > + Tensor manipulation test +setup_conditions: + test_name: "tensor_test" + number_of_nodes: 1 + mining_nodes: [0] + max_test_time: 60 +steps: + - sleep: 5 + - run_python_test: { "script": "tensor_manipulation.submit_contract"} ... \ No newline at end of file diff --git a/tensor_manipulation/submit_contract.py b/tensor_manipulation/submit_contract.py new file mode 100644 index 0000000..9a0ecd6 --- /dev/null +++ b/tensor_manipulation/submit_contract.py @@ -0,0 +1,79 @@ +import os + +from fetchai.ledger.api import LedgerApi +from fetchai.ledger.contract import Contract +from fetchai.ledger.crypto import Entity, Address + +HERE = os.path.dirname(__file__) + + +# generic contract setup +def contract_setup(source, benefactor, options): + # Create keypair for the contract owner + entity1 = Entity() + Address(entity1) + + host = options['host'] + port = options['port'] + # create the APIs + api = LedgerApi(host, port) + + # Transfer tokens from benefactor + api.sync(api.tokens.transfer(benefactor, entity1, int(1e8), 1000)) + + # Create contract + contract = Contract(source, entity1) + + # Deploy contract + api.sync(contract.create(api, entity1, api.tokens.balance(entity1))) + + return api, contract, entity1 + + +# run function for running on end to end tests +def run(options, benefactor): + source_file = os.path.join(HERE, "tensor_manipulation_contract.etch") + + with open(source_file, "r") as fp: + source = fp.read() + + print(options) + + if benefactor is None or options is None: + raise Exception("Must give options and benefactor") + + api, contract, entity = contract_setup(source, benefactor, options) + + # add two tensors and get result + data_string = "2,3,4,5" + label_string = "1,2,3,4" + api.sync(contract.action(api, 'add', api.tokens.balance(entity), + [entity], data_string, label_string)) + prediction = contract.query(api, 'getOutput') + print("Ouput is: " + prediction) + + # subtract two tensors and get result + api.sync(contract.action(api, 'subtract', api.tokens.balance(entity), + [entity], data_string, label_string)) + prediction = contract.query(api, 'getOutput') + print("Ouput is: " + prediction) + + api.sync(contract.action(api, 'multiply', api.tokens.balance(entity), + [entity], data_string, label_string)) + prediction = contract.query(api, 'getOutput') + print("Ouput is: " + prediction) + + api.sync(contract.action(api, 'divide', api.tokens.balance(entity), + [entity], data_string, label_string)) + prediction = contract.query(api, 'getOutput') + print("Ouput is: " + prediction) + + api.sync(contract.action(api, 'copy', api.tokens.balance(entity), + [entity], data_string)) + prediction = contract.query(api, 'getOutput') + print("Ouput is: " + prediction) + + api.sync(contract.action(api, 'at', api.tokens.balance(entity), + [entity], data_string, 3)) + prediction = contract.query(api, 'getOutput') + print("Ouput is: " + prediction) diff --git a/tensor_manipulation/tensor_manipulation_contract.etch b/tensor_manipulation/tensor_manipulation_contract.etch new file mode 100644 index 0000000..c1195a7 --- /dev/null +++ b/tensor_manipulation/tensor_manipulation_contract.etch @@ -0,0 +1,158 @@ +//------------------------------------------------------------------------------ +// +// Copyright 2019 Fetch.AI Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//------------------------------------------------------------------------------ + +persistent output_state : Tensor; + +// initial set up creates the model and persistent data +@init +function setup(owner : Address) + use output_state; + var tensor_shape = Array(2); + tensor_shape[0] = 2u64; + tensor_shape[1] = 2u64; + var output = Tensor(tensor_shape); + + output_state.set(output); +endfunction + +// get the output state +@query +function getOutput() : String + use output_state; + var output = output_state.get(); + return output.toString(); +endfunction + + +// add two tensors and save to state +@action +function add(tensor1_string: String, tensor2_string: String) + var tensor_shape = Array(2); + tensor_shape[0] = 1u64; + tensor_shape[1] = 1u64; + var tensor1 = Tensor(tensor_shape); + tensor1.fromString(tensor1_string); + + var tensor2 = Tensor(tensor_shape); + tensor2.fromString(tensor2_string); + + use output_state; + var output = output_state.get(); + output = tensor1 + tensor2; + output_state.set(output); +endfunction + + +// subtract two tensors and save to state +@action +function subtract(tensor1_string: String, tensor2_string: String) + var tensor_shape = Array(2); + tensor_shape[0] = 1u64; + tensor_shape[1] = 1u64; + var tensor1 = Tensor(tensor_shape); + tensor1.fromString(tensor1_string); + + var tensor2 = Tensor(tensor_shape); + tensor2.fromString(tensor2_string); + + use output_state; + var output = output_state.get(); + output = tensor1 - tensor2; + output_state.set(output); +endfunction + +@action +function multiply(tensor1_string: String, tensor2_string: String) + var tensor_shape = Array(2); + tensor_shape[0] = 1u64; + tensor_shape[1] = 1u64; + var tensor1 = Tensor(tensor_shape); + tensor1.fromString(tensor1_string); + + var tensor2 = Tensor(tensor_shape); + tensor2.fromString(tensor2_string); + + use output_state; + var output = output_state.get(); + output = tensor1 * tensor2; + output_state.set(output); +endfunction + +@action +function divide(tensor1_string: String, tensor2_string: String) + var tensor_shape = Array(2); + tensor_shape[0] = 1u64; + tensor_shape[1] = 1u64; + var tensor1 = Tensor(tensor_shape); + tensor1.fromString(tensor1_string); + + var tensor2 = Tensor(tensor_shape); + tensor2.fromString(tensor2_string); + + use output_state; + var output = output_state.get(); + output = tensor1 / tensor2; + output_state.set(output); +endfunction + +@action +function copy(tensor1_string: String) + var tensor_shape = Array(2); + tensor_shape[0] = 1u64; + tensor_shape[1] = 1u64; + var tensor1 = Tensor(tensor_shape); + tensor1.fromString(tensor1_string); + + use output_state; + var output = output_state.get(); + output = tensor1.copy(); + output_state.set(output); +endfunction + +@action +function at(tensor1_string: String, index: UInt64) + var tensor_shape = Array(2); + tensor_shape[0] = 1u64; + tensor_shape[1] = 1u64; + var tensor1 = Tensor(tensor_shape); + tensor1.fromString(tensor1_string); + + use output_state; + tensor_shape = Array(1); + tensor_shape[0] = 1u64; + var output = Tensor(tensor_shape); + output.setAt(0u64, tensor1.at(0u64, index)); + output_state.set(output); +endfunction + +function main() + use output_state; + var tensor_shape = Array(2); + tensor_shape[0] = 2u64; + tensor_shape[1] = 2u64; + var output = Tensor(tensor_shape); + + output_state.set(output); + + var tensor1_string = "2, 3, 4, 5"; + var tensor2_string = "1, 2, 3, 4"; + add(tensor1_string, tensor2_string); + subtract(tensor1_string, tensor2_string); + + printLn(getOutput()); +endfunction \ No newline at end of file