コード例 #1
0
ファイル: worker_vk.py プロジェクト: yibit/graphicsfuzz
def doImageJob(imageJob):
    name = imageJob.name.replace('.frag', '')
    fragFile = name + '.frag'
    jsonFile = name + '.json'
    png = 'image.png'
    log = 'log.txt'

    res = tt.ImageJobResult()

    # Set nice defaults to fields we will not update anyway
    res.passSanityCheck = True
    res.log = 'Start: ' + name + '\n'

    writeToFile(imageJob.fragmentSource, fragFile)
    writeToFile(imageJob.uniformsInfo, jsonFile)

    remove(png)
    remove(log)

    getimageResult = getImageVulkanAndroid(fragFile)

    # Try to get our own log file in any case
    if os.path.exists('log.txt'):
        res.log += '\n#### LOG START\n'
        with open(log, 'r') as f:
            res.log += f.read()
        res.log += '\n#### LOG END\n'

    # Always add ADB logcat
    adb('logcat -b crash -b system -d > logcat.txt')
    res.log += '\n#### ADB LOGCAT START\n'
    with open('logcat.txt', 'r') as f:
        res.log += f.read()
    res.log += '\n#### ADB LOGCAT END\n'

    if getimageResult == 'crash':
        res.status = tt.JobStatus.CRASH
    elif getimageResult == 'timeout':
        res.status = tt.JobStatus.TIMEOUT
    else:
        assert (getimageResult == 'success')
        res.status = tt.JobStatus.SUCCESS
        with open(png, 'rb') as f:
            res.PNG = f.read()

    return res
コード例 #2
0
def do_image_job(args, image_job):
    name = image_job.name
    if name.endswith('.frag'):
        name = remove_end(name, '.frag')
    frag_file = name + '.frag'
    json_file = name + '.json'
    png = 'image_0.png'
    log = 'vklog.txt'

    frag_spv_file = name + '.frag.spv'
    vert_spv_file = name + '.vert.spv'

    res = tt.ImageJobResult()

    skip_render = image_job.skipRender

    # Set nice defaults to fields we will not update anyway
    res.passSanityCheck = True
    res.log = 'Start: ' + name + '\n'

    write_to_file(image_job.fragmentSource, frag_file)
    write_to_file(image_job.uniformsInfo, json_file)
    prepare_shaders(frag_file, frag_spv_file, vert_spv_file)

    # Optimize
    if args.spirvopt:
        frag_spv_file_opt = frag_spv_file + '.opt'
        cmd = os.path.dirname(HERE) + '/../../bin/' + get_bin_type() + '/spirv-opt ' + \
            args.spirvopt + ' ' + frag_spv_file + ' -o ' + frag_spv_file_opt

        try:
            res.log += 'spirv-opt flags: ' + args.spirvopt + '\n'
            print('Calling spirv-opt with flags: ' + args.spirvopt)
            subprocess.run(cmd,
                           shell=True,
                           stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE,
                           universal_newlines=True,
                           check=True,
                           timeout=TIMEOUT_SPIRV_OPT)
        except subprocess.CalledProcessError as err:
            # spirv-opt failed, early return
            res.log += 'Error triggered by spirv-opt\n'
            res.log += 'COMMAND:\n' + err.cmd + '\n'
            res.log += 'RETURNCODE: ' + str(err.returncode) + '\n'
            if err.stdout:
                res.log += 'STDOUT:\n' + err.stdout + '\n'
            if err.stderr:
                res.log += 'STDERR:\n' + err.stderr + '\n'
            res.status = tt.JobStatus.UNEXPECTED_ERROR
            return res
        except subprocess.TimeoutExpired as err:
            # spirv-opt timed out, early return
            res.log += 'Timeout from spirv-opt\n'
            res.log += 'COMMAND:\n' + err.cmd + '\n'
            res.log += 'TIMEOUT: ' + str(err.timeout) + ' sec\n'
            if err.stdout:
                res.log += 'STDOUT:\n' + err.stdout + '\n'
            if err.stderr:
                res.log += 'STDERR:\n' + err.stderr + '\n'
            res.status = tt.JobStatus.UNEXPECTED_ERROR
            return res

        frag_spv_file = frag_spv_file_opt

    remove(png)
    remove(log)

    if args.linux:
        vkrun.run_linux(vert_spv_file, frag_spv_file, json_file, skip_render)
    else:
        wait_for_screen = not args.force
        vkrun.run_android(vert_spv_file, frag_spv_file, json_file, skip_render,
                          wait_for_screen)

    if os.path.isfile(log):
        with open(log, 'r', encoding='utf-8', errors='ignore') as f:
            res.log += f.read()

    if os.path.isfile(png):
        with open(png, 'rb') as f:
            res.PNG = f.read()

    if os.path.isfile('STATUS'):
        with open('STATUS', 'r') as f:
            status = f.read().rstrip()
        if status == 'SUCCESS':
            res.status = tt.JobStatus.SUCCESS
        elif status == 'CRASH':
            res.status = tt.JobStatus.CRASH
        elif status == 'TIMEOUT':
            res.status = tt.JobStatus.TIMEOUT
        elif status == 'SANITY_ERROR':
            res.status = tt.JobStatus.SANITY_ERROR
        elif status == 'UNEXPECTED_ERROR':
            res.status = tt.JobStatus.UNEXPECTED_ERROR
        elif status == 'NONDET':
            res.status = tt.JobStatus.NONDET
            with open('nondet0.png', 'rb') as f:
                res.PNG = f.read()
            with open('nondet1.png', 'rb') as f:
                res.PNG2 = f.read()
        else:
            res.log += '\nUnknown status value: ' + status + '\n'
            res.status = tt.JobStatus.UNEXPECTED_ERROR
    else:
        # Not even a status file?
        res.log += '\nNo STATUS file\n'
        res.status = tt.JobStatus.UNEXPECTED_ERROR

    return res
