nvGRAPH API参考分析(二)

nvGRAPH Code Examples

本文提供了简单的示例。

1. nvGRAPH convert topology example

void check(nvgraphStatus_t status) {

if (status != NVGRAPH_STATUS_SUCCESS) {

printf("ERROR : %d\n",status);

exit(0);

}

}

int main(int argc, char **argv) {

size_t  n = 6, nnz = 10;

// nvgraph variables

nvgraphHandle_t handle;

nvgraphCSCTopology32I_t CSC_input;

nvgraphCSRTopology32I_t CSR_output;

float *src_weights_d, *dst_weights_d;

cudaDataType_t edge_dimT = CUDA_R_32F;

// Allocate source data

CSC_input = (nvgraphCSCTopology32I_t) malloc(sizeof(struct nvgraphCSCTopology32I_st));

CSC_input->nvertices = n; CSC_input->nedges = nnz;

cudaMalloc( (void**)&(CSC_input->destination_offsets), (n+1)*sizeof(int));

cudaMalloc( (void**)&(CSC_input->source_indices), nnz*sizeof(int));

cudaMalloc( (void**)&src_weights_d, nnz*sizeof(float));

// Copy source data

float src_weights_h[] = {0.333333f, 0.5f, 0.333333f, 0.5f, 0.5f, 1.0f, 0.333333f, 0.5f, 0.5f, 0.5f};

int destination_offsets_h[] = {0, 1, 3, 4, 6, 8, 10};

int source_indices_h[] = {2, 0, 2, 0, 4, 5, 2, 3, 3, 4};

cudaMemcpy(CSC_input->destination_offsets, destination_offsets_h, (n+1)*sizeof(int), cudaMemcpyDefault);

cudaMemcpy(CSC_input->source_indices, source_indices_h, nnz*sizeof(int), cudaMemcpyDefault);

cudaMemcpy(src_weights_d, src_weights_h, nnz*sizeof(float), cudaMemcpyDefault);

// Allocate destination data

CSR_output = (nvgraphCSRTopology32I_t) malloc(sizeof(struct nvgraphCSRTopology32I_st));

cudaMalloc( (void**)&(CSR_output->source_offsets), (n+1)*sizeof(int));

cudaMalloc( (void**)&(CSR_output->destination_indices), nnz*sizeof(int));

cudaMalloc( (void**)&dst_weights_d, nnz*sizeof(float));

// Starting nvgraph and convert

check(nvgraphCreate (&handle));

check(nvgraphConvertTopology(handle, NVGRAPH_CSC_32, CSC_input, src_weights_d,

&edge_dimT, NVGRAPH_CSR_32, CSR_output, dst_weights_d));

// Free memory

check(nvgraphDestroy(handle));

cudaFree(CSC_input->destination_offsets);

cudaFree(CSC_input->source_indices);

cudaFree(CSR_output->source_offsets);

cudaFree(CSR_output->destination_indices);

cudaFree(src_weights_d);

cudaFree(dst_weights_d);

free(CSC_input);

free(CSR_output);

return 0;

}

2. nvGRAPH convert graph example

void check(nvgraphStatus_t status) {

if (status != NVGRAPH_STATUS_SUCCESS) {

printf("ERROR : %d\n",status);

exit(0);

}

}

