def gpu_iuwt_recomposition(in1, scale_adjust, store_on_gpu, smoothed_array):
    wavelet_filter = (1./16)*np.array([1,4,6,4,1], dtype=np.float32)
    wavelet_filter = gpuarray.to_gpu_async(wavelet_filter)
    max_scale = in1.shape[0] + scale_adjust
    if smoothed_array is None:
        recomposition = gpuarray.zeros([in1.shape[1], in1.shape[2]], np.float32)
    else:
        recomposition = gpuarray.to_gpu(smoothed_array.astype(np.float32))
    try:
        gpu_in1 = gpuarray.to_gpu_async(in1.astype(np.float32))
    except:
        gpu_in1 = in1
    gpu_tmp = gpuarray.empty_like(recomposition)
    gpu_scale = gpuarray.zeros([1], np.int32)
    gpu_scale += max_scale-1
    gpu_a_trous_row_kernel, gpu_a_trous_col_kernel = gpu_a_trous()
    grid_rows = int(in1.shape[1]//32)
    grid_cols = int(in1.shape[2]//32)
    for i in range(max_scale-1, scale_adjust-1, -1):
        gpu_a_trous_row_kernel(recomposition, gpu_tmp, wavelet_filter, gpu_scale,
                                block=(32,32,1), grid=(grid_cols, grid_rows))
        gpu_a_trous_col_kernel(gpu_tmp, recomposition, wavelet_filter, gpu_scale,
                                block=(32,32,1), grid=(grid_cols, grid_rows))
        recomposition = recomposition[:,:] + gpu_in1[i-scale_adjust,:,:]
        gpu_scale -= 1
    if scale_adjust>0:
        for i in range(scale_adjust-1, -1, -1):
            gpu_a_trous_row_kernel(recomposition, gpu_tmp, wavelet_filter, gpu_scale,
                                block=(32,32,1), grid=(grid_cols, grid_rows))
            gpu_a_trous_col_kernel(gpu_tmp, recomposition, wavelet_filter, gpu_scale,
                                block=(32,32,1), grid=(grid_cols, grid_rows))
            gpu_scale -= 1
    if store_on_gpu:
        return recomposition
    else:
        return recomposition.get()