コード例 #3
0
def main():
    description = (
        'Uses the piglit GLES3 shader runner to render shader jobs.')

    parser = argparse.ArgumentParser(description=description)

    # Required
    parser.add_argument('worker_name',
                        help='The name that will refer to this worker.')

    # Optional
    parser.add_argument(
        '--server',
        default='http://localhost:8080',
        help='Server URL to connect to (default: http://localhost:8080 )')

    args = parser.parse_args()

    gfuzz_common.tool_on_path('shader_runner_gles3')
    gfuzz_common.log('Worker: ' + args.worker_name)
    server = args.server + '/request'
    gfuzz_common.log('server: ' + server)

    # Get worker info
    worker_info_json_string = '{}'

    gfuzz_common.log('Dumping glxinfo to file for worker info string...')
    try:
        dump_glxinfo(WORKER_INFO_FILE)
        with gfuzz_common.open_helper(WORKER_INFO_FILE, 'r') as info_file:
            worker_info_json_string = info_file.read()
    except Exception as ex:
        gfuzz_common.log(str(ex))
        gfuzz_common.log('Could not get worker info, continuing without it.')

    service = None
    worker = None

    while True:
        if not service:
            gfuzz_common.log('Connecting to server...')
            service, worker = thrift_connect(server, args.worker_name,
                                             worker_info_json_string)
            if not service:
                gfuzz_common.log('Failed to connect, retrying...')
                time.sleep(1)
                continue

        assert worker

        os.makedirs(worker, exist_ok=True)

        try:
            job = service.getJob(worker)
            if job.noJob is not None:
                gfuzz_common.log("No job")
            elif job.skipJob is not None:
                gfuzz_common.log("Skip job")
                service.jobDone(worker, job)
            else:
                assert job.imageJob
                if job.imageJob.computeSource:
                    gfuzz_common.log("Got a compute job, but this worker "
                                     "doesn't support compute shaders.")
                    job.imageJob.result = tt.ImageJobResult()
                    job.imageJob.result.status = tt.JobStatus.UNEXPECTED_ERROR
                else:
                    gfuzz_common.log("#### Image job: " + job.imageJob.name)
                    job.imageJob.result = do_image_job(job.imageJob,
                                                       work_dir=worker)
                gfuzz_common.log("Sending back, results status: {}".format(
                    job.imageJob.result.status))
                service.jobDone(worker, job)
                gfuzz_common.remove(worker)
                continue
        except (TApplicationException, ConnectionError):
            gfuzz_common.log(
                "Connection to server lost. Re-initialising client.")
            service = None
        time.sleep(1)