int main(int argc, char **argv) {

size_t  n = 6, nnz = 10, vert_sets = 2, edge_sets = 1;

// nvgraph variables

nvgraphHandle_t handle; nvgraphGraphDescr_t src_csc_graph;

nvgraphCSCTopology32I_t CSC_input;

cudaDataType_t edge_dimT = CUDA_R_32F;

cudaDataType_t* vertex_dimT;

// Allocate host data

float *pr_1 = (float*)malloc(n*sizeof(float));

void **vertex_dim = (void**)malloc(vert_sets*sizeof(void*));

vertex_dimT = (cudaDataType_t*)malloc(vert_sets*sizeof(cudaDataType_t));

CSC_input = (nvgraphCSCTopology32I_t) malloc(sizeof(struct nvgraphCSCTopology32I_st));

// Initialize host data

float weights_h[] = {0.333333f, 0.5f, 0.333333f, 0.5f, 0.5f, 1.0f, 0.333333f, 0.5f, 0.5f, 0.5f};

int destination_offsets_h[] = {0, 1, 3, 4, 6, 8, 10};

int source_indices_h[] = {2, 0, 2, 0, 4, 5, 2, 3, 3, 4};

float bookmark_h[] = {0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f};

vertex_dim[0] = (void*)bookmark_h; vertex_dim[1]= (void*)pr_1;

vertex_dimT[0] = CUDA_R_32F; vertex_dimT[1]= CUDA_R_32F, vertex_dimT[2]= CUDA_R_32F;

// Starting nvgraph

check(nvgraphCreate (&handle));

check(nvgraphCreateGraphDescr (handle, &src_csc_graph));

CSC_input->nvertices = n; CSC_input->nedges = nnz;

CSC_input->destination_offsets = destination_offsets_h;

CSC_input->source_indices = source_indices_h;

// Set graph connectivity and properties (tranfers)

check(nvgraphSetGraphStructure(handle, src_csc_graph, (void*)CSC_input, NVGRAPH_CSC_32));

check(nvgraphAllocateVertexData(handle, src_csc_graph, vert_sets, vertex_dimT));

check(nvgraphAllocateEdgeData  (handle, src_csc_graph, edge_sets, &edge_dimT));

for (int i = 0; i < 2; ++i)

check(nvgraphSetVertexData(handle, src_csc_graph, vertex_dim[i], i));

check(nvgraphSetEdgeData(handle, src_csc_graph, (void*)weights_h, 0));

// Convert to CSR graph

nvgraphGraphDescr_t dst_csr_graph;

check(nvgraphCreateGraphDescr (handle, &dst_csr_graph));

check(nvgraphConvertGraph(handle, src_csc_graph, dst_csr_graph, NVGRAPH_CSR_32));

check(nvgraphDestroyGraphDescr(handle, src_csc_graph));

check(nvgraphDestroyGraphDescr(handle, dst_csr_graph));

check(nvgraphDestroy(handle));

free(pr_1); free(vertex_dim); free(vertex_dimT);

free(CSC_input);

return 0;

}

3. nvGRAPH pagerank example

void check(nvgraphStatus_t status) {

if (status != NVGRAPH_STATUS_SUCCESS) {

printf("ERROR : %d\n",status);

exit(0);

}

}

int main(int argc, char **argv) {

size_t  n = 6, nnz = 10, vert_sets = 2, edge_sets = 1;

float alpha1 = 0.9f; void *alpha1_p = (void *) &alpha1;

// nvgraph variables

nvgraphHandle_t handle; nvgraphGraphDescr_t graph;

nvgraphCSCTopology32I_t CSC_input;

cudaDataType_t edge_dimT = CUDA_R_32F;

cudaDataType_t* vertex_dimT;

// Allocate host data

float *pr_1 = (float*)malloc(n*sizeof(float));

void **vertex_dim = (void**)malloc(vert_sets*sizeof(void*));

vertex_dimT = (cudaDataType_t*)malloc(vert_sets*sizeof(cudaDataType_t));

CSC_input = (nvgraphCSCTopology32I_t) malloc(sizeof(struct nvgraphCSCTopology32I_st));

// Initialize host data

float weights_h[] = {0.333333f, 0.5f, 0.333333f, 0.5f, 0.5f, 1.0f, 0.333333f, 0.5f, 0.5f, 0.5f};

int destination_offsets_h[] = {0, 1, 3, 4, 6, 8, 10};

int source_indices_h[] = {2, 0, 2, 0, 4, 5, 2, 3, 3, 4};

float bookmark_h[] = {0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f};

vertex_dim[0] = (void*)bookmark_h; vertex_dim[1]= (void*)pr_1;

vertex_dimT[0] = CUDA_R_32F; vertex_dimT[1]= CUDA_R_32F, vertex_dimT[2]= CUDA_R_32F;

// Starting nvgraph

check(nvgraphCreate (&handle));

check(nvgraphCreateGraphDescr (handle, &graph));

CSC_input->nvertices = n; CSC_input->nedges = nnz;

CSC_input->destination_offsets = destination_offsets_h;

CSC_input->source_indices = source_indices_h;

// Set graph connectivity and properties (tranfers)

check(nvgraphSetGraphStructure(handle, graph, (void*)CSC_input, NVGRAPH_CSC_32));

check(nvgraphAllocateVertexData(handle, graph, vert_sets, vertex_dimT));

check(nvgraphAllocateEdgeData  (handle, graph, edge_sets, &edge_dimT));

for (int i = 0; i < 2; ++i)

check(nvgraphSetVertexData(handle, graph, vertex_dim[i], i));

check(nvgraphSetEdgeData(handle, graph, (void*)weights_h, 0));

check(nvgraphPagerank(handle, graph, 0, alpha1_p, 0, 0, 1, 0.0f, 0));

// Get result

check(nvgraphGetVertexData(handle, graph, vertex_dim[1], 1));

check(nvgraphDestroyGraphDescr(handle, graph));

check(nvgraphDestroy(handle));

free(pr_1); free(vertex_dim); free(vertex_dimT);

free(CSC_input);

return 0;

}

