def setup(): layer = get_sample_layer() dict_1 = {"O": 16, "I": 1, "W": 1} dict_2 = {"O": 8, "I": 1, "W": 1} global spm_ordering, dram_ordering spm_ordering = layer.get_ordering_from_reuse_factor(dict_1, "SPM") dram_ordering = layer.get_ordering_from_reuse_factor(dict_2, "DRAM")
def test_get_index_vars(): layer = get_sample_layer() O_write, O_read, I, W = get_ops(layer) assert layer._get_index_vars(O_write) == ["N", "M", "Ox", "Oy"] assert layer._get_index_vars(O_read) == ["N", "M", "Ox", "Oy"] assert set(layer._get_index_vars(I)) == set(["N", "C", "Ox", "Oy", "Fx", "Fy"]) assert layer._get_index_vars(W) == ["M", "C", "Fx", "Fy"]
def test_calculate_Cycles_Datadistribution_NOC(): layer = get_sample_layer() cycles = layer.calculate_Cycles_DataDistribution_NOC() assert len(cycles) == 3 assert cycles[layer._O.name] == 3136 assert cycles[layer._I.name] == 512 assert cycles[layer._W.name] == 288
def test_determine_data_reuse(): layer = get_sample_layer() with assert_raises(Exception): layer.determine_data_reuse("Spatial") data_reuse_with_all_orderings = layer.determine_data_reuse("SPM") loop_ordering = spm_ordering data_reuses, data_use_additional_comm = data_reuse_with_all_orderings[ loop_ordering] assert data_reuses["I"] == 1 assert data_reuses["W"] == 1 assert data_reuses["O"] == 16 assert data_use_additional_comm["I"] == 0 assert data_use_additional_comm["W"] == 0 assert data_use_additional_comm["O"] == 0 data_reuse_with_all_orderings = layer.determine_data_reuse("DRAM") loop_ordering = dram_ordering data_reuses, data_use_additional_comm = data_reuse_with_all_orderings[ loop_ordering] assert data_reuses["I"] == 1 assert data_reuses["W"] == 1 assert data_reuses["O"] == 8 assert data_use_additional_comm["I"] == 0 assert data_use_additional_comm["W"] == 0 assert data_use_additional_comm["O"] == 0
def test_get_reads_writes_of_operand(): layer = get_sample_layer() reads, writes = layer._get_reads_writes_of_operand(layer._O.name) assert len(reads) == 1 and len(writes) == 1 reads, writes = layer._get_reads_writes_of_operand(layer._W.name) assert len(reads) == 1 and len(writes) == 0 reads, writes = layer._get_reads_writes_of_operand(layer._I.name) assert len(reads) == 1 and len(writes) == 0
def test_get_operands(): layer = get_sample_layer() O_write, O_read, I, W = get_ops(layer) operands = layer._get_operands() assert O_write in operands[layer._O.name] assert O_read in operands[layer._O.name] assert I in operands[layer._I.name] assert W in operands[layer._W.name]
def test_get_reads_writes(): layer = get_sample_layer() reads, writes = layer._get_reads_writes() assert len(reads) == 3 assert len(writes) == 1 for read in reads: assert isinstance(read, tvm.expr.Load) for write in writes: assert isinstance(write, tvm.stmt.Store)
def test_get_index_exprs(): layer = get_sample_layer() O_write, O_read, I, W = get_ops(layer) keys = ["n", "m", "c", "ox", "oy", "fx", "fy"] values = [ int(layer.get_TripCounts(key.title(), "loop") / layer.get_TripCounts(key.title(), "DRAM")) for key in layer.base_TCs ] local_vars = dict(zip(keys, values)) assert layer._get_index_expr_evaluated(I, 0, local_vars) == 16 assert layer._get_index_expr_evaluated(I, 1, local_vars) == 16 assert layer._get_index_expr_evaluated(I, 2, local_vars) == 32 assert layer._get_index_expr_evaluated(I, 3, local_vars) == 1
def test_get_stores(): layer = get_sample_layer() stores = layer._get_stores() assert len(stores) == 1 store = stores[0] assert isinstance(store, tvm.stmt.Store) stores = layer._get_stores(pass_init=False) assert len(stores) == 2 assert store in stores for store in stores: assert isinstance(store, tvm.stmt.Store)
def test_set_tiling(): layer = get_sample_layer() assert layer._loop_TCs["N_DRAM"] == 4 assert layer._loop_TCs["N_SPM"] == 1 assert layer._loop_TCs["N_RF"] == 1 assert layer._loop_TCs["N_Spatial"] == 1 layer.set_tiling("N", [1, 1, 2, 2]) assert layer._loop_TCs["N_DRAM"] == 1 assert layer._loop_TCs["N_SPM"] == 1 assert layer._loop_TCs["N_RF"] == 2 assert layer._loop_TCs["N_Spatial"] == 2
def test_set_tiling_wrong_inputs(): layer = get_sample_layer() with assert_raises(Exception): # wrong iv name layer.set_tiling("n", [4, 1, 1, 1]) with assert_raises(Exception): # wrong tiling length layer.set_tiling("N", [4, 1, 1, 1, 1]) with assert_raises(Exception): # wrong tiling value layer.set_tiling("N", [4, 2, 1, 1]) # correct case layer.set_tiling("N", [4, 1, 1, 1])
def test_calculate_DMA_Cycles(): layer = get_sample_layer() assert layer.calculate_DMA_Cycles(16384) == 660 assert layer.calculate_DMA_Cycles(6272) == 281
def test_get_Cycles_One_SPM_Pass(): layer = get_sample_layer() cycles_of_all_orderings = layer.get_Cycles_One_SPM_Pass() cycles = cycles_of_all_orderings[(dram_ordering, spm_ordering)] assert cycles == 8192
def test_map_operands_to_NOCs(): layer = get_sample_layer() cycles_of_all_orderings = layer.map_operands_to_NOCs() comm_cycles = cycles_of_all_orderings[(dram_ordering, spm_ordering)][0] assert len(comm_cycles) == 1 assert comm_cycles[1] == 512
def test_calculate_Cycles_InterPECommunication(): layer = get_sample_layer() cycles = layer.calculate_Cycles_InterPECommunication() assert cycles[layer._I.name] == 0 assert cycles[layer._W.name] == 0 assert cycles[layer._O.name] == 3136
def test_computeEnergyCost_RF(): layer = get_sample_layer() assert abs(layer.computeEnergyCost_RF()-1775700541.44) < 1.0e-5
def test_computeEnergyCost_UsefulOps(): layer = get_sample_layer() assert abs(layer.computeEnergyCost_UsefulOps()-34681651.2) < 1.0e-5
def test_computeEnergyCost_DataDistribution_NOC(): layer = get_sample_layer() energy_costs = layer.get_Energy_DataDistribution_NOC() assert abs(energy_costs[layer._I.name] - 6272) == 0 assert abs(energy_costs[layer._W.name] - 28224) == 0 assert abs(energy_costs[layer._O.name] - 6272) == 0
def test_get_min_edp(): layer = get_sample_layer() min_edp, dram_ordering, spm_ordering = layer.get_min_edp() assert min_edp == 1.62016386750976e+16
def test_get_min_energy(): layer = get_sample_layer() min_energy, dram_ordering, spm_ordering = layer.get_min_energy() energy_of_all_orderings = layer.get_Energy_One_Layer() assert min_energy == 3365577523 assert energy_of_all_orderings[(dram_ordering, spm_ordering)] == min_energy
def test_determine_DMA_Access(): layer = get_sample_layer() #(1) result = layer.determine_DMA_Access() assert result["I"]["dma_invocations"] == 1 assert result["I"]["data_accessed_dma"] == 8192 assert result["W"]["dma_invocations"] == 16 assert result["W"]["data_accessed_dma"] == 288 assert result["O"]["dma_invocations"] == 1 assert result["O"]["data_accessed_dma"] == 3136 #(2) layer.set_tiling("N", [4, 1, 1, 1]) layer.set_tiling("M", [16, 1, 8, 2]) layer.set_tiling("C", [8, 16, 1, 2]) layer.set_tiling("Ox", [1, 1, 2, 7]) layer.set_tiling("Oy", [1, 1, 2, 7]) layer.set_tiling("Fx", [3, 1, 1, 1]) layer.set_tiling("Fy", [3, 1, 1, 1]) result = layer.determine_DMA_Access() assert result["I"]["dma_invocations"] == 448 assert result["I"]["data_accessed_dma"] == 14 assert result["W"]["dma_invocations"] == 512 assert result["W"]["data_accessed_dma"] == 1 assert result["O"]["dma_invocations"] == 1 assert result["O"]["data_accessed_dma"] == 3136 #(3) layer.set_tiling("N", [4, 1, 1, 1]) layer.set_tiling("M", [16, 1, 8, 2]) layer.set_tiling("C", [8, 16, 1, 2]) layer.set_tiling("Ox", [1, 1, 2, 7]) layer.set_tiling("Oy", [1, 1, 2, 7]) layer.set_tiling("Fx", [1, 1, 3, 1]) layer.set_tiling("Fy", [3, 1, 1, 1]) result = layer.determine_DMA_Access() assert result["I"]["dma_invocations"] == 512 assert result["I"]["data_accessed_dma"] == 14 assert result["W"]["dma_invocations"] == 1536 assert result["W"]["data_accessed_dma"] == 1 assert result["O"]["dma_invocations"] == 1 assert result["O"]["data_accessed_dma"] == 3136 #(4) layer.set_tiling("N", [4, 1, 1, 1]) layer.set_tiling("M", [16, 1, 8, 2]) layer.set_tiling("C", [8, 16, 1, 2]) layer.set_tiling("Ox", [1, 1, 2, 7]) layer.set_tiling("Oy", [1, 1, 2, 7]) layer.set_tiling("Fx", [3, 1, 1, 1]) layer.set_tiling("Fy", [1, 1, 3, 1]) result = layer.determine_DMA_Access() assert result["I"]["dma_invocations"] == 32 assert result["I"]["data_accessed_dma"] == 224 assert result["W"]["dma_invocations"] == 512 assert result["W"]["data_accessed_dma"] == 3 assert result["O"]["dma_invocations"] == 1 assert result["O"]["data_accessed_dma"] == 3136 #(5) layer.set_tiling("N", [4, 1, 1, 1]) layer.set_tiling("M", [16, 1, 8, 2]) layer.set_tiling("C", [8, 16, 1, 2]) layer.set_tiling("Ox", [1, 1, 2, 7]) layer.set_tiling("Oy", [2, 1, 1, 7]) layer.set_tiling("Fx", [1, 1, 3, 1]) layer.set_tiling("Fy", [1, 1, 3, 1]) result = layer.determine_DMA_Access() assert result["I"]["dma_invocations"] == 512 assert result["I"]["data_accessed_dma"] == 9 assert result["W"]["dma_invocations"] == 16 assert result["W"]["data_accessed_dma"] == 288 assert result["O"]["dma_invocations"] == 224 assert result["O"]["data_accessed_dma"] == 7 #(6) layer.set_tiling("N", [4, 1, 1, 1]) layer.set_tiling("M", [16, 1, 8, 2]) layer.set_tiling("C", [8, 16, 1, 2]) layer.set_tiling("Ox", [2, 1, 1, 7]) layer.set_tiling("Oy", [1, 1, 2, 7]) layer.set_tiling("Fx", [1, 1, 3, 1]) layer.set_tiling("Fy", [1, 1, 3, 1]) result = layer.determine_DMA_Access() assert result["I"]["dma_invocations"] == 32 assert result["I"]["data_accessed_dma"] == 144 assert result["W"]["dma_invocations"] == 16 assert result["W"]["data_accessed_dma"] == 288 assert result["O"]["dma_invocations"] == 16 assert result["O"]["data_accessed_dma"] == 98
def test_calculate_Energy_DMA_Access(): layer = get_sample_layer() dma_access_energy = layer.calculate_Energy_DMA_Access() assert dma_access_energy["I"] == 1638400 assert dma_access_energy["W"] == 921600 assert dma_access_energy["O"] == 627200
def test_computeEnergyCost_One_SPM_Pass(): layer = get_sample_layer() energy_of_all_orderings = layer.get_Energy_One_SPM_Pass() energy_cost = energy_of_all_orderings[(dram_ordering, spm_ordering)] assert abs(energy_cost - 724736) == 0
def test_computeEnergyCost_DataDistribution_SPM(): layer = get_sample_layer() energy_costs = layer.get_Energy_DataCommunication_SPM() assert abs(energy_costs[layer._I.name] - 6912) == 0 assert abs(energy_costs[layer._W.name] - 3888) == 0 assert abs(energy_costs[layer._O.name] - 42336) == 0
def test_calculate_Cycles_DMA_Access(): layer = get_sample_layer() dma_cycles = layer.calculate_Cycles_DMA_Access() assert dma_cycles["I"] == 660 assert dma_cycles["W"] == 1088 assert dma_cycles["O"] == 281
def test_computeExecTime_UsefulOps_One_RF_Pass(): layer = get_sample_layer() layer.env.pe_pipelined = True layer.env.pe_pipeline_stages = 4 assert layer.computeExecTime_UsefulOps_One_RF_Pass() == 288
def test_get_Cycles_One_Layer(): layer = get_sample_layer() cycles_of_all_orderings = layer.get_Cycles_One_Layer() cycle = cycles_of_all_orderings[(dram_ordering, spm_ordering)] assert cycle == 4581376
def test_calculate_Energy_InterPECommunication(): layer = get_sample_layer() energy_costs = layer.calculate_Energy_InterPECommunication() assert energy_costs[layer._I.name] == 0 assert energy_costs[layer._W.name] == 0 assert abs(energy_costs[layer._O.name] - 15538.88) < 1.0e-5
def test_computeEnergyCost_DataCommunication_DRAM(): layer = get_sample_layer() energy_of_all_orderings = layer.get_Energy_DataCommunication_DRAM() energy_cost = energy_of_all_orderings[(dram_ordering, spm_ordering)] expected_energy = 1310720000 + 40140800 + 994488.32 + 3110912 assert abs(energy_cost - expected_energy) < 1.0e-5
def test_TotalEnergy(): layer = get_sample_layer() energy_of_all_orderings = layer.get_Energy_One_Layer() energy = energy_of_all_orderings[(dram_ordering, spm_ordering)] expected_energy = round(34681651.2 + 1775700541.44 + (724736*512) + 1354966200.32) assert abs(energy - expected_energy) == 0