コード例 #4
0
def do_image_job(image_job: tt.ImageJob, work_dir: str) -> tt.ImageJobResult:
    """
    Does an image job. Sets up directories and some files, then delegates to run_image_job to
    convert the job to a shader_test and run it. Sets a global logfile to log to for the lifetime
    of the function. Gets the status of the shader job from a file that is written to by
    run_image_job.
    :param image_job: the image job containing the shader/uniforms.
    :param work_dir: the directory to work in.
    :return: the result of the image job, including the log, PNG and status.
    """
    # Output directory is based on the name of job.
    output_dir = os.path.join(work_dir, image_job.name)

    # Delete and create output directory.
    gfuzz_common.remove(output_dir)
    os.makedirs(output_dir, exist_ok=True)

    name = image_job.name
    if name.endswith('.frag'):
        name = gfuzz_common.remove_end(name, '.frag')

    frag_file = os.path.join(output_dir, name + FRAG_SUFFIX)
    json_file = os.path.join(output_dir, name + JSON_SUFFIX)
    log_file = os.path.join(output_dir, LOGFILE_NAME)
    status_file = os.path.join(output_dir, STATUS_FILENAME)
    png_file = os.path.join(output_dir, name + PNG_SUFFIX)
    nondet_0 = os.path.join(output_dir, NONDET0_PNG)
    nondet_1 = os.path.join(output_dir, NONDET1_PNG)

    gfuzz_common.write_to_file(image_job.fragmentSource, frag_file)
    gfuzz_common.write_to_file(image_job.uniformsInfo, json_file)

    res = tt.ImageJobResult()

    # Set nice defaults to fields we will not update anyway
    res.passSanityCheck = True
    res.log = 'Start: ' + name + '\n'

    with gfuzz_common.open_helper(log_file, 'w') as f:
        try:
            gfuzz_common.set_logfile(f)
            run_image_job(json_file, status_file, png_file, output_dir,
                          image_job.skipRender)
        except Exception as ex:
            gfuzz_common.log(str(ex))
            gfuzz_common.log('Removing status file and continuing...')
            gfuzz_common.remove(status_file)
        finally:
            gfuzz_common.unset_logfile()

    if os.path.isfile(log_file):
        with gfuzz_common.open_helper(log_file, 'r') as f:
            res.log += f.read()

    if os.path.isfile(png_file):
        with gfuzz_common.open_bin_helper(png_file, 'rb') as f:
            res.PNG = f.read()

    if os.path.isfile(status_file):
        with gfuzz_common.open_helper(status_file, 'r') as f:
            status = f.read().rstrip()
        if status == STATUS_SUCCESS:
            res.status = tt.JobStatus.SUCCESS
        elif status == STATUS_CRASH:
            res.status = tt.JobStatus.CRASH
        elif status == STATUS_TIMEOUT:
            res.status = tt.JobStatus.TIMEOUT
        elif status == STATUS_UNEXPECTED:
            res.status = tt.JobStatus.UNEXPECTED_ERROR
        elif status == STATUS_NONDET:
            res.status = tt.JobStatus.NONDET
            with gfuzz_common.open_bin_helper(nondet_0, 'rb') as f:
                res.PNG = f.read()
            with gfuzz_common.open_bin_helper(nondet_1, 'rb') as f:
                res.PNG2 = f.read()
        else:
            res.log += '\nUnknown status value: ' + status + '\n'
            res.status = tt.JobStatus.UNEXPECTED_ERROR
    else:
        # Not even a status file?
        res.log += '\nNo STATUS file\n'
        res.status = tt.JobStatus.UNEXPECTED_ERROR

    return res