4. nvGRAPH SSSP example

void check(nvgraphStatus_t status) {

if (status != NVGRAPH_STATUS_SUCCESS) {

printf("ERROR : %d\n",status);

exit(0);

}

}

int main(int argc, char **argv) {

const size_t  n = 6, nnz = 10, vertex_numsets = 1, edge_numsets = 1;

float *sssp_1_h;

void** vertex_dim;

// nvgraph variables

nvgraphStatus_t status; nvgraphHandle_t handle;

nvgraphGraphDescr_t graph;

nvgraphCSCTopology32I_t CSC_input;

cudaDataType_t edge_dimT = CUDA_R_32F;

cudaDataType_t* vertex_dimT;

// Init host data

sssp_1_h = (float*)malloc(n*sizeof(float));

vertex_dim  = (void**)malloc(vertex_numsets*sizeof(void*));

vertex_dimT = (cudaDataType_t*)malloc(vertex_numsets*sizeof(cudaDataType_t));

CSC_input = (nvgraphCSCTopology32I_t) malloc(sizeof(struct nvgraphCSCTopology32I_st));

vertex_dim[0]= (void*)sssp_1_h; vertex_dimT[0] = CUDA_R_32F;

float weights_h[] = {0.333333, 0.5, 0.333333, 0.5, 0.5, 1.0, 0.333333, 0.5, 0.5, 0.5};

int destination_offsets_h[] = {0, 1, 3, 4, 6, 8, 10};

int source_indices_h[] = {2, 0, 2, 0, 4, 5, 2, 3, 3, 4};

check(nvgraphCreate(&handle));

check(nvgraphCreateGraphDescr (handle, &graph));

CSC_input->nvertices = n; CSC_input->nedges = nnz;

CSC_input->destination_offsets = destination_offsets_h;

CSC_input->source_indices = source_indices_h;

// Set graph connectivity and properties (tranfers)

check(nvgraphSetGraphStructure(handle, graph, (void*)CSC_input, NVGRAPH_CSC_32));

check(nvgraphAllocateVertexData(handle, graph, vertex_numsets, vertex_dimT));

check(nvgraphAllocateEdgeData  (handle, graph, edge_numsets, &edge_dimT));

check(nvgraphSetEdgeData(handle, graph, (void*)weights_h, 0));

// Solve

int source_vert = 0;

check(nvgraphSssp(handle, graph, 0,  &source_vert, 0));

// Get and print result

check(nvgraphGetVertexData(handle, graph, (void*)sssp_1_h, 0));

//Clean

free(sssp_1_h); free(vertex_dim);

free(vertex_dimT); free(CSC_input);

check(nvgraphDestroyGraphDescr(handle, graph));

check(nvgraphDestroy(handle));

return 0;

}

5. nvGRAPH Semi-Ring SPMV example

void check(nvgraphStatus_t status) {

if (status != NVGRAPH_STATUS_SUCCESS) {

printf("ERROR : %d\n",status);

exit(0);

}

}

