1

我正在尝试编译这个软件包: http: //sourceforge.net/projects/snap-graph/ ?source=dlp

我在这里遇到语法错误:

gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I..  -I../include   -O3 -fomit-frame-pointer -malign-double -fstrict-aliasing -ffast-math -MT drive_seed_community_detection.o -MD -MP -MF .deps/drive_seed_community_detection.Tpo -c -o drive_seed_community_detection.o drive_seed_community_detection.c
drive_seed_community_detection.c: In function ‘identify_comm’:
drive_seed_community_detection.c:214:14: error: expected expression before ‘do’
make[2]: *** [drive_seed_community_detection.o] Fehler 1
make[2]: Leaving directory `/amd.home/home/s/workspace/snap-0.4/test'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/amd.home/home/s/workspace/snap-0.4'
make: *** [all] Error 2

出现错误的相关代码部分是。特别是第 214 行:queue[atomic_fetch_and_add (&k2, 1)] = w;任何想法可能是什么问题?

  /* Find and label the connected components. */
  ncomm = 0;
  for (attr_id_t kseed = 0; kseed < num_seeds; ++kseed) {
    attr_id_t k1, k2;
    const attr_id_t seedv = seeds[kseed];
    if (membership[seedv] != -2) continue;
    queue[0] = seedv;
    membership[seedv] = seedv;
    comm_root[ncomm] = seedv;

    k1 = 0;
    k2 = 1;
    do {
      const attr_id_t qkend = k2;
      attr_id_t cv = 0;
      OMP("omp parallel for reduction(+:cv)")
      for (attr_id_t k1i = k1; k1i < qkend; ++k1i) {
        const attr_id_t v = queue[k1i];
        const attr_id_t deg = xoff[v+1] - xoff[v];
        cv += deg;
        if (deg > comm_maxdeg[ncomm]) comm_maxdeg[ncomm] = deg;
        for (attr_id_t k = xoff[v]; k < xoff[v+1]; ++k) {
          const attr_id_t w = xadj[k];
          attr_id_t memb;
          if (membership[w] < -1) {
            atomic_val_compare_and_swap (memb, &membership[w], -2, seedv);
            if (memb < -1) {
              //if (membership[w] < -1) {
              //membership[w] = seedv;
              //int loc;
              //OMP("omp atomic") loc = k2++;
              queue[atomic_fetch_and_add (&k2, 1)] = w;
            }
          }
        }
      }
      k1 = qkend;
      comm_vol[ncomm] = cv;
    } while (k1 != k2);
    comm_size[ncomm] = k2;
    ++ncomm;
  }
4

3 回答 3

2

只是根据对您问题的评论进行猜测。鉴于它的名字,它似乎

atomic_fetch_and_add(&k2, 1)

是 的原子版本k2 += 1,即保证在k2被读取的那一刻和它的值增加一被存储回的那一刻之间不会被中断的操作k2。如果此假设成立,您可以尝试替换以下行:

queue[atomic_fetch_and_add (&k2, 1)] = w;

使用以下两行:

atomic_fetch_and_add (&k2, 1);
queue[k2] = w;
于 2013-09-17T17:32:23.787 回答
1

(复制和扩展评论。)

鉴于编译错误的上下文:

queue[atomic_fetch_and_add (&k2, 1)] = w;

和错误信息:

drive_seed_community_detection.c:214:14: error: expected expression before ‘do’

这很可能atomic_fetch_and_add是一个使用成语定义的类函数宏do { ... } while (0),如comp.lang.c FAQ的问题 10.4 中所述。

这样的宏被设计为在需要语句的上下文中可用,但不能在需要表达式的上下文中使用。

可能开发人员使用了一个 where atomic_fetch_and_addis defined 的系统,以便它可以在表达式上下文中使用(它可能扩展为一个产生 的递增值的表达式k2)。

Lorenzo Donati 的回答提出了一种可能的解决方法:将调用单独atomic_fetch_and_add放在一行上。

可移植性较差的解决方法可能是利用 gcc-spoecific 扩展:语句表达式在此处描述。你可能会更换

queue[atomic_fetch_and_add (&k2, 1)] = w;

经过

queue[({atomic_fetch_and_add (&k2, 1); k2;})] = w;

我不推荐这种方法,但如果你经常遇到这个问题,半自动应用可能会更容易。

我还建议联系项目的开发人员,以便他们修复此错误。

于 2013-09-17T18:46:09.053 回答
1

只有在没有 OpenMP 支持的情况下编译源代码时才会出现您遇到的错误。

其他答案已经提供了如何修补源以在这种情况下也完成的可能性。

解决 OP 问题的另一种方法是在编译之前启用对 OpenMP 的支持。

这可以通过将适当的选项传递给配置脚本来完成:

snap-0.4$ make clean    
snap-0.4$ ./configure --enable-openmp

这应该产生以下输出:

snap successfully configured! Please verify that
this configuration matches with your expectations.

   User Option                         Value          
------------------------------------------------------
   OpenMP support                      yes
   Enable debug                        no

...

然后使用简单的编译源

snap-0.4$ make

应该无缝工作。


笔记

这仅适用于具有#defineed 的编译器:

  • __GNUC__

或/和

  • __INTEL_COMPILER
于 2013-09-18T06:06:39.127 回答