コード例 #5
0
def do_compute_job(
    args,
    comp_job: tt.ImageJob,
    spirv_opt_args: Optional[List[str]],
    work_dir: str
) -> tt.ImageJobResult:

    # Output directory is based on the name of job.
    output_dir = os.path.join(work_dir, comp_job.name)

    # Delete and create output directory.
    gfuzz_common.remove(output_dir)
    os.makedirs(output_dir, exist_ok=True)

    tmpcomp = os.path.join(output_dir, 'tmp.comp')
    tmpjson = os.path.join(output_dir, 'tmp.json')
    log_file = os.path.join(output_dir, runspv.LOGFILE_NAME)
    ssbo_json_file = os.path.join(output_dir, 'ssbo.json')

    # Output files from running the app.
    status_file = os.path.join(output_dir, 'STATUS')

    gfuzz_common.write_to_file(comp_job.computeSource, tmpcomp)

    gfuzz_common.write_to_file(comp_job.computeInfo, tmpjson)

    res = tt.ImageJobResult()
    res.log = '#### Start compute shader\n\n'

    assert not args.legacy_worker

    # Set runspv logger. Use try-finally to clean up.

    with gfuzz_common.open_helper(log_file, 'w') as f:
        try:
            runspv.log_to_file = f

            runspv.run_compute_amber(
                comp_original=tmpcomp,
                json_file=tmpjson,
                output_dir=output_dir,
                force=args.force,
                is_android=(args.target == 'android'),
                skip_render=comp_job.skipRender,
                spirv_opt_args=spirv_opt_args
            )
        except Exception as ex:
            runspv.log('Exception: ' + str(ex))
            runspv.log('Removing STATUS file.')
            gfuzz_common.remove(status_file)
            runspv.log('Continuing.')
        finally:
            runspv.log_to_file = None

    if os.path.isfile(log_file):
        with gfuzz_common.open_helper(log_file, 'r') as f:
            res.log += f.read()

    if os.path.isfile(status_file):
        with gfuzz_common.open_helper(status_file, 'r') as f:
            status = f.read().rstrip()
        if status == 'SUCCESS':
            res.status = tt.JobStatus.SUCCESS
            assert (os.path.isfile(ssbo_json_file))
            with gfuzz_common.open_helper(ssbo_json_file, 'r') as f:
                res.computeOutputs = f.read()

        elif status == 'CRASH':
            res.status = tt.JobStatus.CRASH
        elif status == 'TIMEOUT':
            res.status = tt.JobStatus.TIMEOUT
        else:
            res.log += '\nUnknown status value: ' + status + '\n'
            res.status = tt.JobStatus.UNEXPECTED_ERROR
    else:
        # Not even a status file?
        res.log += '\nNo STATUS file\n'
        res.status = tt.JobStatus.UNEXPECTED_ERROR

    return res
