跳转至

I. 刀锐奶化

分数:200分

为了达到更好的成像效果,往往需要设计特殊形状的镜片。随着几何像差逐渐减小,传感器分辨率逐渐提升,镜头的设计不得不考虑衍射效应对聚焦光斑的影响。这里,我们将计算一个最简单的例子,点光源的单反射镜成像。

任务

我们会给出点光源坐标 s ,反射镜上的采样点 \mu ,以及传感器像素点坐标 dv

你只需要计算 Iv=abs(\sum_u exp(2\pi i\frac{|dv-\mu|+|\mu-s|}{\lambda}))

其中波长固定为 \lambda=500 nm

注意

  • 本题结果允许一定误差,如果你输出的图像为 img ,参考结果为 ref ,使用 sqrt(((img-ref)**2).sum()/(ref**2).sum()) 衡量误差

输入

一个二进制文件 in.data ,文件内容为

  • 3 个 64 位浮点,表示点光源坐标
  • 一个 64 位整数,表示反射镜上采样点的个数 mirn
  • 3 * mirn 个 64 位浮点,表示反射镜上采样点的坐标 \mu
  • 一个 64 位整数,表示传感器像素个数 senn
  • 3 * senn 个 64 位浮点,表示传感器上像素点的坐标 dv

全部坐标单位均为毫米 (mm)

其中

  • 存在整数 n 使得 senn=n^2
  • 存在 d_o,d_a,d_b 使得对任意整数 0<=i,j<=n-1d_{j*n+i}=d_o+j*d_a+i*d_a
  • 反射镜不一定光滑

输出

一个二进制文件 out.data ,文件内容为

  • senn 个 64 位浮点,Iv

样例程序

#include <math.h>
#include <stdio.h>
#include <malloc.h>
#include <stdint.h>

typedef double d_t;

struct d3_t {
    d_t x, y, z;
};

d_t norm(d3_t x) {
    return sqrt(x.x * x.x + x.y * x.y + x.z * x.z);
}

d3_t operator-(d3_t a, d3_t b) {
    return {a.x-b.x,a.y-b.y,a.z-b.z};
}

int main(){
    FILE* fi;
    fi = fopen("in.data", "rb");
    d3_t src;
    int64_t mirn,senn;
    d3_t* mir, * sen;
    fread(&src, 1, sizeof(d3_t), fi);

    fread(&mirn, 1, sizeof(int64_t), fi);
    mir = (d3_t*)malloc(mirn * sizeof(d3_t));
    fread(mir, 1, mirn * sizeof(d3_t), fi);
    fread(&senn, 1, sizeof(int64_t), fi);
    sen = (d3_t*)malloc(senn * sizeof(d3_t));
    fread(sen, 1, senn * sizeof(d3_t), fi);
    fclose(fi);

    d_t* data = (d_t*)malloc(senn * sizeof(d_t));
    for (int64_t i = 0; i < senn; i++) {
        d_t a=0;
        d_t b=0;
        for (int64_t j = 0; j < mirn; j++) {
            d_t l = norm(mir[j] - src) + norm(mir[j] - sen[i]);
            a += cos(6.283185307179586 * 2000 * l);
            b += sin(6.283185307179586 * 2000 * l);
        }
        data[i] = sqrt(a * a + b * b);
    }

    fi = fopen("out.data", "wb");
    fwrite(data, 1, senn * sizeof(d_t), fi);
    fclose(fi);
    return 0;
}

评测环境

容器镜像:cuda,已安装 CUDA 12.6 和 cublas。保证 nvccPATH 中。

评测的 GPU 为经过 MIG 的 2/7 张 A100,具有 20 GB 显存。

附件

本题提供一组和正式测试仅仅是镜面形状略有不同的输入文件。

评分标准

提交一个 impl.cu,包括 main 函数,读取 in.data,计算 Iv,并将结果写入 out.data

程序使用 nvcc -O2 -gencode arch=compute_80,code=sm_80 编译。

共 1 个测试点,每个测试点得到正确结果获得基本分数,性能分数与运行时间倒数成正比。

final_score = correct ? base_score + perf_score * min(goal / time, 1) : 0

mirn senn base score perf score limit goal pixel size F number image distance object distance
1 1048576 1048576 0 200 2 min 10 s 0.73 μm 5.6 200 mm 400 mm

本题允许约 0.01% 的误差,提交结果会返回实际误差与允许误差之比。

趣味小知识

  • 几个月前斥巨资购买的镜头焦外光斑有奇怪的纹路,为了研究这种现象诞生了本题。
  • 附件是一个很有趣的样例,镜子的形状经过精心设计,改变光的波长会显著影响聚焦效果。普通的凹面镜则不会这样。
  • 附件的镜子整体的形状是凸的,但的确能正常汇聚光线,怎么秽蚀呢?

提示

  • 只要输出误差不超过允许值,就可以降低计算精度换取计算速度。