资讯
首页  >  专题  >  环球科学  >  环球科学<前沿资讯>

为了重跑十几年前的代码,他不得不给Mac电脑装了DOS和Win 3.11

图片来源:unsplash.com

尽管计算(computing)在科学领域越来越重要,研究论文却很少提供作者的基础代码。即便提供了,同行们也很难顺利运行,一些人甚至在发了论文以后发现想重复自己曾经用过的代码都会遇到问题。毕竟,计算机运行环境发展迅速,编程语言也在不断更新,如何让多年前的古董代码重新顺利运行成了令许多程序员及科研人员头疼的难题。

十年可重复性挑战

为了攻克这个难关,法国国家信息与自动化研究所(French National Institute for Research in Digital Science and Technology,INRIA)的计算神经科学家兼程序员Nicolas Rougier和法国国家科学研究中心(French National Centre for Scientific Research,CNRS)的理论生物物理学家Konrad Hinsen在2019年共同构想了一个解决方案:“十年可重复性挑战”(Ten years reproducibility challenge)项目。这个挑战项目鼓励科学家们重现至少十年前他们发表的文章中的代码。参与者还需在2021年6月举行的研讨会上讨论他们的收获。成功的案例会刊登在ReScienceC杂志上。ReScienceC是Rougier和Hinsen在2015年创办的杂志,用来记录研究人员重复已发表论文的代码的情况,以此统计研究的可重复性。

Hinsen表示,这项挑战旨在“寻找有效的编写和发表代码的技巧,让代码十年后还能运行”。项目的启动恰巧与著名的Python 2退出历史舞台在同一天——2020年1月1日。Python 2曾是科学界流行的高级编程语言,被系统支持使用超过20年。(Python 3于2008年发行,现在还在发展中,但这两个版本的差异很大,用一个版本写的代码可能无法在另一个版本中正常运行。)毕竟,“十年在软件世界中是一段很长很长的时间”,伊利诺伊大学厄巴纳-香槟分校研究计算重复性的Victoria Stodden 表示,这项挑战通过设立10年的标准,有效激发了研究人员去突破代码可重复性的时间局限。

尽管项目任重道远,还是有35个人接受了这项挑战。他们共提出了43篇等待检测重复性的论文,其中28篇产生了重复性报告。ReScienceC杂志今年开始发表他们的工作。参与者使用了包括C、R、Mathematica以及Pascal在内的多种编程语言,还有一位参与者甚至重新运行了用 SBML(Systems Biology Markup Language)编码的分子模型。

挑战重重

挑战的发起人Rougier 也参与到了项目中,他重复运行了这项挑战中最古老的代码:自己1岁时在苹果电脑上写的用于图片放大的程序。这个代码当时被刊登在了已不复存在的法国Tremplin Micro杂志上。32年后,Rougier已经不记得代码和它晦涩的 AppleSoft BASIC指令是如何运行的了。不过他还是在网上找到了当年的代码并在网页版的苹果II模拟器上跑了一遍。

然而,难点在于让它在真正的苹果II电脑上顺利运行。硬件不是问题,Rougier 办公室有一台苹果II电脑。但由于苹果II电脑诞生的年代还没有USB数据线和互联网,现代电脑又无法连接老式磁盘驱动器,Rougier不得不用定制硬件(custom hardware)和老式软盘(vintage floppies)来帮助电脑加载代码。如同考古挖掘一样,虽然过程曲折,但Rougier还是让 30 多年前的代码得以重见天日。

然而,另一位发起人Hinsen就没那么幸运了。在上个世纪90年代,Hinsen习惯于把自己的代码储存在磁带上。然而现在,虽然磁带还在,它的阅读器却已经绝版了,Hinsen的代码只能被封在磁带中了。

跟不上时代的运行环境

除了硬件,过时的电脑运行环境也给参与者带来了不少困扰。意大利的计算物理学家Sabino Maggi在1996年曾用Fortran语言来为一个被称为约瑟夫结的超导装置建模,并用微软的Visual Basic语言处理结果。Fortran语言这么多年倒是没什么变化,可Visual Basic已经绝版了,无法在现有的Windows 系统上运行(现在替代它的是Visual Basic.NET,二者只有名字看起来还有点联系)。为了运行代码,他不得不在Mac电脑上安装了十多年前Windows 系统的模拟机,再在模拟机上安装1994年左右发行的微软DOS 6.22和Windows 3.11,以及他在网上找的Visual Basic安装盘。

二十世纪九十年代初期的Win3.11操作系统界面

Maggi承认在模拟机上安装这些在使用、修改上有限制的专有软件存在合法性问题。不过他最早在进行研究时曾有这些工具的有效使用许可证,这使他觉得自己“至少从道义上”有权使用软件。

然而,问题还没有解决。Maggi 不知道自己该使用哪个版本的Visual Basic语言。微软发行的多个版本的语言往往与前一个版本不兼容。Maggi已经记不清自己1996年用的是哪个版本的编程语言了。更糟糕的是,他当年记录这些细节的笔记本也由于一次地下室漏水被销毁了。因此,Maggi不得不耗费巨大的精力重写当年的代码。

图片来源:Sabino Maggi | Nature