コード例 #6
0
def do_image_job(
    args,
    image_job,
    spirv_opt_args: Optional[List[str]],
    work_dir: str
) -> tt.ImageJobResult:

    # Output directory is based on the name of job.
    output_dir = os.path.join(work_dir, image_job.name)

    # Delete and create output directory.
    gfuzz_common.remove(output_dir)
    os.makedirs(output_dir, exist_ok=True)

    name = image_job.name
    if name.endswith('.frag'):
        name = gfuzz_common.remove_end(name, '.frag')
    # TODO(324): the worker currently assumes that no vertex shader is present in the image job.

    vert_file = prepare_vert_file(output_dir) if args.legacy_worker else None
    frag_file = os.path.join(output_dir, name + '.frag')
    json_file = os.path.join(output_dir, name + '.json')
    png_file = os.path.join(output_dir, 'image_0.png')
    log_file = os.path.join(output_dir, runspv.LOGFILE_NAME)
    status_file = os.path.join(output_dir, 'STATUS')
    nondet_0 = os.path.join(output_dir, 'nondet0.png')
    nondet_1 = os.path.join(output_dir, 'nondet1.png')

    res = tt.ImageJobResult()

    skip_render = image_job.skipRender

    # Set nice defaults to fields we will not update anyway
    res.passSanityCheck = True
    res.log = 'Start: ' + name + '\n'

    gfuzz_common.write_to_file(image_job.fragmentSource, frag_file)
    gfuzz_common.write_to_file(image_job.uniformsInfo, json_file)

    # Set runspv logger. Use try-finally to clean up.

    with gfuzz_common.open_helper(log_file, 'w') as f:
        try:
            runspv.log_to_file = f

            resolved_spirvopt_args = resolve_spirvopt_args(spirv_opt_args)

            if args.legacy_worker:
                if args.target == 'host':
                    runspv.run_image_host_legacy(
                        vert_original=vert_file,
                        frag_original=frag_file,
                        json_file=json_file,
                        output_dir=output_dir,
                        skip_render=skip_render,
                        spirv_opt_args=resolved_spirvopt_args,
                    )
                else:
                    assert args.target == 'android'
                    runspv.run_image_android_legacy(
                        vert_original=vert_file,
                        frag_original=frag_file,
                        json_file=json_file,
                        output_dir=output_dir,
                        force=args.force,
                        skip_render=skip_render,
                        spirv_opt_args=resolved_spirvopt_args,
                    )
            else:
                runspv.run_image_amber(
                    vert_original=vert_file,
                    frag_original=frag_file,
                    json_file=json_file,
                    output_dir=output_dir,
                    force=args.force,
                    is_android=(args.target == 'android'),
                    skip_render=skip_render,
                    spirv_opt_args=resolved_spirvopt_args
                )
        except Exception as ex:
            runspv.log('Exception: ' + str(ex))
            runspv.log('Removing STATUS file.')
            gfuzz_common.remove(status_file)
            runspv.log('Continuing.')
        finally:
            runspv.log_to_file = None

    if os.path.isfile(log_file):
        with gfuzz_common.open_helper(log_file, 'r') as f:
            res.log += f.read()

    if os.path.isfile(png_file):
        with gfuzz_common.open_bin_helper(png_file, 'rb') as f:
            res.PNG = f.read()

    if os.path.isfile(status_file):
        with gfuzz_common.open_helper(status_file, 'r') as f:
            status = f.read().rstrip()
        if status == 'SUCCESS':
            res.status = tt.JobStatus.SUCCESS
        elif status == 'CRASH':
            res.status = tt.JobStatus.CRASH
        elif status == 'TIMEOUT':
            res.status = tt.JobStatus.TIMEOUT
        elif status == 'SANITY_ERROR':
            res.status = tt.JobStatus.SANITY_ERROR
        elif status == 'UNEXPECTED_ERROR':
            res.status = tt.JobStatus.UNEXPECTED_ERROR
        elif status == 'NONDET':
            res.status = tt.JobStatus.NONDET
            with gfuzz_common.open_bin_helper(nondet_0, 'rb') as f:
                res.PNG = f.read()
            with gfuzz_common.open_bin_helper(nondet_1, 'rb') as f:
                res.PNG2 = f.read()
        else:
            res.log += '\nUnknown status value: ' + status + '\n'
            res.status = tt.JobStatus.UNEXPECTED_ERROR
    else:
        # Not even a status file?
        res.log += '\nNo STATUS file\n'
        res.status = tt.JobStatus.UNEXPECTED_ERROR

    return res
コード例 #7
0
def doImageJob(imageJob):
    name = imageJob.name.replace('.frag', '')
    fragFile = name + '.frag'
    jsonFile = name + '.json'
    png = name + '.png'
    log = name + '.log'
    qpa = name + '.qpa'
    vk = name + '.vk'

    writeToFile(imageJob.fragmentSource, fragFile)
    writeToFile(imageJob.uniformsInfo, jsonFile)

    if os.path.isfile(png):
        os.remove(png)

    # FIXME: translate runVk.sh as a python function in this file
    # cmd = '../runVk.sh ' + fragFile

    # runVkCompleted = False

    for i in range(2):
        getimage = getImageVulkanAndroid(fragFile)

        if (getimage):
            break
        else:

            print('get image failed, restart dEQP')
            # Hugues: do not use the "-W" (wait) adb flag here, it hangs
            adb('shell am force-stop com.drawelements.deqp')
            time.sleep(0.5)
            adb('shell am start -n com.drawelements.deqp/.execserver.ServiceStarter'
                )
            print('Sleep and retry...')
            time.sleep(0.5)

    res = tt.ImageJobResult()

    # Set nice defaults to fields we will not update anyway
    res.passSanityCheck = True

    if not (os.path.isfile(qpa)):
        # if no QPA, something went really wrong
        res.status = tt.JobStatus.UNEXPECTED_ERROR
        res.log = 'Not even a QPA file found?'

    else:
        # Store QPA as log
        with open(qpa, 'r') as f:
            res.log = f.read()

        # Vulkan calls trace
        if os.path.isfile(vk):
            res.log += '\n#### VK CALLS TRACE START\n'
            with open(vk) as f:
                res.log += f.read()
            res.log += '#### VK CALLS TRACE END\n'

        # Set status
        if os.path.isfile(png):
            res.status = tt.JobStatus.SUCCESS
            with open(png, 'rb') as f:
                res.PNG = f.read()

        elif fileContains(qpa, '#endTestCaseResult'):
            res.status = tt.JobStatus.COMPILE_ERROR

        else:
            res.status = tt.JobStatus.CRASH

            # adb log
            adb('logcat -b crash -b system -d > logcat.txt')
            res.log += '\n#### ADB LOGCAT START\n'
            with open('logcat.txt', 'r') as f:
                res.log += f.read()
            res.log += '\n#### ADB LOGCAT END\n'

    return res