int main(int argc, char **argv) {

size_t  n = 5, nnz = 10, vertex_numsets = 2, edge_numsets = 1;

float alpha = 1.0, beta = 0.0;

void *alpha_p = (void *)&alpha, *beta_p = (void *)&beta;

void** vertex_dim;

cudaDataType_t edge_dimT = CUDA_R_32F;

cudaDataType_t* vertex_dimT;

// nvgraph variables

nvgraphStatus_t status; nvgraphHandle_t handle;

nvgraphGraphDescr_t graph;

nvgraphCSRTopology32I_t CSR_input;

// Init host data

vertex_dim  = (void**)malloc(vertex_numsets*sizeof(void*));

vertex_dimT = (cudaDataType_t*)malloc(vertex_numsets*sizeof(cudaDataType_t));

CSR_input = (nvgraphCSRTopology32I_t) malloc(sizeof(struct nvgraphCSRTopology32I_st));

float x_h[] = {1.1f, 2.2f, 3.3f, 4.4f, 5.5f};

float y_h[] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f};

vertex_dim[0]= (void*)x_h; vertex_dim[1]= (void*)y_h;

vertex_dimT[0] = CUDA_R_32F; vertex_dimT[1]= CUDA_R_32F;

float weights_h[] = {1.0f, 4.0f, 2.0f, 3.0f, 5.0f, 7.0f, 8.0f, 9.0f, 6.0f, 1.5f};

int source_offsets_h[] = {0, 2, 4, 7, 9, 10};

int destination_indices_h[] = {0, 1, 1, 2, 0, 3, 4, 2, 4, 2};

check(nvgraphCreate(&handle));

check(nvgraphCreateGraphDescr(handle, &graph));

CSR_input->nvertices = n; CSR_input->nedges = nnz;

CSR_input->source_offsets = source_offsets_h;

CSR_input->destination_indices = destination_indices_h;

// Set graph connectivity and properties (tranfers)

check(nvgraphSetGraphStructure(handle, graph, (void*)CSR_input, NVGRAPH_CSR_32));

check(nvgraphAllocateVertexData(handle, graph, vertex_numsets, vertex_dimT));

for (int i = 0; i < vertex_numsets; ++i)

check(nvgraphSetVertexData(handle, graph, vertex_dim[i], i));

check(nvgraphAllocateEdgeData  (handle, graph, edge_numsets, &edge_dimT));

check(nvgraphSetEdgeData(handle, graph, (void*)weights_h, 0));

// Solve

check(nvgraphSrSpmv(handle, graph, 0, alpha_p, 0, beta_p, 1, NVGRAPH_PLUS_TIMES_SR));

//Get result

check(nvgraphGetVertexData(handle, graph, (void*)y_h, 1));

//Clean

check(nvgraphDestroyGraphDescr(handle, graph));

check(nvgraphDestroy(handle));

free(vertex_dim); free(vertex_dimT); free(CSR_input);

return 0;

}

6. nvGRAPH Triangles Counting example

#include "stdlib.h"

#include "inttypes.h"

#include "stdio.h"

#include "nvgraph.h"

#define check( a ) \

{\

nvgraphStatus_t status = (a);\

if ( (status) != NVGRAPH_STATUS_SUCCESS) {\

printf("ERROR : %d in %s : %d\n", status, __FILE__ , __LINE__ );\

exit(0);\

}\

}

int main(int argc, char **argv)

{

// nvgraph variables

nvgraphHandle_t handle;

nvgraphGraphDescr_t graph;

nvgraphCSRTopology32I_t CSR_input;

// Init host data

CSR_input = (nvgraphCSRTopology32I_t) malloc(sizeof(struct nvgraphCSRTopology32I_st));

// Undirected graph:

// 0       2-------4

//  \     / \     / \

//   \   /   \   /   \

//    \ /     \ /     \

//     1-------3-------5

// 3 triangles

// CSR of lower triangular of adjacency matrix:

const size_t n = 6, nnz = 8;

int source_offsets[] = {0, 0, 1, 2, 4, 6, 8};

int destination_indices[] = {0, 1, 1, 2, 2, 3, 3, 4};

check(nvgraphCreate(&handle));

check(nvgraphCreateGraphDescr (handle, &graph));

CSR_input->nvertices = n;

CSR_input->nedges = nnz;

CSR_input->source_offsets = source_offsets;

CSR_input->destination_indices = destination_indices;

// Set graph connectivity

check(nvgraphSetGraphStructure(handle, graph, (void*)CSR_input, NVGRAPH_CSR_32));

uint64_t trcount = 0;

check(nvgraphTriangleCount(handle, graph, &trcount));

printf("Triangles count: %" PRIu64 "\n", trcount);

free(CSR_input);

check(nvgraphDestroyGraphDescr(handle, graph));

check(nvgraphDestroy(handle));

return 0;

}

