Home Dashboard Directory Help
Search

Link 1000 error when compiling using 64bit and release (any optimization) build by Lecheps


Status: 

Closed
 as Fixed Help for as Fixed


1
0
Sign in
to vote
Type: Bug
ID: 675274
Opened: 6/14/2011 2:46:13 AM
Access Restriction: Public
Moderator Decision: Sent to Engineering Team for consideration
1
Workaround(s)
view
0
User(s) can reproduce this bug

Description

The code compiles just fine under 32bit (debug and release) and 64bit(debug) but chokes up when i try 64bit release (with any optimization). The culprit, as far as i can tell, is a combination of openmp and the boost/random library.
Here is the error message:

1>Link:
1> Generating code
1>c:\users\jose-luis.guerrero\documents\visual studio 2010\projects\testopenmp\testopenmp\main.cpp(40): fatal error C1001: An internal error has occurred in the compiler.
1> (compiler file 'f:\dd\vctools\compiler\utc\src\p2\main.c[0x615BAC56:0x342279FC]', line 183)
1> To work around this problem, try simplifying or changing the program near the locations listed above.
1> Please choose the Technical Support command on the Visual C++
1> Help menu, or open the Technical Support help file for more information
1>
1>LINK : fatal error LNK1000: Internal error during IMAGE::BuildImage
1>
1>    Version 10.00.30319.01
1>
1>    ExceptionCode            = C0000005
1>    ExceptionFlags         = 00000000
1>    ExceptionAddress         = 615BAC56 (61500000) "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\x86_amd64\c2.dll"
1>    NumberParameters         = 00000002
1>    ExceptionInformation[ 0] = 00000000
1>    ExceptionInformation[ 1] = 342279FC
1>
1> CONTEXT:
1>    Eax    = 040718BC Esp    = 004AEAE0
1>    Ebx    = 0000001E Ebp    = 004AEB30
1>    Ecx    = 0C0710F4 Esi    = 04063EC8
1>    Edx    = 04063628 Edi    = 04025AFC
1>    Eip    = 615BAC56 EFlags = 00010287
1>    SegCs = 00000023 SegDs = 0000002B
1>    SegSs = 0000002B SegEs = 0000002B
1>    SegFs = 00000053 SegGs = 0000002B
1>    Dr0    = 00000000 Dr3    = 00000000
1>    Dr1    = 00000000 Dr6    = 00000000
1>    Dr2    = 00000000 Dr7    = 00000000
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:08.91
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========

And here is the offending piece of code:

#include<iostream>
#include<boost/timer.hpp>
#include <boost/random/linear_congruential.hpp>
#include <boost/random/uniform_int.hpp>
#include <boost/random/uniform_real.hpp>
#include <boost/random/variate_generator.hpp>
#include <boost/generator_iterator.hpp>
#include <boost/random/mersenne_twister.hpp>
#include<omp.h>

#define NUM_THREADS 8

using namespace std;

typedef boost::mt19937 base_generator_type; //Defining the pseudo-random number generator

int main(void){

    omp_set_num_threads(NUM_THREADS);
    base_generator_type generator(42u);

    boost::uniform_real<double> distA4(0.7,0.9);

    int tid;
     #pragma omp parallel private(tid)
    {
        tid = omp_get_thread_num();
        cout << "Hello from thread: " << tid << endl;
    }

    
    boost::variate_generator<base_generator_type&, boost::uniform_real<> >
        uniA4(generator, distA4);
    

     #pragma omp parallel private(tid)
    {
        tid = omp_get_thread_num();
        cout << "Hello from thread: " << tid << endl;
    }

    return 0;
}

The second #pragma omp parallel for is the culprit. The first one works just fine.
Details
Sign in to post a comment.
Posted by Microsoft on 6/23/2011 at 4:53 PM
Thanks for reporting this issue.

The compiler error is caused by mix of variable scopes and openmp. You can work around this by changing the scoping within the function. For example adding an additional set of curly-braces after the boost types like this will compile your example without error:

{
    int tid;
     #pragma omp parallel private(tid)
    {
        tid = omp_get_thread_num();
        cout << "Hello from thread: " << tid << endl;
    }
}


The issue will be fixed in a future release of Visual Studio.

thanks,
ian Bearman
VC++ Code Generation and Optimization Team
Posted by MS-Moderator10 [Feedback Moderator] on 6/14/2011 at 7:34 PM
Thanks for your feedback.

We are rerouting this issue to the appropriate group within the Visual Studio Product Team for triage and resolution. These specialized experts will follow-up with your issue.
Posted by MS-Moderator01 on 6/14/2011 at 2:50 AM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(http://support.microsoft.com)
Sign in to post a workaround.
Posted by Lecheps on 6/15/2011 at 7:47 AM
Found a workaround. If you wrap your random number generation in a class, then the linker has no problem.
The main code becomes:
#include<iostream>
#include<boost/timer.hpp>
#include<omp.h>
#include "myRandom.h"

#define NUM_THREADS 8

using namespace std;

//typedef boost::mt19937 base_generator_type; //Defining the pseudo-random number generator

int main(void){

    omp_set_num_threads(NUM_THREADS);
    
    int tid;
    #pragma omp parallel private(tid)
    {
        tid = omp_get_thread_num();
        cout << "Hello from thread: " << tid << endl;
    }
        
    myRandom test;
    test.setSeed(42u);
    for (int i = 0; i < 10; ++i){
        cout << test.getRandVal() << " ";
    }
    cout << endl;
        
    #pragma omp parallel private(tid)
    {
        tid = omp_get_thread_num();
        cout << "Hello from thread: " << tid << endl;
    }

    return 0;
}

and myRandom.h is:

#pragma once

#include <iostream>
//#include <boost/random/linear_congruential.hpp>
//#include <boost/random/uniform_int.hpp>
#include <boost/random/uniform_real.hpp>
#include <boost/random/variate_generator.hpp>
//#include <boost/generator_iterator.hpp>
#include <boost/random/mersenne_twister.hpp>

using namespace std;

class myRandom
{
    boost::mt19937 rng;
    boost::uniform_real<double> interval;
    boost::variate_generator< boost::mt19937&,boost::uniform_real<double> > varGen;

public:
    
    myRandom():varGen(rng,interval){
        
    };
    ~myRandom(void);
    
    void setInterval(double low, double high){
        interval = boost::uniform_real<double>(low,high);
        varGen.distribution() = interval;
    }

    void setSeed(uint32_t seedVal){
        rng.seed(seedVal);
        varGen.engine() = rng;
    }

    double getRandVal(){
        return varGen();
    }
    

};