def test_get_tensor_histogram_success(self):
        """Get tensor histogram success."""
        test_tag_name = self._complete_tag_name

        processor = TensorProcessor(self._mock_data_manager)
        results = processor.get_tensors([self._train_id], [test_tag_name],
                                        None,
                                        None,
                                        detail='histogram')

        recv_metadata = results.get('tensors')[0].get("values")

        for recv_values, expected_values in zip(recv_metadata, self._tensors):
            assert recv_values.get('wall_time') == expected_values.get(
                'wall_time')
            assert recv_values.get('step') == expected_values.get('step')
            expected_data = expected_values.get('value').get("float_data")
            expected_statistic = TensorUtils.get_statistics_from_tensor(
                expected_data)
            expected_buckets = calc_original_buckets(expected_data,
                                                     expected_statistic)
            recv_buckets = recv_values.get('value').get("histogram_buckets")

            for recv_bucket, expected_bucket in zip(recv_buckets,
                                                    expected_buckets):
                assert recv_bucket[0] - expected_bucket.left < 1e-6
                assert recv_bucket[1] - expected_bucket.width < 1e-6
                assert recv_bucket[2] - expected_bucket.count <= 1
    def test_get_tensor_stats_success(self):
        """Get tensor stats success."""
        test_tag_name = self._complete_tag_name

        processor = TensorProcessor(self._mock_data_manager)
        results = processor.get_tensors([self._train_id], [test_tag_name],
                                        None,
                                        None,
                                        detail='stats')

        recv_metadata = results.get('tensors')[0].get("values")

        for recv_values, expected_values in zip(recv_metadata, self._tensors):
            assert recv_values.get('wall_time') == expected_values.get(
                'wall_time')
            assert recv_values.get('step') == expected_values.get('step')
            expected_data = expected_values.get('value').get("float_data")
            expected_statistic_instance = TensorUtils.get_statistics_from_tensor(
                expected_data)
            expected_statistic = TensorUtils.get_statistics_dict(
                stats=expected_statistic_instance,
                overall_stats=expected_statistic_instance)
            recv_statistic = recv_values.get('value').get("statistics")
            assert recv_statistic.get("max") - expected_statistic.get(
                "max") < 1e-6
            assert recv_statistic.get("min") - expected_statistic.get(
                "min") < 1e-6
            assert recv_statistic.get("avg") - expected_statistic.get(
                "avg") < 1e-6
            assert recv_statistic.get("count") - expected_statistic.get(
                "count") < 1e-6
    def test_get_tensor_data_success(self):
        """Get tensor data success."""
        test_tag_name = self._complete_tag_name

        processor = TensorProcessor(self._mock_data_manager)
        results = processor.get_tensors([self._train_id], [test_tag_name],
                                        step='1',
                                        dims='[0,0,:-1,:]',
                                        detail='data')

        recv_metadata = results.get('tensors')[0].get("values")

        for recv_values, expected_values in zip(recv_metadata, self._tensors):
            assert recv_values.get('wall_time') == expected_values.get(
                'wall_time')
            assert recv_values.get('step') == expected_values.get('step')
            dims = expected_values.get('value').get("dims")
            expected_data = np.array(
                expected_values.get('value').get("float_data")).reshape(dims)
            recv_tensor = np.array(recv_values.get('value').get("data"))
            expected_tensor = TensorUtils.get_specific_dims_data(
                expected_data, (0, 0, slice(None, -1, None), slice(None)))
            # Compare tensor shape when recv_tensor shape is not empty.
            if recv_tensor.shape != (0, ):
                assert recv_tensor.shape == expected_tensor.shape
                assert np.allclose(recv_tensor, expected_tensor, rtol=1e-6)
    def test_get_tensors_with_not_exist_id(self):
        """Get tensor data with not exist id."""
        test_train_id = 'not_exist_id'
        processor = TensorProcessor(self._mock_data_manager)
        with pytest.raises(TrainJobNotExistError) as exc_info:
            processor.get_tensors([test_train_id], [self._tag_name], None, None, None)

        assert exc_info.value.error_code == '50545005'
        assert exc_info.value.message == "Train job is not exist. Detail: Can not find the given train job in cache."
    def test_get_tensor_data_with_not_dims(self):
        """Get tensor data with not dims."""
        test_tag_name = self._complete_tag_name

        processor = TensorProcessor(self._mock_data_manager)
        with pytest.raises(ParamMissError) as exc_info:
            processor.get_tensors([self._train_id], [test_tag_name], step='1', dims=None, detail='data')

        assert exc_info.value.error_code == '50540003'
        assert "Param missing. 'dims' is required." in exc_info.value.message
    def test_get_tensors_with_not_exist_tag(self):
        """Get tensor data with not exist tag."""
        test_tag_name = 'not_exist_tag_name'

        processor = TensorProcessor(self._mock_data_manager)

        with pytest.raises(TensorNotExistError) as exc_info:
            processor.get_tensors([self._train_id], [test_tag_name], None, None, None)

        assert exc_info.value.error_code == '50545012'
        assert "Can not find any data in this train job by given tag." in exc_info.value.message
    def test_get_tensor_data_with_exceed_two_dims(self):
        """Get tensor data with exceed two dims."""
        test_tag_name = self._complete_tag_name

        processor = TensorProcessor(self._mock_data_manager)
        with pytest.raises(ParamValueError) as exc_info:
            processor.get_tensors([self._train_id], [test_tag_name], step='1', dims='[0,:,:,:]', detail='data')

        assert exc_info.value.error_code == '50540002'
        assert "Invalid parameter value. Flexible dimensions cannot exceed limit value: 2, size: 3" \
               in exc_info.value.message
    def test_get_tensor_data_with_wrong_dims(self):
        """Get tensor data with wrong dims."""
        test_tag_name = self._complete_tag_name

        processor = TensorProcessor(self._mock_data_manager)
        with pytest.raises(ParamValueError) as exc_info:
            processor.get_tensors([self._train_id], [test_tag_name], step='1', dims='[0,:]', detail='data')

        assert exc_info.value.error_code == '50540002'
        assert "Invalid parameter value. The length of param dims: 2, is not equal to the length of tensor dims: 4" \
               in exc_info.value.message
    def test_get_tensors_with_not_support_detail(self):
        """Get tensor data with not support detail."""
        test_tag_name = self._complete_tag_name

        processor = TensorProcessor(self._mock_data_manager)
        with pytest.raises(ParamValueError) as exc_info:
            processor.get_tensors([self._train_id], [test_tag_name], None, None, detail='data1')

        assert exc_info.value.error_code == '50540002'
        assert "Invalid parameter value. Can not support this value: data1 of detail." \
               in exc_info.value.message
    def test_get_tensor_data_with_exceed_two_dims(self):
        """Get tensor data with exceed two dims."""
        test_tag_name = self._complete_tag_name

        processor = TensorProcessor(self._mock_data_manager)
        with pytest.raises(ParamValueError) as exc_info:
            processor.get_tensors([self._train_id], [test_tag_name],
                                  step='1',
                                  dims='[0,:,:,:]',
                                  detail='data')

        assert exc_info.value.error_code == '50540002'
        assert "Invalid shape. At most 2 dimensions are specified" in exc_info.value.message