コード例 #8
0
def doImageJob(args, imageJob):
    name = imageJob.name.replace('.frag', '')
    fragFile = name + '.frag'
    jsonFile = name + '.json'
    png = 'image.png'
    log = 'vklog.txt'

    res = tt.ImageJobResult()

    skipRender = imageJob.skipRender

    # Set nice defaults to fields we will not update anyway
    res.passSanityCheck = True
    res.log = 'Start: ' + name + '\n'

    writeToFile(imageJob.fragmentSource, fragFile)
    writeToFile(imageJob.uniformsInfo, jsonFile)
    prepareShaders(fragFile)
    shutil.copy(jsonFile, 'test.json')

    # Optimize
    if args.spirvopt:
        cmd = os.path.dirname(HERE) + '/../../bin/' + getBinType(
        ) + '/spirv-opt ' + args.spirvopt + ' test.frag.spv -o test.frag.spv.opt'
        try:
            res.log += 'spirv-opt flags: ' + args.spirvopt + '\n'
            print('Calling spirv-opt with flags: ' + args.spirvopt)
            subprocess.run(cmd,
                           shell=True,
                           stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE,
                           universal_newlines=True,
                           check=True,
                           timeout=TIMEOUT_SPIRVOPT)
        except subprocess.CalledProcessError as err:
            # spirv-opt failed, early return
            res.log += 'Error triggered by spirv-opt\n'
            res.log += 'COMMAND:\n' + err.cmd + '\n'
            res.log += 'RETURNCODE: ' + str(err.returncode) + '\n'
            if err.stdout:
                res.log += 'STDOUT:\n' + err.stdout + '\n'
            if err.stderr:
                res.log += 'STDERR:\n' + err.stderr + '\n'
            res.status = tt.JobStatus.UNEXPECTED_ERROR
            return res
        except subprocess.TimeoutExpired as err:
            # spirv-opt timed out, early return
            res.log += 'Timeout from spirv-opt\n'
            res.log += 'COMMAND:\n' + err.cmd + '\n'
            res.log += 'TIMEOUT: ' + str(err.timeout) + ' sec\n'
            if err.stdout:
                res.log += 'STDOUT:\n' + err.stdout + '\n'
            if err.stderr:
                res.log += 'STDERR:\n' + err.stderr + '\n'
            res.status = tt.JobStatus.UNEXPECTED_ERROR
            return res

        shutil.move('test.frag.spv.opt', 'test.frag.spv')

    remove(png)
    remove(log)

    if args.linux:
        vkrun.run_linux('test.vert.spv', 'test.frag.spv', 'test.json',
                        skipRender)
    else:
        vkrun.run_android('test.vert.spv', 'test.frag.spv', 'test.json',
                          skipRender)

    if os.path.exists(log):
        with open(log, 'r') as f:
            res.log += f.read()

    if os.path.exists(png):
        with open(png, 'rb') as f:
            res.PNG = f.read()

    if os.path.exists('STATUS'):
        with open('STATUS', 'r') as f:
            status = f.read().rstrip()
        if status == 'SUCCESS':
            res.status = tt.JobStatus.SUCCESS
        elif status == 'CRASH':
            res.status = tt.JobStatus.CRASH
        elif status == 'TIMEOUT':
            res.status = tt.JobStatus.TIMEOUT
        else:
            res.log += '\nUnknown status value: ' + status + '\n'
            res.status = tt.JobStatus.UNEXPECTED_ERROR
    else:
        # Not even a status file?
        res.log += '\nNo STATUS file\n'
        res.status = tt.JobStatus.UNEXPECTED_ERROR

    return res