7. nvGRAPH Traversal example

void check_status(nvgraphStatus_t status){

if ((int)status != 0)    {

printf("ERROR : %d\n",status);

exit(0);

}

}

int main(int argc, char **argv){

//Example of graph (CSR format)

const size_t  n = 7, nnz = 12, vertex_numsets = 2, edge_numset = 0;

int source_offsets_h[] = {0, 1, 3, 4, 6, 8, 10, 12};

int destination_indices_h[] = {5, 0, 2, 0, 4, 5, 2, 3, 3, 4, 1, 5};

//where to store results (distances from source) and where to store results (predecessors in search tree)

int bfs_distances_h[n], bfs_predecessors_h[n];

// nvgraph variables

nvgraphStatus_t status;

nvgraphHandle_t handle;

nvgraphGraphDescr_t graph;

nvgraphCSRTopology32I_t CSR_input;

cudaDataType_t* vertex_dimT;

size_t distances_index = 0;

size_t predecessors_index = 1;

vertex_dimT = (cudaDataType_t*)malloc(vertex_numsets*sizeof(cudaDataType_t));

vertex_dimT[distances_index] = CUDA_R_32I;

vertex_dimT[predecessors_index] = CUDA_R_32I;

//Creating nvgraph objects

check_status(nvgraphCreate (&handle));

check_status(nvgraphCreateGraphDescr (handle, &graph));

// Set graph connectivity and properties (tranfers)

CSR_input = (nvgraphCSRTopology32I_t) malloc(sizeof(struct nvgraphCSCTopology32I_st));

CSR_input->nvertices = n;

CSR_input->nedges = nnz;

CSR_input->source_offsets = source_offsets_h;

CSR_input->destination_indices = destination_indices_h;

check_status(nvgraphSetGraphStructure(handle, graph, (void*)CSR_input, NVGRAPH_CSR_32));

check_status(nvgraphAllocateVertexData(handle, graph, vertex_numsets, vertex_dimT));

int source_vert = 1;

//Setting the traversal parameters

nvgraphTraversalParameter_t traversal_param;

nvgraphTraversalParameterInit(&traversal_param);

nvgraphTraversalSetDistancesIndex(&traversal_param, distances_index);

nvgraphTraversalSetPredecessorsIndex(&traversal_param, predecessors_index);

nvgraphTraversalSetUndirectedFlag(&traversal_param, false);

//Computing traversal using BFS algorithm

check_status(nvgraphTraversal(handle, graph, NVGRAPH_TRAVERSAL_BFS, &source_vert, traversal_param));

// Get result

check_status(nvgraphGetVertexData(handle, graph, (void*)bfs_distances_h, distances_index));

check_status(nvgraphGetVertexData(handle, graph, (void*)bfs_predecessors_h, predecessors_index));

// expect bfs distances_h = (1 0 1 3 3 2 2147483647)

for (int i = 0; i<n; i++)  printf("Distance to vertex %d: %i\n",i, bfs_distances_h[i]); printf("\n");

// expect bfs predecessors = (1 -1 1 5 5 0 -1)

for (int i = 0; i<n; i++)  printf("Predecessor of vertex %d: %i\n",i, bfs_predecessors_h[i]); printf("\n");

free(vertex_dimT);

free(CSR_input);

check_status(nvgraphDestroyGraphDescr (handle, graph));

check_status(nvgraphDestroy (handle));

return 0;

}

