Esempio n. 1
0
void PhotonMap::send_photons() {
    printf("Each photon used %ld bytes\n",sizeof(Photon));
    std::vector<std::vector<Photon> > raw_photons(MAX_THREADS);
    #pragma omp parallel for
    for(unsigned int j=0; j<MAX_THREADS; j++) {
        raw_photons[j].reserve(scene->num_lights()*PHOTON_COUNT*(MAX_PHOTON_DEPTH+1));
        for(unsigned int i=0; i<scene->num_lights(); i++) {
            SphereLight light = scene->get_lights()[i];
            Color3 c=light.color;
            real_t prob=montecarlo(c);
            unsigned int photonCount=PHOTON_COUNT*prob/MAX_THREADS;
            printf("Sending %d photons.\n",photonCount);
            for(unsigned int k=0; k<photonCount; k++) {
                Ray ray;
                ray.d = random_sphere_indexed(k,photonCount);
                ray.e = light.position+random_sphere()*light.radius;
                trace_photon(raw_photons[j],c,ray,MAX_PHOTON_DEPTH);
            }
        }
    }
    std::vector<size_t> offsets(raw_photons.size());
    size_t total=0;
    for(size_t i=0; i<raw_photons.size(); i++) {
        offsets[i]=total;
        total+=raw_photons[i].size();
        raw_photons[i].shrink_to_fit();
    }
    printf("Made %ld photons\n",total);
    delete all_raw_photons;
    all_raw_photons = new std::vector<Photon>(total);
    for(size_t i=0; i<raw_photons.size(); i++) {
        std::vector<Photon>::iterator dest=all_raw_photons->begin()+offsets[i];
        while(raw_photons[i].size()>0) {
            assert(dest<all_raw_photons->end());
            //rough attempt at page-aligning during copy
            size_t copySize=1024*1024;
            size_t extra=raw_photons[i].size()%copySize;
            if(extra!=0) {
                copySize=extra;
            }
            shift_buffer(&(raw_photons[i]),dest,copySize);
        }
    }
    printf("Collected %ld photons\n",all_raw_photons->size());
    //TODO: organize the photons into some sort of kd-tree
}
int main(int argc, char *argv[]) {
    MPI_Init(&argc,&argv);

    if (argc != 6) {
        printf("Bad arguments (%d)  -  exit.\n",argc);
        return -1;
    }

#if 1
    int dim = atoi(argv[1]);
    int nof_nodes = atoi(argv[2]);
    char * shm_input_handler = argv[3];
    char * shm_output_handler = argv[4];
    char * shm_config_handler = argv[5];

    int input_size = sizeof(double)*nof_nodes*dim;
    int output_size = sizeof(double)*nof_nodes;
    int config_size = sizeof(struct mc_mpi_config);

    int shm_input_fd = shm_open(shm_input_handler, O_RDWR, S_IRUSR | S_IWUSR);
    if (shm_input_fd < 0) {
        perror("shm_open() 3");
    }

    int shm_output_fd = shm_open(shm_output_handler, O_RDWR, S_IRUSR | S_IWUSR);
    if (shm_output_fd < 0) {
        perror("shm_open() 4");
    }

    int shm_config_fd = shm_open(shm_config_handler, O_RDWR, S_IRUSR | S_IWUSR);
    if (shm_config_fd < 0) {
        perror("shm_open()");
    }

    //create shared memory for node_coord (input)
    void *shm_node_coord = mmap(NULL,input_size,PROT_READ | PROT_WRITE,MAP_SHARED,shm_input_fd,0);
    if (shm_node_coord == MAP_FAILED) {
        perror("mmap()");
    }

    //create shared memory for sol_est (output)
    void *shm_sol_est = mmap(NULL,output_size,PROT_READ | PROT_WRITE,MAP_SHARED,shm_output_fd,0);
    if (shm_sol_est == MAP_FAILED) {
        perror("mmap()");
    }

    void *shm_config = mmap(NULL,config_size,PROT_READ | PROT_WRITE,MAP_SHARED,shm_config_fd,0);
    if (shm_config == MAP_FAILED) {
        perror("mmap()");
    }

    if (close(shm_input_fd) == -1)
        perror("close()");

    if (close(shm_output_fd) == -1)
        perror("close()");

    if (close(shm_config_fd) == -1)
        perror("close()");

    double *node_coord = (double *)shm_node_coord;
    double *sol_est = (double *)shm_sol_est;
    struct mc_mpi_config *common_data = (struct mc_mpi_config *)shm_config;
#endif

    //////////////////////////////////////////////////
    //              MPI code
    //////////////////////////////////////////////////

    int rank;
    int nof_mpi_processes;
    MPI_Comm_size(MPI_COMM_WORLD,&nof_mpi_processes);
    MPI_Comm_rank(MPI_COMM_WORLD,&rank);

    printf("rank = %d of (%d)\n",rank,nof_mpi_processes);

#if 1
    int local_nof_nodes = nof_nodes/nof_mpi_processes;
    enum impl_t impl = IMPL_THREADS;  //IMPL_CL

#if 1
    std::shared_ptr<const dolfin::Expression> f(&common_data->f);
    std::shared_ptr<const dolfin::Expression> q(&common_data->q);
#else
    std::shared_ptr<const dolfin::Expression> &f(common_data->f);
    std::shared_ptr<const dolfin::Expression> &q(common_data->q);
#endif

    std::vector<double> local_sol_est(local_nof_nodes);
    local_sol_est = montecarlo(common_data->D,dim,
                               node_coord + local_nof_nodes*dim*rank, local_nof_nodes,
                               f,q,
                               common_data->walks, common_data->btol,common_data->threads,impl);

    for (int i=0; i<local_nof_nodes; ++i) {
        sol_est[local_nof_nodes*rank + i] = local_sol_est[i];
    }
#endif

    //release shared memory and handler

#if 1
    if (munmap(shm_node_coord,input_size) == -1) {
        perror("munmap()");
    }

    if (munmap(shm_sol_est,output_size) == -1) {
        perror("munmap()");
    }

    if (munmap(shm_config,config_size) == -1) {
        perror("munmap()");
    }
#endif

#if 0
    if (shm_unlink(shm_input_handler)) {
        perror("shm_unlink()");
    }

    if (shm_unlink(shm_output_handler)) {
        perror("shm_unlink()");
    }

    if (shm_unlink(shm_config_handler)) {
        perror("shm_unlink()");
    }
#endif

    MPI_Finalize();

    return 0;
}