def get_tensors():
    """
    Interface to obtain tensor data.

    Returns:
        Response, which contains a JSON object.
    """
    train_ids = request.args.getlist('train_id')
    tags = request.args.getlist('tag')
    step = request.args.get("step", default=None)
    dims = request.args.get("dims", default=None)
    detail = request.args.get("detail", default=None)

    processor = TensorProcessor(DATA_MANAGER)
    response = processor.get_tensors(train_ids, tags, step, dims, detail)
    return jsonify(response)
    def test_get_tensor_data_success(self):
        """Get tensor data success."""
        test_tag_name = self._complete_tag_name

        processor = TensorProcessor(self._mock_data_manager)
        results = processor.get_tensors([self._train_id], [test_tag_name], step='1', dims='[0,0,:,:]', detail='data')

        recv_metadata = results.get('tensors')[0].get("values")

        for recv_values, expected_values in zip(recv_metadata, self._tensors):
            assert recv_values.get('wall_time') == expected_values.get('wall_time')
            assert recv_values.get('step') == expected_values.get('step')
            dims = expected_values.get('value').get("dims")
            expected_data = np.array(expected_values.get('value').get("float_data")).reshape(dims)
            recv_tensor = np.array(recv_values.get('value').get("data"))
            expected_tensor = TensorUtils.get_specific_dims_data(expected_data, [0, 0, None, None], dims)
            assert np.sum(np.isclose(recv_tensor, expected_tensor, rtol=1e-6) == 0) == 0