nvGRAPH API参考分析(二)的更多相关文章

  1. nvGRAPH API参考分析(一)

    nvGRAPH API参考分析(一) 本文通过描述nvGRAPH库函数的输入/输出参数,数据类型和错误代码来指定其行为. 1.    返回值nvgraphStatus_t 除以下内容外,所有nvGRA ...

  2. PJSUA2开发文档--第十二章 PJSUA2 API 参考手册

    12 PJSUA2 API 参考手册 12.1 endpoint.hpp PJSUA2基本代理操作.  namespace pj PJSUA2 API在pj命名空间内. 12.1.1 class En ...

  3. Elasticsearch Java Rest Client API 整理总结 (二) —— SearchAPI

    目录 引言 Search APIs Search API Search Request 可选参数 使用 SearchSourceBuilder 构建查询条件 指定排序 高亮请求 聚合请求 建议请求 R ...

  4. 框架-springmvc源码分析(二)

    框架-springmvc源码分析(二) 参考: http://www.cnblogs.com/leftthen/p/5207787.html http://www.cnblogs.com/leftth ...

  5. Vue源码分析(二) : Vue实例挂载

    Vue源码分析(二) : Vue实例挂载 author: @TiffanysBear 实例挂载主要是 $mount 方法的实现,在 src/platforms/web/entry-runtime-wi ...

  6. SQLite入门与分析(二)---设计与概念(续)

    SQLite入门与分析(二)---设计与概念(续)   写在前面:本节讨论事务,事务是DBMS最核心的技术之一.在计算机科学史上,有三位科学家因在数据库领域的成就而获ACM图灵奖,而其中之一Jim G ...

  7. Linux内核启动代码分析二之开发板相关驱动程序加载分析

    Linux内核启动代码分析二之开发板相关驱动程序加载分析 1 从linux开始启动的函数start_kernel开始分析,该函数位于linux-2.6.22/init/main.c  start_ke ...

  8. 透过【百度地图API】分析双闭包问题

    原文:透过[百度地图API]分析双闭包问题 摘要: 有位API爱好者问到,昨天的教程里为什么不使用for循环?他使用for循环后,也发现代码无效.这是什么原因? ------------------- ...

  9. java微信开发API解析(二)-获取消息和回复消息

    java微信开发API解析(二)-获取消息和回复消息 说明 * 本演示样例依据微信开发文档:http://mp.weixin.qq.com/wiki/home/index.html最新版(4/3/20 ...

随机推荐

  1. DVWA之Brute Force

    DVWA简介 DVWA(Damn Vulnerable Web Application)是一个用来进行安全脆弱性鉴定的PHP/MySQL Web应用,旨在为安全专业人员测试自己的专业技能和工具提供合法 ...

  2. Linux-鸟菜-1-Linux简介

    Linux-鸟菜-1-Linux简介 鸟哥这一章是介绍了Linux的由来以及建议怎么学Linux.很多也是建议性的东西,概念性的东西(当然我不是排斥概念).把最后鸟哥的汇总粘过来吧. 建议大家去看下这 ...

  3. JAVA的安装

    1.从JAVA官网 下载 注意选择自己需要的版本 2.百度云盘 链接:https://pan.baidu.com/s/1deOFGN1xB0mgz6s2mTRXdA 提取码:ke97 安装JAVA J ...

  4. Redis(附Win10版本 和可视化工具)

    启动服务端 通过win+r,cmd 运行命令行然后输入如下指令: G: cd software cd G:\software\redis-64.3.0.503 redis-server.exe 这样就 ...

  5. Codeforces Round #694 (Div. 2)

     A. Strange Partition 题意:就是求最小和最大的bi/x向上取整的和. 思路:见题解:https://blog.csdn.net/qq_45900709/article/detai ...

  6. 个人项目作业$\cdot$求交点个数

    个人项目作业\(\cdot\)求交点个数 一.作业要求简介 本次作业是北航计算机学院软件工程课程的个人项目作业,个人开发能力对于软件开发团队是至关重要的,本项目旨在通过一个求几何图形的交点的需求来使学 ...

  7. Pytorch_Part1_简介&张量

    VisualPytorch beta发布了! 功能概述:通过可视化拖拽网络层方式搭建模型,可选择不同数据集.损失函数.优化器生成可运行pytorch代码 扩展功能:1. 模型搭建支持模块的嵌套:2. ...

  8. [bug] springboot 静态资源 layui.css 404

    目录结构 引用路径 <link rel="stylesheet" href="../static/layui/css/layui.css" type=&q ...

  9. ln -s 新目录(最后一个目录新建images) 旧目录(删除最后的images目录)

    sudo yum install libvirt virt-install qemu-kvm 默认安装会启用一个NAT模式的bridgevirbr0 启动激活libvirtd服务 systemctl ...

  10. Ubuntu 18.04安装 Adob Flash player

    1.Ctrl + Alt + T 打开命令终端,启用Canonical Partners Repository存储库 (最新的Flash插件位于Canonical Partners的存储库中,默认情况 ...