无独有偶,INRIA的研发工程师Ludovic Courtès在重新运行2006年用C语言写的对比不同数据安装策略的代码时遇到了麻烦。受程序员青睐的应用程序编程接口(Application Programming Interface,API)可以将两个不同的软件对接,方便程序员调用其它软件的功能、打通软件间的数据;而操作系统等运行环境的改变会导致API的变动。API的变动使他的代码无法用当前的软件库压缩。他只好将多个电脑组件改回到旧版本。Courtès表示电脑系统的发展如同《爱丽丝漫游奇境记》中的兔子洞,里面会发生什么都是未知的。

解决策略

现在,为应对变化未知的运行环境,研究人员可以用Docker容器和Conda虚拟环境来对电脑运算环境进行打包备用。Conda是一个开源通用包管理系统兼环境管理系统,可以安装多版本的软件包及其依赖软件,并在它们之间轻松切换。不过,有好几位参与者都选择了另一个办法:Linux通用包管理系统Guix。Guix的好处在于,它具备了科研论文可重复性的黄金准则:环境的全面可重复性,以及透明的代码版本。

此外,为了提高长期可重复性,为代码存档尤为重要。INRIA的计算机科学家Roberto DiCosmo曾试图在自己和合作者的多个备份硬盘里寻找1998年平行编程系统OcamlP3l的代码,却怎么也找不到。毫无办法的他只好在他2015年建立的Software Heritage网站上进行搜索。考虑到Software Heritage在他开发OcamlP3l时还不存在,DiCosmo 并没有抱太大的希望。然而神奇的是,他居然搜到了 OcamlP3l 的源代码!原来,Software Heritage 通过定期抓取 GitHub 等代码共享站点的信息,收集存放了大量计算机程序的源代码。就像因特网为网页存档那样,Software Heritage 为软件源代码进行存档。

虽然不少参与者发现,当年能顺利运行的代码现在频频报错;但也有轻松化解问题的大佬。CNRS 的生物物理化学家 Charles Robert 就是其中一位。1995 年,他曾在笔记本软件上运行 Mathematica 来为真核生物染色体的 3D 结构建模。当年在运行时,Robert 的代码出现了结构缺陷以及代码片段顺序混乱等来自笔记本软件的问题。如今,再次面对当年的代码,他通过将代码分解成模块进行测试避开了这些问题。他还利用版本控制(是指对软件开发过程中各种程序代码、配置文件及说明文档等文件变更的管理,是软件配置管理的核心思想之一)的方法来追踪代码的变更,记录每个版本的软件运行的结果。

DiCosmo和Robert的例子或许可以给致力于提高代码长期可重复性的研究者们一些启示。虽然难以保证多年前的古董代码一定能再次运行,但还是可以在平时编写代码时采取有效的策略来增加成功的可能性。具体策略如下:

编码(Code):将计算和数据处理包含在代码中。不要使用基于Excel等点击界面的流程图。

存档(Document):利用记事本等软件详细解释代码运行过程,定义预期的参数和需要的运算环境。

记录(Record):记录重要参数,例如递归程序开始时使用的种子值(seed value)。

测试(Test):创建一套测试功能。利用阳性阴性对照数据集来确保你得到想要的结果。边开发代码边进行测试,及时处理bug。

建立指南(Guide):创建一个主脚本(如“run.sh”文件)用来下载所需的数据集和变量,执行工作流程并提供明显的代码入口点(entry point to code)。

建档案(Archive):GitHub是流行的非永久性代码线上存放处。Zenodo,Figshare和Software Heritage可以长期稳定存放代码。

追踪(Track):利用Git等版本控制工具记录你的项目历程。标注每个结果对应的版本。

打包(Package):利用容器工具(Docker,Singularity)、网页服务器(Code Ocean, Gigantum, Binder)或虚拟环境管理器(Conda)创建随时可用的运行环境。

自动化(Automate):利用持续集成服务(Travis CI等)将项目进行持续性自动化测试以控制代码质量。

简化(Simplify):避免使用难安装的第三方代码库。

核对(Verify):检查代码在不同运行环境的可移植性。

无论选择哪种方法,“十年可重复性挑战”的参与者们想实现代码的重新运行仍有较大的难度。不过,他们将会为论文代码长期可重复性的提高带来许多启示。正如英国曼彻斯特大学计算机科学家Carole Goble所说,可重复性有一定范围,“软件是个不断更新的活物,它终将凋亡;人们需要修复它或者替换掉它”。

作者:Jeffrey M. Perkel

翻译:王千玥

编辑:魏潇

引进来源:Nature

本文来自:中国数字科技馆
特别声明:本文转载仅仅是出于科普传播信息的需要,并不意味着代表本网站观点或证实其内容的真实性;如其他媒体、网站或个人从本网站转载使用,须保留本网站注明的“来源”,并自负版权等法律责任;作者如果不希望被转载或其它相关事宜,请与我们接洽。
[责任编辑:环球科学]
分享到:
文章排行榜
©2011-2021 版权所有:中国数字科技馆
未经书面许可任何人不得复制或镜像
京ICP备11000850号-1 京公网安备11010502039775号
信息网络传播视听节目许可证0111611号
国家科技基础条件平台
./t20210314_1044178_taonews.html